def submitblock(self, params): err = { "code" : -1, "message" : "invalid params" } if (len(params) != 1 or (not isinstance(params[0], str) and not isinstance(params[0], unicode))): return (None, err) data = params[0].decode('hex') f = cStringIO.StringIO(data) block = CBlock() block.deserialize(f) res = self.chaindb.putblock(block) if not res: return ("rejected", None) return (None, None)
def __init__(self): self.blockcount = 0 self.rawmempool = {} self.on = True self._blockhashes, blocks_ser = load_obj(blockdata) self._blocks = {} for blockhash, block_ser in blocks_ser.items(): self._blocks[blockhash] = CBlock.deserialize(block_ser)
class BitcoinMainNet(object): # Replace global defs from bitcoin.core COIN = 100000000 MAX_MONEY = 21000000 * COIN MAX_BLOCK_SIZE = 1000000 MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE / 50 BIP0031_VERSION = 60000 PROTO_VERSION = 60002 MIN_PROTO_VERSION = 209 CADDR_TIME_VERSION = 31402 # Mimick bitcoinlib "params" global MESSAGE_START = b'\xf9\xbe\xb4\xd9' DEFAULT_PORT = 8333 RPC_PORT = 8332 DNS_SEEDS = (('bitcoin.sipa.be', 'seed.bitcoin.sipa.be'), ('bluematt.me', 'dnsseed.bluematt.me'), ('dashjr.org', 'dnsseed.bitcoin.dashjr.org'), ('bitcoinstats.com', 'seed.bitcoinstats.com'), ('xf2.org', 'bitseed.xf2.org')) BASE58_PREFIXES = {'PUBKEY_ADDR': 0, 'SCRIPT_ADDR': 5, 'SECRET_KEY': 128} # Mimick bitcoinlib "core_params" global NAME = 'bitcoin_mainnet' GENESIS_BLOCK = CBlock.deserialize( x('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000' )) SUBSIDY_HALVING_INTERVAL = 210000 PROOF_OF_WORK_LIMIT = 2**256 - 1 >> 32 # Not part of bitcoinlib CHECKPOINTS = { 0: 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26fL, 11111: 0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1dL, 33333: 0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6L, 74000: 0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20L, 105000: 0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97L, 134444: 0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0feL, 168000: 0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763L, 193000: 0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317L, } MEMPOOL_GD_VERSION = 60002 BIP0031_VERSION = 60000 NOBLKS_VERSION_START = 32000 NOBLKS_VERSION_END = 32400
def loadfile(filename): fd = os.open(filename, os.O_RDONLY) print("IMPORTING DATA FROM " + filename) buf = '' wanted = 4096 while True: if wanted > 0: if wanted < 4096: wanted = 4096 s = os.read(fd, wanted) if len(s) == 0: break buf += s wanted = 0 buflen = len(buf) startpos = string.find(buf, netmagic) startpos = 0 if startpos < 0: wanted = 8 continue sizepos = startpos + 4 blkpos = startpos + 8 if blkpos > buflen: wanted = 8 continue blksize = struct.unpack("<i", buf[sizepos:blkpos])[0] print "blkpos: ", blkpos, "blksize: ", blksize, "buflen: ", buflen if (blkpos + blksize) > buflen: wanted = 8 + blksize continue ser_blk = buf[blkpos:blkpos+blksize] buf = buf[blkpos+blksize:] f = cStringIO.StringIO(ser_blk) block = CBlock() block.deserialize(f) print block
def test_path_from_txid_to_merkleroot(self): def T(blk): merkle_root = blk.calc_merkle_root() for tx in blk.vtx: txid = tx.GetHash() path = path_from_txid_to_merkleroot(txid, blk) self.assertEqual(path(txid), merkle_root) # Block with two transactions in it blk170 = CBlock.deserialize(x('0100000055bd840a78798ad0da853f68974f3d183e2bd1db6a842c1feecf222a00000000ff104ccb05421ab93e63f8c3ce5c2c2e9dbb37de2764b3a3175c8166562cac7d51b96a49ffff001d283e9e700201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0102ffffffff0100f2052a01000000434104d46c4968bde02899d2aa0963367c7a6ce34eec332b32e42e5f3407e052d64ac625da6f0718e7b302140434bd725706957c092db53805b821a85b23a7ac61725bac000000000100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000')) T(blk170) # 99960 three transactions blk_3tx = CBlock.deserialize(x('01000000e78b20013e6e9a21b6366ead5d866b2f9dc00664508b90f24da8000000000000f94b61259c7e9af3455b277275800d0d6a58b929eedf9e0153a6ef2278a5d53408d11a4d4c86041b0fbf10b00301000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0119ffffffff0100f2052a0100000043410427e729f9cb5564abf2a1ccda596c636b77bd4d9d91f657d4738f3c70fce8ac4e12b1c782905554d9ff2c2e050fdfe3ff93c91c5817e617877d51f450b528c9e4ac000000000100000001e853c9e0c133547fd9e162b1d3860dd0f27d5b9b8a7430d28896c00fbb3f1bc7000000008c49304602210095bcd54ebd0caa7cee75f0f89de472a765e6ef4b98c5fd4b32c7f9d4905db9ae022100ebd3f668e3a1a36d56e30184c27531dbb9fc136c84b1282be562064d86997d1e014104727eb4fdcc90658cd26abe7dcb0ae7297810b15b9e27c32bcf8e3edd934901968806dc18b1276d7273cc4c223feee0070361ed947888a3cef422bebfede96e08ffffffff020065cd1d000000001976a91468c6c2b3c0bc4a8eeb10d16a300d627a31a3b58588ac0008af2f000000001976a9141d87f0a54a1d704ffc70eae83b025698bc0fdcfc88ac00000000010000000125f582f1d37b6713b14b85665a2daea4f464f5ed1c3ab3d4dcf152fb61414b9e000000008a473044022066ec12ced31659e1bf961b542b58bba76ba8f2a1e8f36d5f60be0601598eac21022047ce33685a63283a4c3ebc390261191f215999b2f7d8e1504b8af39aae4a2881014104c5e1d713d10fe59cc48f60701a3efcac418969c22e9c6cf57440f71e44dc82837af5351bf3e1d898f06aa5c792bf0251a39902311d1d27c16847b1b414494f35ffffffff02404b4c00000000001976a91466a3b2e43cfa5c6d9b2f0095f7be5a5cb608478c88ac80b8dc3c030000001976a9146df5ed8cee34df5c05c90406761a11ed143c202d88ac00000000')) T(blk_3tx) # 99993 four transactions blk_4tx = CBlock.deserialize(x('01000000acda3db591d5c2c63e8c09e7523a5b0581707ef3e3520d6ca180000000000000701179cb9a9e0fe709cc96261b6b943b31362b61dacba94b03f9b71a06cc2eff7d1c1b4d4c86041b75962f880401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0152ffffffff014034152a01000000434104216220ab283b5e2871c332de670d163fb1b7e509fd67db77997c5568e7c25afd988f19cd5cc5aec6430866ec64b5214826b28e0f7a86458073ff933994b47a5cac0000000001000000042a40ae58b06c3a61ae55dbee05cab546e80c508f71f24ef0cdc9749dac91ea5f000000004a49304602210089c685b37903c4aa62d984929afeaca554d1641f9a668398cd228fb54588f06b0221008a5cfbc5b0a38ba78c4f4341e53272b9cd0e377b2fb740106009b8d7fa693f0b01ffffffff7b999491e30af112b11105cb053bc3633a8a87f44740eb158849a76891ff228b00000000494830450221009a4aa8663ff4017063d2020519f2eade5b4e3e30be69bf9a62b4e6472d1747b2022021ee3b3090b8ce439dbf08a5df31e2dc23d68073ebda45dc573e8a4f74f5cdfc01ffffffffdea82ec2f9e88e0241faa676c13d093030b17c479770c6cc83239436a4327d49000000004a493046022100c29d9de71a34707c52578e355fa0fdc2bb69ce0a957e6b591658a02b1e039d69022100f82c8af79c166a822d305f0832fb800786d831aea419069b3aed97a6edf8f02101fffffffff3e7987da9981c2ae099f97a551783e1b21669ba0bf3aca8fe12896add91a11a0000000049483045022100e332c81781b281a3b35cf75a5a204a2be451746dad8147831255291ebac2604d02205f889a2935270d1bf1ef47db773d68c4d5c6a51bb51f082d3e1c491de63c345601ffffffff0100c817a8040000001976a91420420e56079150b50fb0617dce4c374bd61eccea88ac00000000010000000265a7293b2d69ba51d554cd32ac7586f7fbeaeea06835f26e03a2feab6aec375f000000004a493046022100922361eaafe316003087d355dd3c0ef3d9f44edae661c212a28a91e020408008022100c9b9c84d53d82c0ba9208f695c79eb42a453faea4d19706a8440e1d05e6cff7501fffffffff6971f00725d17c1c531088144b45ed795a307a22d51ca377c6f7f93675bb03a000000008b483045022100d060f2b2f4122edac61a25ea06396fe9135affdabc66d350b5ae1813bc6bf3f302205d8363deef2101fc9f3d528a8b3907e9d29c40772e587dcea12838c574cb80f801410449fce4a25c972a43a6bc67456407a0d4ced782d4cf8c0a35a130d5f65f0561e9f35198349a7c0b4ec79a15fead66bd7642f17cc8c40c5df95f15ac7190c76442ffffffff0200f2052a010000001976a914c3f537bc307c7eda43d86b55695e46047b770ea388ac00cf7b05000000001976a91407bef290008c089a60321b21b1df2d7f2202f40388ac0000000001000000014ab7418ecda2b2531eef0145d4644a4c82a7da1edd285d1aab1ec0595ac06b69000000008c493046022100a796490f89e0ef0326e8460edebff9161da19c36e00c7408608135f72ef0e03e0221009e01ef7bc17cddce8dfda1f1a6d3805c51f9ab2f8f2145793d8e85e0dd6e55300141043e6d26812f24a5a9485c9d40b8712215f0c3a37b0334d76b2c24fcafa587ae5258853b6f49ceeb29cd13ebb76aa79099fad84f516bbba47bd170576b121052f1ffffffff0200a24a04000000001976a9143542e17b6229a25d5b76909f9d28dd6ed9295b2088ac003fab01000000001976a9149cea2b6e3e64ad982c99ebba56a882b9e8a816fe88ac00000000')) T(blk_4tx)
def getwork_submit(self, hexstr): data = hexstr.decode('hex') if len(data) != 128: err = { "code" : -5, "message" : "invalid data" } return (None, err) data = bufreverse(data) blkhdr = data[:80] # why are we passing blkheader for constructing block, should not we pass the whole block" # f = cStringIO.StringIO(blkhdr) f = cStringIO.StringIO(data) block_tmp = CBlock() block_tmp.deserialize(f) if block_tmp.hashMerkleRoot not in self.work_blocks: return (False, None) block = self.work_blocks[block_tmp.hashMerkleRoot] block.nTime = block_tmp.nTime block.nNonce = block_tmp.nNonce res = self.chaindb.putblock(block) return (res, None)
def getwork_submit(self, hexstr): data = hexstr.decode('hex') if len(data) != 128: err = { "code" : -5, "message" : "invalid data" } return (None, err) data = bufreverse(data) blkhdr = data[:80] # FIXME(obulpathi): can we just use the blkheader? #f = cStringIO.StringIO(blkhdr) f = cStringIO.StringIO(data) block_tmp = CBlock() block_tmp.deserialize(f) if block_tmp.hashMerkleRoot not in self.work_blocks: return (False, None) block = self.work_blocks[block_tmp.hashMerkleRoot] block.nTime = block_tmp.nTime block.nNonce = block_tmp.nNonce res = self.chaindb.putblock(block) return (res, None)
def getblock(self, block_hash): """Get block <block_hash> Raises IndexError if block_hash is not valid. """ try: block_hash = b2lx(block_hash) except TypeError: raise TypeError('%s.getblock(): block_hash must be bytes; got %r instance' % (self.__class__.__name__, block_hash.__class__)) try: r = self._call('getblock', block_hash, False) except JSONRPCException as ex: raise IndexError('%s.getblock(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) return CBlock.deserialize(unhexlify(r))
def provide_block(self, block_data): """THIS METHOD WILL BLOCK UNTIL SENDING IS COMPLETE""" tx_count, read_pos = decode_varint(block_data, 80) self.send_lock.acquire() try: relay_data = pack('>3I', self.MAGIC_BYTES, self.BLOCK_TYPE, tx_count) + block_data[0:80] wire_bytes = 3 * 4 + 80 for i in range(0, tx_count): tx_start = read_pos read_pos += 4 tx_in_count, read_pos = decode_varint(block_data, read_pos) for j in range(0, tx_in_count): read_pos += 36 script_len, read_pos = decode_varint(block_data, read_pos) read_pos += script_len + 4 tx_out_count, read_pos = decode_varint(block_data, read_pos) for j in range(0, tx_out_count): read_pos += 8 script_len, read_pos = decode_varint(block_data, read_pos) read_pos += script_len read_pos += 4 transaction_data = block_data[tx_start:read_pos] tx_index = self.send_transaction_cache.get_index(transaction_data) if tx_index is None: relay_data += pack('>H', 0xffff) + pack('>HB', len(transaction_data) >> 8, len(transaction_data) & 0xff) + transaction_data wire_bytes += 2 + 3 + len(transaction_data) else: relay_data += pack('>H', tx_index) wire_bytes += 2 self.send_transaction_cache.remove(transaction_data) relay_data += pack('>3I', self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0) self.relay_sock.sendall(relay_data) if deserialize_utils: block = CBlock.deserialize(block_data) print("Sent block " + str(b2lx(block.GetHash())) + " of size " + str(len(block_data)) + " with " + str(wire_bytes) + " bytes on the wire") else: print("Sent block of size " + str(len(block_data)) + " with " + str(wire_bytes) + " bytes on the wire") except (OSError, socket.error) as err: print("Failed to send to relay node: ", err) finally: self.send_lock.release()
def getblock(self, block_hash): """Get block <block_hash> Raises IndexError if block_hash is not valid. """ try: block_hash = b2lx(block_hash) except TypeError: raise TypeError('%s.getblock(): block_hash must be bytes; got %r instance' % (self.__class__.__name__, block_hash.__class__)) try: # With this change ( https://github.com/bitcoin/bitcoin/commit/96c850c20913b191cff9f66fedbb68812b1a41ea#diff-a0c8f511d90e83aa9b5857e819ced344 ), # bitcoin core's rpc takes 0/1/2 instead of true/false as the 2nd argument which specifies verbosity, since v0.15.0. # The change above is backward-compatible so far; the old "false" is taken as the new "0". r = self._call('getblock', block_hash, False) except InvalidAddressOrKeyError as ex: raise IndexError('%s.getblock(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) return CBlock.deserialize(unhexlify(r))
class BitcoinRegTest(BitcoinMainNet): # Mimick bitcoinlib "core_params" global NAME = 'bitcoin_regtest' GENESIS_BLOCK = CBlock.deserialize( x('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000' )) SUBSIDY_HALVING_INTERVAL = 150 PROOF_OF_WORK_LIMIT = 2**256 - 1 >> 1 # Mimick bitcoinlib "params" global MESSAGE_START = b'\xfa\xbf\xb5\xda' DEFAULT_PORT = 18444 RPC_PORT = 18332 DNS_SEEDS = () BASE58_PREFIXES = { 'PUBKEY_ADDR': 111, 'SCRIPT_ADDR': 196, 'SECRET_KEY': 239 } CHECKPOINTS = {}
def getblock(self, block_hash): """Get block <block_hash> Raises IndexError if block_hash is not valid. """ try: block_hash = b2lx(block_hash) except TypeError: raise TypeError( '%s.getblock(): block_hash must be bytes; got %r instance' % (self.__class__.__name__, block_hash.__class__)) try: # With this change ( https://github.com/bitcoin/bitcoin/commit/96c850c20913b191cff9f66fedbb68812b1a41ea#diff-a0c8f511d90e83aa9b5857e819ced344 ), # bitcoin core's rpc takes 0/1/2 instead of true/false as the 2nd argument which specifies verbosity, since v0.15.0. # The change above is backward-compatible so far; the old "false" is taken as the new "0". r = self._call('getblock', block_hash, False) except InvalidAddressOrKeyError as ex: raise IndexError('%s.getblock(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) return CBlock.deserialize(unhexlify(r))
def deserialize(self, raw): """Deserialize hex-encoded block/block header.""" only_header = False if len(raw) == 160: only_header = True block = None block_header = None try: if only_header: block_header = CBlockHeader.deserialize(x(raw)) else: # We don't use block.get_header() in case the header is # correct but the rest of the block isn't. block_header = CBlockHeader.deserialize(x(raw[0:160])) block = CBlock.deserialize(x(raw)) except Exception: pass return (block, block_header)
def provide_block(self, block_data): # THIS METHOD WILL BLOCK UNTIL SENDING IS COMPLETE tx_count, read_pos = decode_varint(block_data, 80) self.send_lock.acquire() try: txn_bytes = [] for i in range(0, tx_count): tx_start = read_pos tx_in_count, read_pos = decode_varint(block_data, read_pos + 4) for j in range(0, tx_in_count): script_len, read_pos = decode_varint(block_data, read_pos + 36) read_pos += script_len + 4 tx_out_count, read_pos = decode_varint(block_data, read_pos) for j in range(0, tx_out_count): script_len, read_pos = decode_varint(block_data, read_pos + 8) read_pos += script_len read_pos += 4 txn_bytes.append(block_data[tx_start:read_pos]) send_data = pack('>3I', self.MAGIC_BYTES, self.BLOCK_TYPE, tx_count) + block_data[0:80] + b''.join((self.compress_tx(t) for t in txn_bytes)) self.relay_sock.sendall(send_data) self.relay_sock.sendall(pack('>3I', self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0)) if deserialize_utils: block = CBlock.deserialize(block_data) print("Sent block " + str(b2lx(block.GetHash())) + " of size " + str(len(block_data)) + " with " + str(len(send_data)) + " bytes on the wire") else: print("Sent block of size " + str(len(block_data)) + " with " + str(len(send_data)) + " bytes on the wire") except (OSError, socket.error) as err: print("Failed to send to relay node: ", err) self.relay_sock.shutdown(socket.SHUT_RDWR) finally: self.send_lock.release()
class BitcoinTestNet(BitcoinMainNet): # Mimick bitcoinlib "core_params" global NAME = 'bitcoin_testnet' GENESIS_BLOCK = CBlock.deserialize( x('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000' )) # Mimick bitcoinlib "params" global MESSAGE_START = b'\x0b\x11\x09\x07' DEFAULT_PORT = 18333 RPC_PORT = 18332 DNS_SEEDS = (('bitcoin.petertodd.org', 'testnet-seed.bitcoin.petertodd.org'), ('bluematt.me', 'testnet-seed.bluematt.me')) BASE58_PREFIXES = { 'PUBKEY_ADDR': 111, 'SCRIPT_ADDR': 196, 'SECRET_KEY': 239 } # Not part of bitcoinlib CHECKPOINTS = { 0: 0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943L, }
def getblock(block_hash): block_hex = BACKEND().getblock(block_hash) return CBlock.deserialize(util.unhexlify(block_hex))
log = Log.Log(SETTINGS['log']) mempool = MemPool.MemPool(log) chaindb = ChainDb.ChainDb(SETTINGS['db'], log, mempool, NETWORKS[MY_NETWORK]) scanned = 0 failures = 0 for height in xrange(chaindb.getheight()): heightidx = ChainDb.HeightIdx() heightidx.deserialize(chaindb.height[str(height)]) blkhash = heightidx.blocks[0] ser_hash = ser_uint256(blkhash) f = cStringIO.StringIO(chaindb.blocks[ser_hash]) block = CBlock() block.deserialize(f) if not block.is_valid(): log.write("block %064x failed" % (blkhash,)) failures += 1 scanned += 1 if (scanned % 1000) == 0: log.write("Scanned height %d (%d failures)" % ( height, failures)) log.write("Scanned %d blocks (%d failures)" % (scanned, failures))
def loadfile(filename,start,end,chaindb): fd = os.open(filename, os.O_RDONLY) #self.log.write("IMPORTING DATA FROM " + filename) buf = '' wanted = 4096 count = 1 while True: if wanted > 0: if wanted < 4096: wanted = 4096 s = os.read(fd, wanted) if len(s) == 0: break buf += s wanted = 0 buflen = len(buf) startpos = string.find(buf, msg_start) if startpos < 0: wanted = 8 continue sizepos = startpos + 4 blkpos = startpos + 8 if blkpos > buflen: wanted = 8 continue blksize = struct.unpack("<i", buf[sizepos:blkpos])[0] if (blkpos + blksize) > buflen: wanted = 8 + blksize continue ser_blk = buf[blkpos:blkpos+blksize] buf = buf[blkpos+blksize:] f = cStringIO.StringIO(ser_blk) block = CBlock() block.deserialize(f) count += 1 skip_load = (count < start) if skip_load: if ((count % 10000) == 0): print "skiping: %d" % count continue if (end > -1) and (count >= end): print "Exit!" sys.exit(0) ret = chaindb.putblock(block) height = chaindb.getheight() #if count == 778: # print repr(block) heightidx = ChainDb.HeightIdx() heightidx.deserialize(chaindb.height(str(height))) blkhash = heightidx.blocks[0] skiped = False scanned = False #skip_scan = (height < skip_scan_height) #if not skip_scan: # if ret: # scanned = scan_vtx(chaindb,block) strBlkHash = hex(blkhash).replace('0x','').replace('L','') print "Count: %d Putblock: %s Height: %d BlockHash: %s" % (count,ret,height,strBlkHash) print "tell: %d" % fd.tell() return count
def connect(self): self.send_lock.acquire() self.recv_transaction_cache = FlaggedArraySet(1000) self.send_transaction_cache = FlaggedArraySet(1000) self.relay_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.relay_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) try: try: self.relay_sock.connect((self.server, 8336)) self.relay_sock.sendall(pack('>3I', self.MAGIC_BYTES, self.VERSION_TYPE, len(self.VERSION_STRING))) self.relay_sock.sendall(self.VERSION_STRING) finally: self.send_lock.release() while True: msg_header = unpack('>3I', self.relay_sock.recv(3 * 4, socket.MSG_WAITALL)) if msg_header[0] != self.MAGIC_BYTES: raise ProtocolError("Invalid magic bytes: " + str(msg_header[0]) + " != " + str(self.MAGIC_BYTES)) if msg_header[2] > 1000000: raise ProtocolError("Got message too large: " + str(msg_header[2])) if msg_header[1] == self.VERSION_TYPE: version = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL) if version != self.VERSION_STRING: raise ProtocolError("Got back unknown version type " + str(version)) print("Connected to relay node with protocol version " + str(version)) elif msg_header[1] == self.BLOCK_TYPE: if msg_header[2] > 10000: raise ProtocolError("Got a BLOCK message with far too many transactions: " + str(msg_header[2])) wire_bytes = 3 * 4 header_data = self.relay_sock.recv(80, socket.MSG_WAITALL) wire_bytes += 80 self.data_recipient.provide_block_header(header_data) if deserialize_utils: header = CBlockHeader.deserialize(header_data) print("Got block header: " + str(b2lx(header.GetHash()))) if msg_header[2] < 0xfd: block_data = header_data + pack('B', msg_header[2]) elif msg_header[2] < 0xffff: block_data = header_data + b'\xfd' + pack('<H', msg_header[2]) elif msg_header[2] < 0xffffffff: block_data = header_data + b'\xfe' + pack('<I', msg_header[2]) else: raise ProtocolError("WTF?????") for i in range(0, msg_header[2]): index = unpack('>H', self.relay_sock.recv(2, socket.MSG_WAITALL))[0] wire_bytes += 2 if index == 0xffff: data_length = unpack('>HB', self.relay_sock.recv(3, socket.MSG_WAITALL)) wire_bytes += 3 data_length = data_length[0] << 8 | data_length[1] if data_length > 1000000: raise ProtocolError("Got in-block transaction of size > MAX_BLOCK_SIZE: " + str(dat_length)) transaction_data = self.relay_sock.recv(data_length, socket.MSG_WAITALL) wire_bytes += data_length if deserialize_utils: transaction = CTransaction.deserialize(transaction_data) print("Got in-block full transaction: " + str(b2lx(transaction.GetHash())) + " of length " + str(data_length)) else: print("Got in-block full transaction of length " + str(data_length)) block_data += transaction_data else: transaction_data = self.recv_transaction_cache.get_by_index(index) if transaction_data is None: raise ProtocolError("Got index for a transaction we didn't have") self.recv_transaction_cache.remove(transaction_data) block_data += transaction_data self.data_recipient.provide_block(block_data) if deserialize_utils: print("Got full block " + str(b2lx(header.GetHash())) + " with " + str(msg_header[2]) + " transactions in " + str(wire_bytes) + " wire bytes") block = CBlock.deserialize(block_data) print("Deserialized full block " + str(b2lx(block.GetHash()))) else: print("Got full block with " + str(msg_header[2]) + " transactions in " + str(wire_bytes) + " wire bytes") if unpack('>3I', self.relay_sock.recv(3 * 4, socket.MSG_WAITALL)) != (self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0): raise ProtocolError("Invalid END_BLOCK message after block") elif msg_header[1] == self.TRANSACTION_TYPE: if msg_header[2] > self.MAX_RELAY_TRANSACTION_BYTES and (self.recv_transaction_cache.get_flag_count() >= self.MAX_EXTRA_OVERSIZE_TRANSACTIONS or msg_header[2] > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES): raise ProtocolError("Got a freely relayed transaction too large (" + str(msg_header[2]) + ") bytes") transaction_data = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL) self.recv_transaction_cache.add(transaction_data, msg_header[2] > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES) self.data_recipient.provide_transaction(transaction_data) if deserialize_utils: transaction = CTransaction.deserialize(transaction_data) print("Got transaction: " + str(b2lx(transaction.GetHash()))) else: print("Got transaction of length " + str(msg_header[2])) elif msg_header[1] == self.MAX_VERSION_TYPE: version = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL) print("Relay network now uses version " + str(version) + " (PLEASE UPGRADE)") else: raise ProtocolError("Unknown message type: " + str(msg_header[1])) except (OSError, socket.error) as err: print("Lost connect to relay node:", err) self.reconnect() except ProtocolError as err: print("Error processing data from relay node:", err) self.reconnect() except Exception as err: print("Unknown error processing data from relay node:", err) self.reconnect()
def loadfile(filename, start, end, chaindb): fd = os.open(filename, os.O_RDONLY) #self.log.write("IMPORTING DATA FROM " + filename) buf = '' wanted = 4096 count = 1 while True: if wanted > 0: if wanted < 4096: wanted = 4096 s = os.read(fd, wanted) if len(s) == 0: break buf += s wanted = 0 buflen = len(buf) startpos = string.find(buf, msg_start) if startpos < 0: wanted = 8 continue sizepos = startpos + 4 blkpos = startpos + 8 if blkpos > buflen: wanted = 8 continue blksize = struct.unpack("<i", buf[sizepos:blkpos])[0] if (blkpos + blksize) > buflen: wanted = 8 + blksize continue ser_blk = buf[blkpos:blkpos + blksize] buf = buf[blkpos + blksize:] f = cStringIO.StringIO(ser_blk) block = CBlock() block.deserialize(f) count += 1 skip_load = (count < start) if skip_load: if ((count % 10000) == 0): print "skiping: %d" % count continue if (end > -1) and (count >= end): print "Exit!" sys.exit(0) ret = chaindb.putblock(block) height = chaindb.getheight() #if count == 778: # print repr(block) heightidx = ChainDb.HeightIdx() heightidx.deserialize(chaindb.height(str(height))) blkhash = heightidx.blocks[0] skiped = False scanned = False #skip_scan = (height < skip_scan_height) #if not skip_scan: # if ret: # scanned = scan_vtx(chaindb,block) strBlkHash = hex(blkhash).replace('0x', '').replace('L', '') print "Count: %d Putblock: %s Height: %d BlockHash: %s" % ( count, ret, height, strBlkHash) print "tell: %d" % fd.tell() return count