Exemplo n.º 1
0
    async def recv(self) -> MessageAPI:
        header_bytes = await self.read(HEADER_LEN + MAC_LEN)
        try:
            padded_header = self._decrypt_header(header_bytes)
        except (ValueError, DecryptionError) as err:
            self.logger.info("Bad message header from peer %s: Error: %r",
                             self, err)
            raise MalformedMessage(*err.args) from err
        # TODO: use `int.from_bytes(...)`
        frame_size = self._get_frame_size(padded_header)
        # The frame_size specified in the header does not include the padding to 16-byte boundary,
        # so need to do this here to ensure we read all the frame's data.
        read_size = roundup_16(frame_size)
        frame_data = await self.read(read_size + MAC_LEN)
        try:
            body = self._decrypt_body(frame_data, frame_size)
        except (ValueError, DecryptionError) as err:
            self.logger.info("Bad message body from peer %s: Error: %r", self,
                             err)
            raise MalformedMessage(*err.args) from err

        # Decode the header data and re-encode to recover the unpadded header size.
        try:
            header_data = _decode_header_data(padded_header[3:])
        except rlp.exceptions.DeserializationError as err:
            raise MalformedMessage(*err.args) from err

        header = padded_header[:3] + rlp.encode(header_data)

        return Message(header, body)
Exemplo n.º 2
0
    async def recv(self) -> MessageAPI:
        # Check that Transport read state is IDLE.
        if self.read_state is not TransportState.IDLE:
            # This is logged at INFO level because it indicates we are not
            # properly managing the Transport and are interrupting it mid-read
            # somewhere.
            self.logger.info(
                'Corrupted transport: %s - state=%s',
                self,
                self.read_state.name,
            )
            raise CorruptTransport(f"Corrupted transport: {self} - state={self.read_state.name}")

        # Set status to indicate we are waiting to read the message header
        self.read_state = TransportState.HEADER

        try:
            header_bytes = await self.read(HEADER_LEN + MAC_LEN)
        except asyncio.CancelledError:
            self.logger.debug('Transport cancelled during header read. resetting to IDLE state')
            self.read_state = TransportState.IDLE
            raise

        # Set status to indicate we are waiting to read the message body
        self.read_state = TransportState.BODY
        try:
            padded_header = self._decrypt_header(header_bytes)
        except DecryptionError as err:
            self.logger.debug(
                "Bad message header from peer %s: Error: %r",
                self, err,
            )
            raise MalformedMessage from err
        # TODO: use `int.from_bytes(...)`
        frame_size = self._get_frame_size(padded_header)
        # The frame_size specified in the header does not include the padding to 16-byte boundary,
        # so need to do this here to ensure we read all the frame's data.
        read_size = roundup_16(frame_size)
        frame_data = await self.read(read_size + MAC_LEN)
        try:
            body = self._decrypt_body(frame_data, frame_size)
        except DecryptionError as err:
            self.logger.debug(
                "Bad message body from peer %s: Error: %r",
                self, err,
            )
            raise MalformedMessage from err

        # Reset status back to IDLE
        self.read_state = TransportState.IDLE

        # Decode the header data and re-encode to recover the unpadded header size.
        try:
            header_data = _decode_header_data(padded_header[3:])
        except rlp.exceptions.DeserializationError as err:
            raise MalformedMessage from err

        header = padded_header[:3] + rlp.encode(header_data)

        return Message(header, body)
Exemplo n.º 3
0
 async def recv(self) -> MessageAPI:
     self.read_state = TransportState.HEADER
     try:
         encoded_sizes = await self.read(8)
     except asyncio.CancelledError:
         self.read_state = TransportState.IDLE
         raise
     header_size, body_size = struct.unpack('>II', encoded_sizes)
     self.read_state = TransportState.BODY
     header = await self.read(header_size)
     body = await self.read(body_size)
     self.read_state = TransportState.IDLE
     return Message(header, body)
Exemplo n.º 4
0
def test_eip8_hello():
    # Data taken from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md
    payload_body = decode_hex(
        "f87137916b6e6574682f76302e39312f706c616e39cdc5836574683dc6846d6f726b1682270fb840"
        "fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569"
        "bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877c883666f6f836261720304"
    )
    msg = Message(b'', b'\x80' + payload_body)

    cmd = Hello.decode(msg, snappy_support=False)
    assert cmd.payload.capabilities == (('eth', 61), ('mork', 22))
    assert cmd.payload.version == 55
    assert cmd.payload.client_version_string == 'kneth/v0.91/plan9'
    assert cmd.payload.listen_port == 9999
    assert cmd.payload.remote_public_key == b'\xfd\xa1\xcf\xf6t\xc9\x0c\x9a\x19u9\xfe=\xfbS\x08j\xced\xf8>\xd7\xc6\xea\xbe\xc7A\xf7\xf3\x81\xcc\x80>R\xab,\xd5]Ui\xbc\xe44q\x07\xa3\x10\xdf\xd5\xf8\x8a\x01\x0c\xd2\xff\xd1\x00\\\xa4\x06\xf1\x84(w'  # noqa: E501
Exemplo n.º 5
0
    def encode(self, cmd_id: int, snappy_support: bool) -> MessageAPI:
        raw_payload_data = self.serialization_codec.encode(self.payload)

        if snappy_support:
            payload_data = self.compression_codec.compress(raw_payload_data)
        else:
            payload_data = raw_payload_data

        cmd_id_data = rlp.encode(cmd_id, sedes=rlp.sedes.big_endian_int)
        frame_size = len(cmd_id_data) + len(payload_data)

        if frame_size.bit_length() > 24:
            raise ValueError("Frame size has to fit in a 3-byte integer")

        # Frame-size is a 3-bit integer
        header = frame_size.to_bytes(3, 'big') + RLPX_HEADER_DATA
        body = cmd_id_data + payload_data

        return Message(header, body)
 async def recv(self) -> MessageAPI:
     encoded_sizes = await self.read(8)
     header_size, body_size = struct.unpack('>II', encoded_sizes)
     header = await self.read(header_size)
     body = await self.read(body_size)
     return Message(header, body)