<s> import os , sys <EOL> import json <EOL> import hashlib <EOL> import httplib <EOL> import threading , time <EOL> from socket import error as SocketError <EOL> from bitcoin . rpc import JSONRPCException <EOL> import web <EOL> from coloredcoinlib import BlockchainState , ColorDefinition <EOL> urls = ( <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> ) <EOL> testnet = False <EOL> if ( len ( sys . argv ) > <NUM_LIT:2> ) and ( sys . argv [ <NUM_LIT:2> ] == '<STR_LIT>' ) : <EOL> testnet = True <EOL> HEADERS_FILE = '<STR_LIT>' if testnet else '<STR_LIT>' <EOL> if ( len ( sys . argv ) > <NUM_LIT:3> ) : <EOL> HEADERS_FILE = sys . argv [ <NUM_LIT:3> ] <EOL> class ErrorThrowingRequestProcessor : <EOL> def require ( self , data , key , message ) : <EOL> value = data . get ( key , None ) <EOL> if value is None : <EOL> raise web . HTTPError ( "<STR_LIT>" , <EOL> { "<STR_LIT>" : "<STR_LIT>" } , <EOL> message ) <EOL> class Tx ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> data = json . loads ( web . data ( ) ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> txhash = data . get ( '<STR_LIT>' ) <EOL> print txhash <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> return blockchainstate . get_raw ( txhash ) <EOL> class PublishTx ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> txdata = web . data ( ) <EOL> reply = None <EOL> try : <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> reply = blockchainstate . bitcoind . sendrawtransaction ( txdata ) <EOL> except Exception as e : <EOL> reply = ( "<STR_LIT>" + str ( e ) ) <EOL> return reply <EOL> class TxBlockhash ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> data = json . loads ( web . data ( ) ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> txhash = data . get ( '<STR_LIT>' ) <EOL> print txhash <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> blockhash , in_mempool = blockchainstate . get_tx_blockhash ( txhash ) <EOL> return json . dumps ( [ blockhash , in_mempool ] ) <EOL> class Prefetch ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> data = json . loads ( web . data ( ) ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> txhash = data . get ( '<STR_LIT>' ) <EOL> output_set = data . get ( '<STR_LIT>' ) <EOL> color_desc = data . get ( '<STR_LIT>' ) <EOL> limit = data . get ( '<STR_LIT>' ) <EOL> color_def = ColorDefinition . from_color_desc ( <NUM_LIT> , color_desc ) <EOL> tx_lookup = { } <EOL> def process ( current_txhash , current_outindex ) : <EOL> """<STR_LIT>""" <EOL> if limit and len ( tx_lookup ) > limit : <EOL> return <EOL> if tx_lookup . get ( current_txhash ) : <EOL> return <EOL> current_tx = blockchainstate . get_tx ( current_txhash ) <EOL> if not current_tx : <EOL> return <EOL> tx_lookup [ current_txhash ] = blockchainstate . get_raw ( current_txhash ) <EOL> inputs = set ( ) <EOL> inputs = inputs . union ( <EOL> color_def . get_affecting_inputs ( current_tx , <EOL> [ current_outindex ] ) ) <EOL> for i in inputs : <EOL> process ( i . prevout . hash , i . prevout . n ) <EOL> for oi in output_set : <EOL> process ( txhash , oi ) <EOL> return tx_lookup <EOL> class BlockCount ( ErrorThrowingRequestProcessor ) : <EOL> def GET ( self ) : <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> return str ( blockchainstate . get_block_count ( ) ) <EOL> class DecimalEncoder ( json . JSONEncoder ) : <EOL> def default ( self , o ) : <EOL> import decimal <EOL> if isinstance ( o , decimal . Decimal ) : <EOL> return str ( o ) <EOL> return super ( DecimalEncoder , self ) . default ( o ) <EOL> class Header ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> data = json . loads ( web . data ( ) ) <EOL> block_hash = data . get ( '<STR_LIT>' ) <EOL> if not block_hash : <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> height = data . get ( '<STR_LIT>' ) <EOL> block_hash = blockchainstate . get_block_hash ( height ) <EOL> block = blockchainstate . get_block ( block_hash ) <EOL> return json . dumps ( { <EOL> '<STR_LIT>' : block [ '<STR_LIT>' ] , <EOL> '<STR_LIT:version>' : block [ '<STR_LIT:version>' ] , <EOL> '<STR_LIT>' : block [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : block [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : block [ '<STR_LIT:time>' ] , <EOL> '<STR_LIT>' : int ( block [ '<STR_LIT>' ] , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : block [ '<STR_LIT>' ] , <EOL> } , cls = DecimalEncoder ) <EOL> class ChunkThread ( threading . Thread ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> threading . Thread . __init__ ( self , * args , ** kwargs ) <EOL> self . running = False <EOL> self . lock = threading . Lock ( ) <EOL> self . headers = '<STR_LIT>' <EOL> def is_running ( self ) : <EOL> with self . lock : <EOL> return self . running <EOL> def stop ( self ) : <EOL> with self . lock : <EOL> self . running = False <EOL> def run ( self ) : <EOL> self . headers = open ( HEADERS_FILE , '<STR_LIT>' ) . read ( ) <EOL> with self . lock : <EOL> self . running = True <EOL> run_time = time . time ( ) <EOL> while self . is_running ( ) : <EOL> if run_time > time . time ( ) : <EOL> time . sleep ( <NUM_LIT> ) <EOL> continue <EOL> run_time = time . time ( ) + <NUM_LIT:1> <EOL> try : <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> height = blockchainstate . get_block_count ( ) <EOL> if height == self . height : <EOL> continue <EOL> if height < self . height : <EOL> self . headers = self . headers [ : height * <NUM_LIT> ] <EOL> while height > self . height : <EOL> if not self . is_running ( ) : <EOL> break <EOL> block_height = self . height + <NUM_LIT:1> <EOL> blockhash = blockchainstate . get_block_hash ( block_height ) <EOL> block = blockchainstate . get_block ( blockhash ) <EOL> if block_height == <NUM_LIT:0> : <EOL> self . headers = self . _header_to_string ( block ) <EOL> else : <EOL> prev_hash = self . _hash_header ( self . headers [ - <NUM_LIT> : ] ) <EOL> if prev_hash == block [ '<STR_LIT>' ] : <EOL> self . headers += self . _header_to_string ( block ) <EOL> else : <EOL> self . headers = self . headers [ : - <NUM_LIT> ] <EOL> open ( HEADERS_FILE , '<STR_LIT:wb>' ) . write ( self . headers ) <EOL> except httplib . BadStatusLine : <EOL> pass <EOL> except SocketError : <EOL> pass <EOL> except JSONRPCException as e : <EOL> if e . error [ "<STR_LIT:code>" ] != - <NUM_LIT> : <EOL> raise <EOL> pass <EOL> @ property <EOL> def height ( self ) : <EOL> return len ( self . headers ) / <NUM_LIT> - <NUM_LIT:1> <EOL> def _rev_hex ( self , s ) : <EOL> return s . decode ( '<STR_LIT>' ) [ : : - <NUM_LIT:1> ] . encode ( '<STR_LIT>' ) <EOL> def _int_to_hex ( self , i , length = <NUM_LIT:1> ) : <EOL> s = hex ( i ) [ <NUM_LIT:2> : ] . rstrip ( '<STR_LIT:L>' ) <EOL> s = "<STR_LIT:0>" * ( <NUM_LIT:2> * length - len ( s ) ) + s <EOL> return self . _rev_hex ( s ) <EOL> def _header_to_string ( self , h ) : <EOL> s = self . _int_to_hex ( h . get ( '<STR_LIT:version>' ) , <NUM_LIT:4> ) + self . _rev_hex ( h . get ( '<STR_LIT>' , "<STR_LIT:0>" * <NUM_LIT:64> ) ) + self . _rev_hex ( h . get ( '<STR_LIT>' ) ) + self . _int_to_hex ( h . get ( '<STR_LIT:time>' ) , <NUM_LIT:4> ) + self . _rev_hex ( h . get ( '<STR_LIT>' ) ) + self . _int_to_hex ( h . get ( '<STR_LIT>' ) , <NUM_LIT:4> ) <EOL> return s . decode ( '<STR_LIT>' ) <EOL> def _hash_header ( self , raw_header ) : <EOL> return hashlib . sha256 ( hashlib . sha256 ( raw_header ) . digest ( ) ) . digest ( ) [ : : - <NUM_LIT:1> ] . encode ( '<STR_LIT>' ) <EOL> chunkThread = ChunkThread ( ) <EOL> class Chunk ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> data = json . loads ( web . data ( ) ) <EOL> self . require ( data , '<STR_LIT:index>' , "<STR_LIT>" ) <EOL> index = data . get ( '<STR_LIT:index>' ) <EOL> with open ( HEADERS_FILE , '<STR_LIT:rb>' ) as headers : <EOL> headers . seek ( index * <NUM_LIT> * <NUM_LIT> ) <EOL> return headers . read ( <NUM_LIT> * <NUM_LIT> ) <EOL> class Merkle ( ErrorThrowingRequestProcessor ) : <EOL> def POST ( self ) : <EOL> data = json . loads ( web . data ( ) ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> self . require ( data , '<STR_LIT>' , "<STR_LIT>" ) <EOL> txhash = data . get ( '<STR_LIT>' ) <EOL> blockhash = data . get ( '<STR_LIT>' ) <EOL> hash_decode = lambda x : x . decode ( '<STR_LIT>' ) [ : : - <NUM_LIT:1> ] <EOL> hash_encode = lambda x : x [ : : - <NUM_LIT:1> ] . encode ( '<STR_LIT>' ) <EOL> Hash = lambda x : hashlib . sha256 ( hashlib . sha256 ( x ) . digest ( ) ) . digest ( ) <EOL> blockchainstate = BlockchainState . from_url ( None , testnet ) <EOL> b = blockchainstate . get_block ( blockhash ) <EOL> tx_list = b . get ( '<STR_LIT>' ) <EOL> tx_pos = tx_list . index ( txhash ) <EOL> merkle = map ( hash_decode , tx_list ) <EOL> target_hash = hash_decode ( txhash ) <EOL> s = [ ] <EOL> while len ( merkle ) != <NUM_LIT:1> : <EOL> if len ( merkle ) % <NUM_LIT:2> : <EOL> merkle . append ( merkle [ - <NUM_LIT:1> ] ) <EOL> n = [ ] <EOL> while merkle : <EOL> new_hash = Hash ( merkle [ <NUM_LIT:0> ] + merkle [ <NUM_LIT:1> ] ) <EOL> if merkle [ <NUM_LIT:0> ] == target_hash : <EOL> s . append ( hash_encode ( merkle [ <NUM_LIT:1> ] ) ) <EOL> target_hash = new_hash <EOL> elif merkle [ <NUM_LIT:1> ] == target_hash : <EOL> s . append ( hash_encode ( merkle [ <NUM_LIT:0> ] ) ) <EOL> target_hash = new_hash <EOL> n . append ( new_hash ) <EOL> merkle = merkle [ <NUM_LIT:2> : ] <EOL> merkle = n <EOL> return json . dumps ( { "<STR_LIT>" : b . get ( '<STR_LIT>' ) , "<STR_LIT>" : s , "<STR_LIT>" : tx_pos } ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> import signal <EOL> def sigint_handler ( signum , frame ) : <EOL> print ( '<STR_LIT>' ) <EOL> chunkThread . stop ( ) <EOL> print ( '<STR_LIT>' ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> signal . signal ( signal . SIGINT , sigint_handler ) <EOL> chunkThread . start ( ) <EOL> app = web . application ( urls , globals ( ) ) <EOL> app . run ( ) </s>
