# Path: pycoinnet/message.py
# def parse_from_data(message_name, data):
#     message_stream = io.BytesIO(data)
#     parser = MESSAGE_PARSERS.get(message_name)
#     if parser:
#         d = parser(message_stream)
#         fixup = MESSAGE_FIXUPS.get(message_name)
#         if fixup:
#             d = fixup(d, message_stream)
#     else:
#         logging.error("unknown message: %s %s", message_name, binascii.hexlify(data))
#         d = {}
#     return d
# 
# def pack_from_data(message_name, **kwargs):
#     the_struct = MESSAGE_STRUCTURES[message_name]
#     if not the_struct:
#         return b''
#     f = io.BytesIO()
#     the_fields = the_struct.split(" ")
#     pairs = [t.split(":") for t in the_fields]
#     for name, type in pairs:
#         if type[0] == '[':
#             bitcoin_streamer.BITCOIN_STREAMER.stream_struct("I", f, len(kwargs[name]))
#             for v in kwargs[name]:
#                 if not isinstance(v, (tuple, list)):
#                     v = [v]
#                 bitcoin_streamer.BITCOIN_STREAMER.stream_struct(type[1:-1], f, *v)
#         else:
#             bitcoin_streamer.BITCOIN_STREAMER.stream_struct(type, f, kwargs[name])
#     return f.getvalue()


import asyncio
import binascii
import logging
import struct
import time
import weakref
from pycoin import encoding
from pycoinnet.message import parse_from_data, pack_from_data

        # read magic header
        reader = self.reader
        blob = yield from reader.readexactly(len(self.magic_header))
        if blob != self.magic_header:
            raise BitcoinProtocolError("bad magic: got %s" % binascii.hexlify(blob))

        # read message name
        message_size_hash_bytes = yield from reader.readexactly(20)
        message_name_bytes = message_size_hash_bytes[:12]
        message_name = message_name_bytes.replace(b"\0", b"").decode("utf8")

        # get size of message
        size_bytes = message_size_hash_bytes[12:16]
        size = int.from_bytes(size_bytes, byteorder="little")
        if size > self.MAX_MESSAGE_SIZE:
            raise BitcoinProtocolError("absurdly large message size %d" % size)

        # read the hash, then the message
        transmitted_hash = message_size_hash_bytes[16:20]
        message_data = yield from reader.readexactly(size)

        # check the hash
        actual_hash = encoding.double_sha256(message_data)[:4]
        if actual_hash != transmitted_hash:
            raise BitcoinProtocolError("checksum is WRONG: %s instead of %s" % (
                binascii.hexlify(actual_hash), binascii.hexlify(transmitted_hash)))
        logging.debug("message %s: %s (%d byte payload)", self, message_name, len(message_data))

        # parse the blob into a BitcoinProtocolMessage object

# Path: pycoinnet/message.py
# def parse_from_data(message_name, data):
#     message_stream = io.BytesIO(data)
#     parser = MESSAGE_PARSERS.get(message_name)
#     if parser:
#         d = parser(message_stream)
#         fixup = MESSAGE_FIXUPS.get(message_name)
#         if fixup:
#             d = fixup(d, message_stream)
#     else:
#         logging.error("unknown message: %s %s", message_name, binascii.hexlify(data))
#         d = {}
#     return d
# 
# def pack_from_data(message_name, **kwargs):
#     the_struct = MESSAGE_STRUCTURES[message_name]
#     if not the_struct:
#         return b''
#     f = io.BytesIO()
#     the_fields = the_struct.split(" ")
#     pairs = [t.split(":") for t in the_fields]
#     for name, type in pairs:
#         if type[0] == '[':
#             bitcoin_streamer.BITCOIN_STREAMER.stream_struct("I", f, len(kwargs[name]))
#             for v in kwargs[name]:
#                 if not isinstance(v, (tuple, list)):
#                     v = [v]
#                 bitcoin_streamer.BITCOIN_STREAMER.stream_struct(type[1:-1], f, *v)
#         else:
#             bitcoin_streamer.BITCOIN_STREAMER.stream_struct(type, f, kwargs[name])
#     return f.getvalue()


# Path: pycoinnet/peer/BitcoinPeerProtocol.py
import asyncio
import binascii
import logging
import struct
import time
import weakref
from pycoin import encoding
from pycoinnet.message import parse_from_data, pack_from_data


        # read magic header
        reader = self.reader
        blob = yield from reader.readexactly(len(self.magic_header))
        if blob != self.magic_header:
            raise BitcoinProtocolError("bad magic: got %s" % binascii.hexlify(blob))

        # read message name
        message_size_hash_bytes = yield from reader.readexactly(20)
        message_name_bytes = message_size_hash_bytes[:12]
        message_name = message_name_bytes.replace(b"\0", b"").decode("utf8")

        # get size of message
        size_bytes = message_size_hash_bytes[12:16]
        size = int.from_bytes(size_bytes, byteorder="little")
        if size > self.MAX_MESSAGE_SIZE:
            raise BitcoinProtocolError("absurdly large message size %d" % size)

        # read the hash, then the message
        transmitted_hash = message_size_hash_bytes[16:20]
        message_data = yield from reader.readexactly(size)

        # check the hash
        actual_hash = encoding.double_sha256(message_data)[:4]
        if actual_hash != transmitted_hash:
            raise BitcoinProtocolError("checksum is WRONG: %s instead of %s" % (
                binascii.hexlify(actual_hash), binascii.hexlify(transmitted_hash)))
        logging.debug("message %s: %s (%d byte payload)", self, message_name, len(message_data))

        # parse the blob into a BitcoinProtocolMessage object

        data = parse_from_data(message_name, message_data)