def __class_getitem__(cls, params) -> Type["List"]: (element_type, limit) = params contents_depth = 0 packed = False if isinstance(element_type, BasicView): elems_per_chunk = 32 // element_type.type_byte_length() contents_depth = get_depth( (limit + elems_per_chunk - 1) // elems_per_chunk) packed = True else: contents_depth = get_depth(limit) class SpecialListView(List): @classmethod def is_packed(cls) -> bool: return packed @classmethod def contents_depth(cls) -> int: return contents_depth @classmethod def element_cls(cls) -> Type[View]: return element_type @classmethod def limit(cls) -> int: return limit SpecialListView.__name__ = SpecialListView.type_repr() return SpecialListView
def __class_getitem__(cls, params) -> Type["Vector"]: (element_view_cls, length) = params if length <= 0: raise Exception(f"Invalid vector length: {length}") tree_depth = 0 packed = False if isinstance(element_view_cls, BasicView): elems_per_chunk = 32 // element_view_cls.type_byte_length() tree_depth = get_depth( (length + elems_per_chunk - 1) // elems_per_chunk) packed = True else: tree_depth = get_depth(length) class SpecialVectorView(Vector): @classmethod def is_packed(cls) -> bool: return packed @classmethod def tree_depth(cls) -> int: return tree_depth @classmethod def element_cls(cls) -> Type[View]: return element_view_cls @classmethod def vector_length(cls) -> int: return length out_typ = SpecialVectorView # for fixed-size vectors, pre-compute the size. if element_view_cls.is_fixed_byte_length(): byte_length = element_view_cls.type_byte_length() * length class FixedSpecialVectorView(SpecialVectorView): @classmethod def type_byte_length(cls) -> int: return byte_length @classmethod def min_byte_length(cls) -> int: return byte_length @classmethod def max_byte_length(cls) -> int: return byte_length out_typ = FixedSpecialVectorView out_typ.__name__ = out_typ.type_repr() return out_typ
def get_valid_custody_response(spec, state, bit_challenge, custody_data, challenge_index, invalid_chunk_bit=False): chunks = custody_chunkify(spec, custody_data) chunk_index = len(chunks) - 1 chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key, chunks[chunk_index]) while chunk_bit == bit_challenge.chunk_bits[ chunk_index] ^ invalid_chunk_bit: chunk_index -= 1 chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key, chunks[chunk_index]) chunks_hash_tree_roots = [ hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunk)) for chunk in chunks ] chunks_hash_tree_roots += [ hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK]( b"\0" * spec.BYTES_PER_CUSTODY_CHUNK)) for i in range(2**spec.ceillog2(len(chunks)) - len(chunks)) ] data_tree = get_merkle_tree(chunks_hash_tree_roots) data_branch = get_merkle_proof(data_tree, chunk_index) bitlist_chunk_index = chunk_index // BYTES_PER_CHUNK print(bitlist_chunk_index) bitlist_chunk_nodes = pack_bits_to_chunks(bit_challenge.chunk_bits) bitlist_tree = subtree_fill_to_contents(bitlist_chunk_nodes, get_depth(spec.MAX_CUSTODY_CHUNKS)) print(bitlist_tree) bitlist_chunk_branch = None # TODO; extract proof from merkle tree bitlist_chunk_index = chunk_index // 256 chunk_bits_leaf = Bitvector[256]( bit_challenge.chunk_bits[bitlist_chunk_index * 256:(bitlist_chunk_index + 1) * 256]) return spec.CustodyResponse( challenge_index=challenge_index, chunk_index=chunk_index, chunk=ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunks[chunk_index]), data_branch=data_branch, chunk_bits_branch=bitlist_chunk_branch, chunk_bits_leaf=chunk_bits_leaf, )
def __class_getitem__(cls, limit) -> Type["ByteList"]: chunk_count = (limit + 31) // 32 contents_depth = get_depth(chunk_count) class SpecialByteListView(ByteList): @classmethod def contents_depth(cls) -> int: return contents_depth @classmethod def limit(cls) -> int: return limit return SpecialByteListView
def __class_getitem__(cls, length) -> Type["ByteVector"]: chunk_count = (length + 31) // 32 tree_depth = get_depth(chunk_count) class SpecialByteVectorView(ByteVector): @classmethod def default_node(cls) -> Node: return subtree_fill_to_length(zero_node(0), tree_depth, chunk_count) @classmethod def tree_depth(cls) -> int: return tree_depth @classmethod def type_byte_length(cls) -> int: return length return SpecialByteVectorView
def tree_depth(cls) -> int: return get_depth(len(cls.fields()))
def test_tree_depth(count: int, depth: int): assert get_depth(count) == depth
def tree_depth(cls) -> int: return get_depth((cls.vector_length() + 255) // 256)
def contents_depth(cls) -> int: # depth excluding the length mix-in return get_depth((cls.limit() + 255) // 256)