<s> import hashlib <EOL> import os <EOL> import struct <EOL> import format <EOL> from . . import util <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def _debug ( obj , params ) : <EOL> message = [ '<STR_LIT>' % obj . __class__ . __name__ ] <EOL> for ( k , v ) in params : <EOL> if isinstance ( v , ( list , tuple ) ) : <EOL> message . append ( ( '<STR_LIT>' % ( k , len ( v ) ) ) ) <EOL> if len ( v ) : <EOL> k = '<STR_LIT>' % k <EOL> v = v [ <NUM_LIT:0> ] <EOL> if v : <EOL> if isinstance ( v , format . NetworkAddress ) : <EOL> text = '<STR_LIT>' % ( v . address , v . port ) <EOL> elif isinstance ( v , format . InventoryVector ) : <EOL> obj_type = '<STR_LIT>' <EOL> if v . object_type <= <NUM_LIT:2> : <EOL> obj_type = [ '<STR_LIT:error>' , '<STR_LIT>' , '<STR_LIT>' ] [ v . object_type ] <EOL> text = '<STR_LIT>' % ( obj_type , v . hash . encode ( '<STR_LIT>' ) ) <EOL> elif isinstance ( v , format . Txn ) : <EOL> text = v . hash . encode ( '<STR_LIT>' ) <EOL> elif isinstance ( v , format . BlockHeader ) : <EOL> text = v . hash . encode ( '<STR_LIT>' ) <EOL> else : <EOL> text = str ( v ) <EOL> message . append ( ( '<STR_LIT>' % ( k , text ) ) ) <EOL> return "<STR_LIT:U+0020>" . join ( message ) + '<STR_LIT:>>' <EOL> class UnknownMessageException ( Exception ) : pass <EOL> class MessageFormatException ( Exception ) : pass <EOL> class Message ( format . CompoundType ) : <EOL> '''<STR_LIT>''' <EOL> command = None <EOL> do_not_register = False <EOL> properties = [ ] <EOL> _magic = None <EOL> magic = property ( lambda s : s . _magic ) <EOL> def binary ( self , magic ) : <EOL> '<STR_LIT>' <EOL> payload = format . CompoundType . binary ( self ) <EOL> checksum = hashlib . sha256 ( hashlib . sha256 ( payload ) . digest ( ) ) . digest ( ) [ : <NUM_LIT:4> ] <EOL> command = self . command + ( chr ( <NUM_LIT:0> ) * ( <NUM_LIT:12> - len ( self . command ) ) ) <EOL> return magic + command + struct . pack ( '<STR_LIT>' , len ( payload ) ) + checksum + payload <EOL> MessageTypes = dict ( ) <EOL> @ staticmethod <EOL> def register ( message_type ) : <EOL> '<STR_LIT>' <EOL> Message . MessageTypes [ message_type . command ] = message_type <EOL> @ staticmethod <EOL> def first_message_length ( data ) : <EOL> '''<STR_LIT>''' <EOL> if len ( data ) < <NUM_LIT:20> : <EOL> return None <EOL> return struct . unpack ( '<STR_LIT>' , data [ <NUM_LIT:16> : <NUM_LIT:20> ] ) [ <NUM_LIT:0> ] + <NUM_LIT> <EOL> @ classmethod <EOL> def parse ( cls , data , magic ) : <EOL> if data [ <NUM_LIT:0> : <NUM_LIT:4> ] != magic : <EOL> raise MessageFormatException ( '<STR_LIT>' ) <EOL> ( length , ) = struct . unpack ( '<STR_LIT>' , data [ <NUM_LIT:16> : <NUM_LIT:20> ] ) <EOL> payload = data [ <NUM_LIT> : <NUM_LIT> + length ] <EOL> checksum = hashlib . sha256 ( hashlib . sha256 ( payload ) . digest ( ) ) . digest ( ) [ : <NUM_LIT:4> ] <EOL> if data [ <NUM_LIT:20> : <NUM_LIT> ] != checksum : <EOL> raise MessageFormatException ( '<STR_LIT>' ) <EOL> command = data [ <NUM_LIT:4> : <NUM_LIT:16> ] . strip ( chr ( <NUM_LIT:0> ) ) <EOL> message_type = cls . MessageTypes . get ( command ) <EOL> if message_type is None : <EOL> raise UnknownMessageException ( '<STR_LIT>' % ( command , data ) ) <EOL> ( vl , message ) = super ( Message , message_type ) . parse ( payload ) <EOL> message . _magic = magic <EOL> return message <EOL> @ property <EOL> def name ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . command <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ] ) <EOL> class Version ( Message ) : <EOL> command = "<STR_LIT:version>" <EOL> properties = [ <EOL> ( '<STR_LIT:version>' , format . FormatTypeNumber ( '<STR_LIT:i>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:q>' , allow_float = True ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNetworkAddressWithoutTimestamp ( ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNetworkAddressWithoutTimestamp ( ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:8> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeVarString ( ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:i>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeOptional ( format . FormatTypeNumber ( '<STR_LIT:B>' ) , True ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ <EOL> ( '<STR_LIT:v>' , self . version ) , <EOL> ( '<STR_LIT:s>' , self . services ) , <EOL> ( '<STR_LIT>' , self . user_agent ) , <EOL> ( '<STR_LIT>' , self . start_height ) , <EOL> ] ) <EOL> class VersionAck ( Message ) : <EOL> command = '<STR_LIT>' <EOL> name = "<STR_LIT>" <EOL> class Address ( Message ) : <EOL> command = '<STR_LIT>' <EOL> name = "<STR_LIT:address>" <EOL> properties = [ <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeNetworkAddress ( ) , max_length = <NUM_LIT:1000> ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT:a>' , self . addr_list ) ] ) <EOL> class Inventory ( Message ) : <EOL> command = '<STR_LIT>' <EOL> name = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeInventoryVector ( ) , max_length = <NUM_LIT> ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT:i>' , self . inventory ) ] ) <EOL> class GetData ( Inventory ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> class NotFound ( Inventory ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> class GetBlocks ( Message ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT:version>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeBytes ( <NUM_LIT:32> ) , <NUM_LIT:1> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:32> ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT>' , [ h . encode ( '<STR_LIT>' ) for h in self . block_locator_hashes ] ) ] ) <EOL> class GetHeaders ( GetBlocks ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> class Transaction ( Message ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT:version>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeTxnIn ( ) , <NUM_LIT:1> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeTxnOut ( ) , <NUM_LIT:1> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT>' , self . tx_in ) , ( '<STR_LIT>' , self . tx_out ) ] ) <EOL> class Block ( Message ) : <EOL> command = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT:version>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:32> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:32> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' , allow_float = True ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeTxn ( ) ) ) , <EOL> ] <EOL> @ staticmethod <EOL> def from_block ( block ) : <EOL> return Block ( block . version , block . previous_block_hash , <EOL> block . merkle_root , block . timestamp , block . bits , <EOL> block . nonce , block . transactions ) <EOL> def _debug ( self ) : <EOL> block_hash = util . get_block_header ( self . version , <EOL> self . prev_block , <EOL> self . merkle_root , <EOL> self . timestamp , <EOL> self . bits , <EOL> self . nonce ) <EOL> return _debug ( self , [ ( '<STR_LIT:h>' , block_hash . encode ( '<STR_LIT>' ) ) , ( '<STR_LIT:t>' , self . txns ) ] ) <EOL> class Headers ( Message ) : <EOL> command = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeBlockHeader ( ) ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT:h>' , self . headers ) ] ) <EOL> class GetAddress ( VersionAck ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> class MemoryPool ( VersionAck ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> class Ping ( Message ) : <EOL> command = '<STR_LIT>' <EOL> properties = [ <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:8> ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT:n>' , self . nonce . encode ( '<STR_LIT>' ) ) ] ) <EOL> class Pong ( Ping ) : <EOL> command = "<STR_LIT>" <EOL> class Reject ( Message ) : <EOL> command = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT:message>' , format . FormatTypeVarString ( ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:B>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeVarString ( ) ) , <EOL> ] <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT:m>' , self . message ) , ( '<STR_LIT:r>' , self . reason ) ] ) <EOL> class FilterLoad ( Message ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> do_not_register = True <EOL> properties = [ <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeNumber ( '<STR_LIT:B>' ) ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:B>' ) ) , <EOL> ] <EOL> class FilterLoad ( Message ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> do_not_register = True <EOL> properties = [ <EOL> ( '<STR_LIT:data>' , format . FormatTypeVarString ( ) ) , <EOL> ] <EOL> class FilterClear ( VersionAck ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> do_not_register = True <EOL> class MerkleBlock ( Message ) : <EOL> command = "<STR_LIT>" <EOL> name = "<STR_LIT>" <EOL> do_not_register = True <EOL> properties = [ <EOL> ( '<STR_LIT:version>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:32> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeBytes ( <NUM_LIT:32> ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' , allow_float = True ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeNumber ( '<STR_LIT:I>' ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeBytes ( <NUM_LIT:32> ) ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeArray ( format . FormatTypeNumber ( '<STR_LIT:b>' ) ) ) , <EOL> ] <EOL> class Alert ( Message ) : <EOL> command = "<STR_LIT>" <EOL> properties = [ <EOL> ( '<STR_LIT>' , format . FormatTypeVarString ( ) ) , <EOL> ( '<STR_LIT>' , format . FormatTypeVarString ( ) ) <EOL> ] <EOL> payload_properties = [ <EOL> '<STR_LIT:version>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:id>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ] <EOL> version = property ( lambda s : s . _parse_and_get ( '<STR_LIT:version>' ) ) <EOL> relay_until = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> expiration = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> id = property ( lambda s : s . _parse_and_get ( '<STR_LIT:id>' ) ) <EOL> cancel = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> set_cancel = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> min_ver = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> max_ver = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> set_sub_ver = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> priority = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> comment = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> status_bar = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> reserved = property ( lambda s : s . _parse_and_get ( '<STR_LIT>' ) ) <EOL> def _parse_and_get ( self , name ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . _data = dict ( ) <EOL> if not self . _data : <EOL> data = self . payload <EOL> self . _data = dict ( ) <EOL> offset = <NUM_LIT:0> <EOL> ( v , r , e , i , c ) = struct . unpack ( '<STR_LIT>' , data [ offset : offset + <NUM_LIT> ] ) <EOL> self . _data [ '<STR_LIT:version>' ] = v <EOL> self . _data [ '<STR_LIT>' ] = r <EOL> self . _data [ '<STR_LIT>' ] = e <EOL> self . _data [ '<STR_LIT:id>' ] = i <EOL> self . _data [ '<STR_LIT>' ] = c <EOL> offset += <NUM_LIT> <EOL> ( vl , s ) = format . parse_variable_set ( data [ offset : ] , format . FormatTypeNumber ( '<STR_LIT:i>' ) ) <EOL> self . _data [ '<STR_LIT>' ] = s <EOL> offset += vl <EOL> ( minver , maxver ) = struct . unpack ( '<STR_LIT>' , data [ offset : offset + <NUM_LIT:8> ] ) <EOL> self . _data [ '<STR_LIT>' ] = minver <EOL> self . _data [ '<STR_LIT>' ] = maxver <EOL> offset += <NUM_LIT:8> <EOL> ( vl , s ) = format . parse_variable_set ( data [ offset : ] , format . FormatTypeVarString ( ) ) <EOL> self . _data [ '<STR_LIT>' ] = s <EOL> offset += vl <EOL> ( p , ) = struct . unpack ( '<STR_LIT>' , data [ offset : offset + <NUM_LIT:4> ] ) <EOL> self . _data [ '<STR_LIT>' ] = p <EOL> offset += <NUM_LIT:4> <EOL> ( vl , c ) = format . FormatTypeVarString . parse ( data [ offset : ] ) <EOL> self . _data [ '<STR_LIT>' ] = c <EOL> offset += vl <EOL> ( vl , s ) = format . FormatTypeVarString . parse ( data [ offset : ] ) <EOL> self . _data [ '<STR_LIT>' ] = s <EOL> offset += vl <EOL> ( vl , r ) = format . FormatTypeVarString . parse ( data [ offset : ] ) <EOL> self . _data [ '<STR_LIT>' ] = r <EOL> offset += vl <EOL> return self . _data [ name ] <EOL> def verify ( self , public_key ) : <EOL> return util . ecc . verify ( self . payload , public_key , self . signature ) <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % ( self . version , self . relay_until , self . expiration , self . id , self . cancel , "<STR_LIT:U+002CU+0020>" . join ( str ( i ) for i in self . set_cancel ) , self . min_ver , self . max_ver , "<STR_LIT:U+002CU+0020>" . join ( self . set_sub_ver ) , self . priority , self . comment , self . status_bar , self . reserved ) <EOL> def _debug ( self ) : <EOL> return _debug ( self , [ ( '<STR_LIT:s>' , self . status_bar ) ] ) </s>
