<s> import binascii <EOL> import logging <EOL> import io <EOL> import struct <EOL> from pycoin . block import Block , BlockHeader <EOL> from pycoin . encoding import double_sha256 <EOL> from pycoin . serialize import b2h_rev , bitcoin_streamer <EOL> from pycoin . tx . Tx import Tx <EOL> from pycoinnet . InvItem import InvItem <EOL> from pycoinnet . PeerAddress import PeerAddress <EOL> MESSAGE_STRUCTURES = { <EOL> '<STR_LIT:version>' : ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : ( <EOL> "<STR_LIT>" <EOL> ) , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> } <EOL> def _make_parser ( the_struct = '<STR_LIT>' ) : <EOL> def f ( message_stream ) : <EOL> struct_items = [ s . split ( "<STR_LIT::>" ) for s in the_struct . split ( ) ] <EOL> names = [ s [ <NUM_LIT:0> ] for s in struct_items ] <EOL> types = '<STR_LIT>' . join ( s [ <NUM_LIT:1> ] for s in struct_items ) <EOL> return bitcoin_streamer . parse_as_dict ( names , types , message_stream ) <EOL> return f <EOL> def _message_parsers ( ) : <EOL> return dict ( ( k , _make_parser ( v ) ) for k , v in MESSAGE_STRUCTURES . items ( ) ) <EOL> def fixup_merkleblock ( d , f ) : <EOL> def recurse ( level_widths , level_index , node_index , hashes , flags , flag_index , tx_acc ) : <EOL> idx , r = divmod ( flag_index , <NUM_LIT:8> ) <EOL> mask = ( <NUM_LIT:1> << r ) <EOL> flag_index += <NUM_LIT:1> <EOL> if flags [ idx ] & mask == <NUM_LIT:0> : <EOL> h = hashes . pop ( ) <EOL> return h , flag_index <EOL> if level_index == len ( level_widths ) - <NUM_LIT:1> : <EOL> h = hashes . pop ( ) <EOL> tx_acc . append ( h ) <EOL> return h , flag_index <EOL> left_hash , flag_index = recurse ( <EOL> level_widths , level_index + <NUM_LIT:1> , node_index * <NUM_LIT:2> , hashes , flags , flag_index , tx_acc ) <EOL> if node_index * <NUM_LIT:2> + <NUM_LIT:1> < level_widths [ level_index + <NUM_LIT:1> ] : <EOL> right_hash , flag_index = recurse ( <EOL> level_widths , level_index + <NUM_LIT:1> , node_index * <NUM_LIT:2> + <NUM_LIT:1> , hashes , flags , flag_index , tx_acc ) <EOL> if left_hash == right_hash : <EOL> raise ValueError ( "<STR_LIT>" % node_index ) <EOL> else : <EOL> right_hash = left_hash <EOL> return double_sha256 ( left_hash + right_hash ) , flag_index <EOL> level_widths = [ ] <EOL> count = d [ "<STR_LIT>" ] <EOL> while count > <NUM_LIT:1> : <EOL> level_widths . append ( count ) <EOL> count += <NUM_LIT:1> <EOL> count //= <NUM_LIT:2> <EOL> level_widths . append ( <NUM_LIT:1> ) <EOL> level_widths . reverse ( ) <EOL> tx_acc = [ ] <EOL> flags = d [ "<STR_LIT>" ] <EOL> hashes = list ( reversed ( d [ "<STR_LIT>" ] ) ) <EOL> left_hash , flag_index = recurse ( level_widths , <NUM_LIT:0> , <NUM_LIT:0> , hashes , flags , <NUM_LIT:0> , tx_acc ) <EOL> if len ( hashes ) > <NUM_LIT:0> : <EOL> raise ValueError ( "<STR_LIT>" % hashes ) <EOL> idx , r = divmod ( flag_index - <NUM_LIT:1> , <NUM_LIT:8> ) <EOL> if idx != len ( flags ) - <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if flags [ idx ] > ( <NUM_LIT:1> << ( r + <NUM_LIT:1> ) ) - <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if left_hash != d [ "<STR_LIT>" ] . merkle_root : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % ( <EOL> b2h_rev ( d [ "<STR_LIT>" ] . merkle_root ) , b2h_rev ( left_hash ) ) ) <EOL> d [ "<STR_LIT>" ] = tx_acc <EOL> return d <EOL> def _message_fixups ( ) : <EOL> def fixup_version ( d , f ) : <EOL> if d [ "<STR_LIT:version>" ] >= <NUM_LIT> : <EOL> b = f . read ( <NUM_LIT:1> ) <EOL> if len ( b ) > <NUM_LIT:0> : <EOL> d [ "<STR_LIT>" ] = ( ord ( b ) != <NUM_LIT:0> ) <EOL> return d <EOL> alert_submessage_parser = _make_parser ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> def fixup_alert ( d , f ) : <EOL> d1 = alert_submessage_parser ( io . BytesIO ( d [ "<STR_LIT>" ] ) ) <EOL> d [ "<STR_LIT>" ] = d1 <EOL> return d <EOL> return dict ( version = fixup_version , alert = fixup_alert , merkleblock = fixup_merkleblock ) <EOL> def _make_parse_from_data ( ) : <EOL> def init_bitcoin_streamer ( ) : <EOL> more_parsing = [ <EOL> ( "<STR_LIT:A>" , ( PeerAddress . parse , lambda f , peer_addr : peer_addr . stream ( f ) ) ) , <EOL> ( "<STR_LIT:v>" , ( InvItem . parse , lambda f , inv_item : inv_item . stream ( f ) ) ) , <EOL> ( "<STR_LIT:T>" , ( Tx . parse , lambda f , tx : tx . stream ( f ) ) ) , <EOL> ( "<STR_LIT:B>" , ( Block . parse , lambda f , block : block . stream ( f ) ) ) , <EOL> ( "<STR_LIT:z>" , ( BlockHeader . parse , lambda f , blockheader : blockheader . stream ( f ) ) ) , <EOL> ( "<STR_LIT:1>" , ( lambda f : struct . unpack ( "<STR_LIT:B>" , f . read ( <NUM_LIT:1> ) ) [ <NUM_LIT:0> ] , lambda f , b : f . write ( struct . pack ( "<STR_LIT:B>" , b ) ) ) ) , <EOL> ] <EOL> bitcoin_streamer . BITCOIN_STREAMER . register_functions ( more_parsing ) <EOL> init_bitcoin_streamer ( ) <EOL> MESSAGE_PARSERS = _message_parsers ( ) <EOL> MESSAGE_FIXUPS = _message_fixups ( ) <EOL> def parse_from_data ( message_name , data ) : <EOL> message_stream = io . BytesIO ( data ) <EOL> parser = MESSAGE_PARSERS . get ( message_name ) <EOL> if parser : <EOL> d = parser ( message_stream ) <EOL> fixup = MESSAGE_FIXUPS . get ( message_name ) <EOL> if fixup : <EOL> d = fixup ( d , message_stream ) <EOL> else : <EOL> logging . error ( "<STR_LIT>" , message_name , binascii . hexlify ( data ) ) <EOL> d = { } <EOL> return d <EOL> return parse_from_data <EOL> parse_from_data = _make_parse_from_data ( ) <EOL> def pack_from_data ( message_name , ** kwargs ) : <EOL> the_struct = MESSAGE_STRUCTURES [ message_name ] <EOL> if not the_struct : <EOL> return b'<STR_LIT>' <EOL> f = io . BytesIO ( ) <EOL> the_fields = the_struct . split ( "<STR_LIT:U+0020>" ) <EOL> pairs = [ t . split ( "<STR_LIT::>" ) for t in the_fields ] <EOL> for name , type in pairs : <EOL> if type [ <NUM_LIT:0> ] == '<STR_LIT:[>' : <EOL> bitcoin_streamer . BITCOIN_STREAMER . stream_struct ( "<STR_LIT:I>" , f , len ( kwargs [ name ] ) ) <EOL> for v in kwargs [ name ] : <EOL> if not isinstance ( v , ( tuple , list ) ) : <EOL> v = [ v ] <EOL> bitcoin_streamer . BITCOIN_STREAMER . stream_struct ( type [ <NUM_LIT:1> : - <NUM_LIT:1> ] , f , * v ) <EOL> else : <EOL> bitcoin_streamer . BITCOIN_STREAMER . stream_struct ( type , f , kwargs [ name ] ) <EOL> return f . getvalue ( ) </s>
