def getwork(bitcoind, use_getblocktemplate=False): def go(): if use_getblocktemplate: return bitcoind.rpc_getblocktemplate( dict(mode='template', rules=['segwit'])) else: return bitcoind.rpc_getmemorypool() try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found use_getblocktemplate = not use_getblocktemplate try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found print >> sys.stderr, 'Error: Bitcoin version too old! Upgrade to v0.5 or newer!' raise deferral.RetrySilentlyException() packed_transactions = [ x['data'].decode('hex') for x in work['transactions'] if len(x.get('depends', [])) == 0 ] if 'height' not in work: work['height'] = (yield bitcoind.rpc_getblock( work['previousblockhash']))['height'] + 1 elif p2pool.DEBUG: assert work['height'] == (yield bitcoind.rpc_getblock( work['previousblockhash']))['height'] + 1 defer.returnValue( dict( version=work['version'], previous_block=int(work['previousblockhash'], 16), transactions=map(bitcoin_data.tx_type.unpack, packed_transactions), transaction_hashes=map(bitcoin_data.hash256, packed_transactions), transaction_fees=[ x.get('fee', None) if isinstance(x, dict) else None for x in work['transactions'] ], subsidy=work['coinbasevalue'], devreward_value=work['coinbasedevreward']['value'], devreward_scriptpubkey=work['coinbasedevreward']['scriptpubkey'], time=work['time'] if 'time' in work else work['curtime'], bits=bitcoin_data.FloatingIntegerType().unpack( work['bits'].decode('hex')[::-1]) if isinstance( work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']), coinbaseflags=work['coinbaseflags'].decode('hex') if 'coinbaseflags' in work else ''.join( x.decode('hex') for x in work['coinbaseaux'].itervalues()) if 'coinbaseaux' in work else '', height=work['height'], rules=work.get('rules', []), last_update=time.time(), use_getblocktemplate=use_getblocktemplate, latency=end - start, ))
def get_blocks2(n): height = yield blockchain('q/getblockcount') res = [] for i in xrange(n): x = yield blockchain('block-height/%i?format=json' % (height - i,)) for block in x['blocks']: #print block header = dict( version=block['ver'], previous_block=int(block['prev_block'], 16), merkle_root=int(block['mrkl_root'], 16), timestamp=block['time'], bits=bitcoin_data.FloatingInteger(block['bits']), nonce=block['nonce'], ) assert bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)) == int(block['hash'], 16) # there seems to be no way to get the raw transaction # from blockchain.info (?format=hex doesn't work for # coinbase transctions ): so instead fake it txs = [dict( version=tx['ver'], tx_ins=[dict( previous_output=None, script='', sequence=0, ) for tx_in in tx['inputs']], tx_outs=[dict( value=tx_out['value'], script='\x6a' + 'blah'*100 if tx_out['type'] == -1 else p2pool_data.DONATION_SCRIPT if tx_out['addr'] == bitcoin_data.script2_to_address(p2pool_data.DONATION_SCRIPT, net) else bitcoin_data.pubkey_hash_to_script2(bitcoin_data.address_to_pubkey_hash(tx_out['addr'], net)), ) for tx_out in tx['out']], lock_time=0, ) for tx in block['tx']] #print txs[0] # fails because we don't have coinbase script ): #assert bitcoin_data.hash256(bitcoin_data.tx_type.pack(txs[0])) == block['tx'][0]['hash'] block2 = dict(header=header, txs=txs) res.append(dict( block=block2, height=block['height'], gentx_hash=int(block['tx'][0]['hash'], 16), )) defer.returnValue(res)
def test_header_hash_litecoin(self): assert networks.nets['litecoin'].POW_FUNC( data.block_header_type.pack( dict( version=1, previous_block= 0xd928d3066613d1c9dd424d5810cdd21bfeef3c698977e81ec1640e1084950073, merkle_root= 0x03f4b646b58a66594a182b02e425e7b3a93c8a52b600aa468f1bc5549f395f16, timestamp=1327807194, bits=data.FloatingInteger(0x1d01b56f), nonce=20736, ))) < 2**256 // 2**30
def test_header_hash(self): assert data.hash256( data.block_header_type.pack( dict( version=1, previous_block= 0x000000000000038a2a86b72387f93c51298298a732079b3b686df3603d2f6282, merkle_root= 0x37a43a3b812e4eb665975f46393b4360008824aab180f27d642de8c28073bc44, timestamp=1323752685, bits=data.FloatingInteger(437159528), nonce=3658685446, )) ) == 0x000000000000003aaaf7638f9f9c0d0c60e8b0eb817dcdb55fd2b1964efc5175
def get_block_header(self, hash): if hash == 0x16c169477c25421250ec5d32cf9c6d38538b5de970a2355fd89: return defer.succeed({ 'nonce': 1853158954, 'timestamp': 1351658517, 'merkle_root': 2282849479936278423916707524932131168473430114569971665822757638339486597658L, 'version': 1, 'previous_block': 1048610514577342396345362905164852351970507722694242579238530L, 'bits': bitcoin_data.FloatingInteger( bits=0x1a0513c5, target= 0x513c50000000000000000000000000000000000000000000000L), }) print hex(hash) return defer.fail('blah')
def __init__(self): self.blocks = [ 0x000000000000016c169477c25421250ec5d32cf9c6d38538b5de970a2355fd89 ] self.headers = { 0x16c169477c25421250ec5d32cf9c6d38538b5de970a2355fd89: { 'nonce': 1853158954, 'timestamp': 1351658517, 'merkle_root': 2282849479936278423916707524932131168473430114569971665822757638339486597658L, 'version': 1, 'previous_block': 1048610514577342396345362905164852351970507722694242579238530L, 'bits': bitcoin_data.FloatingInteger( bits=0x1a0513c5, target= 0x513c50000000000000000000000000000000000000000000000L), } }
def getwork(bitcoind, use_getblocktemplate=False, txidcache={}, feecache={}, feefifo=[], known_txs={}): def go(): if use_getblocktemplate: return bitcoind.rpc_getblocktemplate(dict(mode='template', rules=['segwit'])) else: return bitcoind.rpc_getmemorypool() try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found use_getblocktemplate = not use_getblocktemplate try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found print >>sys.stderr, 'Error: Bitcoin version too old! Upgrade to v0.5 or newer!' raise deferral.RetrySilentlyException() if not 'start' in txidcache: # we clear it every 30 min txidcache['start'] = time.time() t0 = time.time() unpacked_transactions = [] txhashes = [] cachehits = 0 cachemisses = 0 knownhits = 0 knownmisses = 0 for x in work['transactions']: fee = x['fee'] x = x['data'] if isinstance(x, dict) else x packed = None if x in txidcache: cachehits += 1 txid = (txidcache[x]) txhashes.append(txid) else: cachemisses += 1 packed = x.decode('hex') txid = bitcoin_data.hash256(packed) txidcache[x] = txid txhashes.append(txid) if txid in known_txs: knownhits += 1 unpacked = known_txs[txid] else: knownmisses += 1 if not packed: packed = x.decode('hex') unpacked = bitcoin_data.tx_type.unpack(packed) unpacked_transactions.append(unpacked) # The only place where we can get information on transaction fees is in GBT results, so we need to store those # for a while so we can spot shares that miscalculate the block reward if not txid in feecache: feecache[txid] = fee feefifo.append(txid) if time.time() - txidcache['start'] > 30*60.: keepers = {(x['data'] if isinstance(x, dict) else x):txid for x, txid in zip(work['transactions'], txhashes)} txidcache.clear() txidcache.update(keepers) # limit the fee cache to 100,000 entries, which should be about 10-20 MB fum = 100000 while len(feefifo) > fum: del feecache[feefifo.pop(0)] packed_transactions = [x['data'].decode('hex') for x in work['transactions'] if len(x.get('depends', [])) == 0] if 'height' not in work: work['height'] = (yield bitcoind.rpc_getblock(work['previousblockhash']))['height'] + 1 elif p2pool.DEBUG: assert work['height'] == (yield bitcoind.rpc_getblock(work['previousblockhash']))['height'] + 1 t1 = time.time() if p2pool.BENCH: print "%8.3f ms for helper.py:getwork(). Cache: %i hits %i misses, %i known_tx %i unknown %i cached" % ((t1 - t0)*1000., cachehits, cachemisses, knownhits, knownmisses, len(txidcache)) defer.returnValue(dict( version=work['version'], previous_block=int(work['previousblockhash'], 16), transactions=unpacked_transactions, transaction_hashes=txhashes, transaction_fees=[x.get('fee', None) if isinstance(x, dict) else None for x in work['transactions']], subsidy=work['coinbasevalue'], time=work['time'] if 'time' in work else work['curtime'], bits=bitcoin_data.FloatingIntegerType().unpack(work['bits'].decode('hex')[::-1]) if isinstance(work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']), coinbaseflags=work['coinbaseflags'].decode('hex') if 'coinbaseflags' in work else ''.join(x.decode('hex') for x in work['coinbaseaux'].itervalues()) if 'coinbaseaux' in work else '', height=work['height'], rules=work.get('rules', []), last_update=time.time(), use_getblocktemplate=use_getblocktemplate, latency=end - start, ))
#"hash" : "000008d60d927a984d19b852348711f8d21c261b1247e61b44f307580f2ca6b6" #"version" : 3, #"merkleroot" : "916fb05aed6373d6e5c49626efc0dea5d103038135bffbc86014f5204df2ebe3", #"mint" : 100.00000000, #"time" : 1367995782, #"nonce" : 58004, #"bits" : "1e0fffff", block_header = dict( version=3, previous_block=0xf260c39629d99355c5476d710d46ca0d35b3d962b44054b9ff943fe622, merkle_root= 0x916fb05aed6373d6e5c49626efc0dea5d103038135bffbc86014f5204df2ebe3, timestamp=1367995782, bits=data.FloatingInteger(0x1e0fffff), nonce=58004, ) DONATION_SCRIPT = '01210241b8aba0994f320a8b438c627dbf31fbdd7dc722dd8418d829d67a9c6e4fd69021036fbd9d0a34a569f10b0431c8aeecf74ad796b99838b7272ef35ded130a794f9b02ae'.decode( 'hex') print DONATION_SCRIPT[2:35].encode('hex') print data.pubkey_to_address(DONATION_SCRIPT[2:35], networks.nets['yacoin']) print networks.nets['yacoin'].POW_FUNC( data.block_header_type.pack(block_header)) print data.pubkey_hash_to_script2( data.address_to_pubkey_hash('YJL3vTFn7m82zQRs7XAXcJXnBNNmZdb1Ty', networks.nets['yacoin'])).encode('hex') donate = '4104ffd03de44a6e11b9917f3a29f9443283d9871c9d743ef30d5eddcd37094b64d1b3d8090496b53256786bf5c82932ec23c3b74d9f05a6f95a8b5529352656664bac'.decode(
def getwork(bitcoind, use_getblocktemplate=True): def go(): if use_getblocktemplate: return bitcoind.rpc_getblocktemplate(dict(mode='template')) else: return bitcoind.rpc_getmemorypool() try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found use_getblocktemplate = not use_getblocktemplate try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found print >> sys.stderr, 'Error: Bitcoin version too old! Upgrade to v0.5 or newer!' raise deferral.RetrySilentlyException() packed_transactions = [ (x['data'] if isinstance(x, dict) else x).decode('hex') for x in work['transactions'] ] if 'height' not in work: work['height'] = (yield bitcoind.rpc_getblock( work['previousblockhash']))['height'] + 1 elif p2pool.DEBUG: assert work['height'] == (yield bitcoind.rpc_getblock( work['previousblockhash']))['height'] + 1 # Smileycoin Payments packed_payments = [] payment_amount = 0 if 'payee' in work['richaddress']: g = {} g['payee'] = str(work['richaddress']['payee']) g['amount'] = work['richaddress']['amount'] if g['amount'] > 0: payment_amount += g['amount'] packed_payments.append(g) if 'payee' in work['EIASaddress']: g = {} g['payee'] = str(work['EIASaddress']['payee']) g['amount'] = work['EIASaddress']['amount'] if g['amount'] > 0: payment_amount += g['amount'] packed_payments.append(g) defer.returnValue( dict( version=work['version'], previous_block=int(work['previousblockhash'], 16), transactions=map(bitcoin_data.tx_type.unpack, packed_transactions), transaction_hashes=map(bitcoin_data.hash256, packed_transactions), transaction_fees=[ x.get('fee', None) if isinstance(x, dict) else None for x in work['transactions'] ], subsidy=work['coinbasevalue'], time=work['time'] if 'time' in work else work['curtime'], bits=bitcoin_data.FloatingIntegerType().unpack( work['bits'].decode('hex')[::-1]) if isinstance( work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']), coinbaseflags=work['coinbaseflags'].decode('hex') if 'coinbaseflags' in work else ''.join( x.decode('hex') for x in work['coinbaseaux'].itervalues()) if 'coinbaseaux' in work else '', height=work['height'], last_update=time.time(), use_getblocktemplate=use_getblocktemplate, latency=end - start, payment_amount=payment_amount, packed_payments=packed_payments, ))
def getwork(bitcoind, use_getblocktemplate=False): def go(): if use_getblocktemplate: return bitcoind.rpc_getblocktemplate(dict(mode='template')) else: return bitcoind.rpc_getmemorypool() try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found use_getblocktemplate = not use_getblocktemplate try: start = time.time() work = yield go() end = time.time() except jsonrpc.Error_for_code(-32601): # Method not found print >>sys.stderr, 'Error: Bitcoin version too old! Upgrade to v0.5 or newer!' raise deferral.RetrySilentlyException() packed_transactions = [(x['data'] if isinstance(x, dict) else x).decode('hex') for x in work['transactions']] if 'height' not in work: work['height'] = (yield bitcoind.rpc_getblock(work['previousblockhash']))['height'] + 1 elif p2pool.DEBUG: assert work['height'] == (yield bitcoind.rpc_getblock(work['previousblockhash']))['height'] + 1 fee_list = [x.get('fee', None) if isinstance(x, dict) else None for x in work['transactions']] # for FRC Parent transform unicode fees to int fee_helper = [] for fee in fee_list: if isinstance(fee, unicode): float_fee = float(fee) int_fee = int(float_fee * 100000000) fee_helper.append(int_fee) else: fee_helper.append(fee) fee_list = fee_helper defer.returnValue(dict( version=work['version'], previous_block=int(work['previousblockhash'], 16), transactions=map(bitcoin_data.tx_type.unpack, packed_transactions), transaction_hashes=map(bitcoin_data.hash256, packed_transactions), transaction_fees=fee_list, # for FRC Parent +fee_list subsidy=work['coinbasevalue'], time=work['time'] if 'time' in work else work['curtime'], bits=bitcoin_data.FloatingIntegerType().unpack(work['bits'].decode('hex')[::-1]) if isinstance(work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']), coinbaseflags=work['coinbaseflags'].decode('hex') if 'coinbaseflags' in work else ''.join(x.decode('hex') for x in work['coinbaseaux'].itervalues()) if 'coinbaseaux' in work else '', height=work['height'], last_update=time.time(), use_getblocktemplate=use_getblocktemplate, latency=end - start, ))