class Status(Command): _cmd_id = 0 decode_strict = False # A list of (key, value) pairs is all a Status msg contains, but since the values can be of # any type, we need to use the raw sedes here and do the actual deserialization in # decode_payload(). structure = sedes.CountableList(sedes.List([sedes.binary, sedes.raw])) # The sedes used for each key in the list above. items_sedes = { 'protocolVersion': sedes.big_endian_int, 'networkId': sedes.big_endian_int, 'headTd': sedes.big_endian_int, 'headHash': sedes.binary, 'headNum': sedes.big_endian_int, 'genesisHash': sedes.binary, 'serveHeaders': None, 'serveChainSince': sedes.big_endian_int, 'serveStateSince': sedes.big_endian_int, 'txRelay': None, 'flowControl/BL': sedes.big_endian_int, 'flowControl/MRC': sedes.CountableList( sedes.List([ sedes.big_endian_int, sedes.big_endian_int, sedes.big_endian_int ])), 'flowControl/MRR': sedes.big_endian_int, } @to_dict def decode_payload(self, rlp_data): data = super(Status, self).decode_payload(rlp_data) # The LES/Status msg contains an arbitrary list of (key, value) pairs, where values can # have different types and unknown keys should be ignored for forward compatibility # reasons, so here we need an extra pass to deserialize each of the key/value pairs we # know about. for key, value in data: # The sedes.binary we use in .structure above will give us a bytes value here, but # using bytes as dictionary keys makes it impossible to use the dict() constructor # with keyword arguments, so we convert them to strings here. key = key.decode('ascii') if key not in self.items_sedes: continue item_sedes = self.items_sedes[key] if item_sedes is not None: yield key, item_sedes.deserialize(value) else: yield key, value def encode_payload(self, data): response = [(key, self.items_sedes[key].serialize(value)) for key, value in sorted(data.items())] return super(Status, self).encode_payload(response) def as_head_info(self, decoded: _DecodedMsgType) -> HeadInfo: decoded = cast(Dict[str, Any], decoded) return HeadInfo( block_number=decoded['headNum'], block_hash=decoded['headHash'], total_difficulty=decoded['headTd'], reorg_depth=0, )
class BeaconBlocks(Command): _cmd_id = 2 structure = [ ('request_id', sedes.big_endian_int), ('encoded_blocks', sedes.CountableList(sedes.binary)), ]
class GetProofs(Command): _cmd_id = 8 structure = [ ('request_id', sedes.big_endian_int), ('proof_requests', sedes.CountableList(ProofRequest)), ]
class GetContractCodes(Command): _cmd_id = 10 structure = [ ('request_id', sedes.big_endian_int), ('code_requests', sedes.CountableList(ContractCodeRequest)), ]
class GetReceipts(Command): _cmd_id = 15 structure = sedes.CountableList(sedes.binary)
class GetReceipts(Command): _cmd_id = 6 structure = [ ('request_id', sedes.big_endian_int), ('block_hashes', sedes.CountableList(sedes.binary)), ]
class BlockBodies(Command): _cmd_id = 6 structure = sedes.CountableList(BlockBody)
class NodeData(Command): _cmd_id = 14 structure = sedes.CountableList(sedes.binary)
class GetBlockBodies(Command): _cmd_id = 5 structure = sedes.CountableList(sedes.binary)
class BlockBody(rlp.Serializable): fields = [('transactions', sedes.CountableList(BaseTransaction)), ('uncles', sedes.CountableList(BlockHeader))]
class BlockHeaders(Command): _cmd_id = 4 structure = sedes.CountableList(BlockHeader)
class Transactions(Command): _cmd_id = 2 structure = sedes.CountableList(BaseTransaction)
class NewBlockHashes(Command): _cmd_id = 1 structure = sedes.CountableList( sedes.List([sedes.binary, sedes.big_endian_int]))
class Receipts(Command): _cmd_id = 16 structure = sedes.CountableList(sedes.CountableList(Receipt))
class BlockHeaders(BaseBlockHeaders): _cmd_id = 4 structure = sedes.CountableList(BlockHeader) def extract_headers(self, msg: _DecodedMsgType) -> Tuple[BlockHeader, ...]: return cast(Tuple[BlockHeader, ...], tuple(msg))