def getblock(self, blockid): """ Get specific block from database cache. :param blockid: Block height or block hash :type blockid: int, str :return Block: """ if not self.cache_enabled(): return False qr = self.session.query(DbCacheBlock) if isinstance(blockid, int): block = qr.filter_by(height=blockid, network_name=self.network.name).scalar() else: block = qr.filter_by(block_hash=to_bytes(blockid)).scalar() if not block: return False b = Block(block_hash=block.block_hash, height=block.height, network=block.network_name, merkle_root=block.merkle_root, time=block.time, nonce=block.nonce, version=block.version, prev_block=block.prev_block, bits=block.bits) b.tx_count = block.tx_count _logger.info("Retrieved block with height %d from cache" % b.height) return b
def getblock(self, blockid): if not SERVICE_CACHING_ENABLED: return False qr = self.session.query(DbCacheBlock) if isinstance(blockid, int): block = qr.filter_by(height=blockid, network_name=self.network.name).scalar() else: block = qr.filter_by(block_hash=to_bytes(blockid)).scalar() if not block: return False b = Block(block_hash=block.block_hash, height=block.height, network=block.network_name, merkle_root=block.merkle_root, time=block.time, nonce=block.nonce, version=block.version, prev_block=block.prev_block, bits=block.bits) b.tx_count = block.tx_count _logger.info("Retrieved block with height %d from cache" % b.height) return b
def test_blocks_create_block(self): block_hash = '00000000000023b05c9ae15577257daf17029604eba0a58824e93306e44d0c62' height = 123123 version = 1 merkle_root = '37495012489500f0c7ca8bf5bfa116cc8cf46d34214cfbd3b73f6d84d4e667f0' prev_block = '000000000000668a34cfab030cf33b865cf3f5eaac46c70f665b70524528f078' bits = 443192243 time = 1305042430 nonce = 3568752398 b = Block(block_hash, version, prev_block, merkle_root, time, bits, nonce, height=height) expected_dict = {'block_hash': '00000000000023b05c9ae15577257daf17029604eba0a58824e93306e44d0c62', 'height': 123123, 'version': 1, 'prev_block': '000000000000668a34cfab030cf33b865cf3f5eaac46c70f665b70524528f078', 'merkle_root': '37495012489500f0c7ca8bf5bfa116cc8cf46d34214cfbd3b73f6d84d4e667f0', 'timestamp': 1305042430, 'bits': 443192243, 'nonce': 3568752398, 'target': '0000000000006a93b30000000000000000000000000000000000000000000000', 'difficulty': 157416.40184364893} self.assertDictEqualExt(b.as_dict(), expected_dict)
def test_blocks_parse_block_and_transactions(self): b = Block.from_raw(self.rb250000, parse_transactions=True) self.assertEqual(to_hexstring(b.block_hash), '000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214') self.assertEqual(b.height, 250000) self.assertEqual(b.version_int, 2) self.assertEqual(b.prev_block, to_bytes('0000000000000009c2e82d884ec07b4aafb64ca3ef83baca2b6b0b5eb72c8f02')) self.assertEqual(b.merkle_root, to_bytes('16ec1eafaca8ca59d182cbf94f29b50b06ac4207b883f380b9bf547fe8fed723')) self.assertEqual(b.bits_int, 0x1972dbf2) self.assertEqual(b.time, 1375533383) self.assertEqual(b.nonce_int, 0x917661) self.assertEqual(int(b.difficulty), 37392766) self.assertEqual(b.target, 720982641204331278205950312227594303241470815982254303477760) self.assertEqual(b.tx_count, 156) self.assertEqual(b.transactions[0].txid, '7ae2ab185a6e501753f6e29e5b6a98ba040098acb7c11ffed9430f22ed5263a3') self.assertEqual(b.transactions[49].txid, '3b6d97f107cba804270f4d22fafda3295b3bfb735366da6c1473157cc94a5f7c') self.assertEqual(b.transactions[122].txid, 'a5cc9bd850b6eedc3e466b3e0f5c85fb640de0a3537259eb0cae761d0a4f78b4') self.assertEqual(b.transactions[155].txid, 'e3d6cb87bd37ca53509cdc9ecdabf82ef966d9b25a2598b7de87c8173beb40d5')
def test_blocks_parse_block_and_transactions(self): b = Block.from_raw(self.rb330000, parse_transactions=True, limit=5) self.assertEqual(to_hexstring(b.block_hash), '00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02') self.assertEqual(b.height, 330000) self.assertEqual(b.version_int, 2) self.assertEqual(b.prev_block, to_bytes('000000000000000003e20f90920dc065da4a507bcf045f44b9abac7fabff4857')) self.assertEqual(b.merkle_root, to_bytes('5a97519772c615a875c12859f447d9c1fea922f7e36bd08e96cc95eee235d28f')) self.assertEqual(b.bits_int, 404472624) self.assertEqual(b.time, 1415983209) self.assertEqual(b.nonce_int, 3756201140) self.assertEqual(int(b.difficulty), 39603666252) self.assertEqual(b.tx_count, 81) self.assertEqual(b.transactions[0].txid, 'dfd63430f8d14f6545117d74b20da63efd4a75c7e28f723b3dead431b88469ee') self.assertEqual(b.transactions[4].txid, '717bc8b42f12baf771b6719c2e3b2742925fe3912917c716abef03e35fe49020') self.assertEqual(len(b.transactions), 5) b.parse_transactions(70) self.assertEqual(len(b.transactions), 75) b.parse_transactions(10) self.assertEqual(len(b.transactions), 81) self.assertEqual(b.transactions[80].txid, '7c8483c890942334ecb73db3802f7571b06047b5c15febe3bad11e460065709b')
def test_blocks_parse_genesis(self): raw_block = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3' \ 'e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c010100000001000000000000000000' \ '0000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d657320303' \ '32f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f7574' \ '20666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03' \ '909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000' b = Block.from_raw(to_bytes(raw_block), height=0) self.assertEqual(to_hexstring(b.block_hash), '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f') self.assertEqual(b.height, 0) self.assertEqual(b.version_int, 1) self.assertEqual(b.prev_block, 32 * b'\x00') self.assertEqual(to_hexstring(b.merkle_root), '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b') self.assertEqual(to_hexstring(b.bits), '1d00ffff') self.assertEqual(b.time, 1231006505) self.assertEqual(to_hexstring(b.nonce), '7c2bac1d') self.assertEqual(b.difficulty, 1) self.assertEqual(b.target_hex, '00000000ffff0000000000000000000000000000000000000000000000000000') self.assertEqual(b.tx_count, 1) self.assertEqual(str(b), '<Block(000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f, 0, transactions: 1)>')
def getblock(self, blockid, parse_transactions=True, page=1, limit=None): """ Get block with specified block height or block hash from service providers. If parse_transaction is set to True a list of Transaction object will be returned otherwise a list of transaction ID's. Some providers require 1 or 2 extra request per transaction, so to avoid timeouts or rate limiting errors you can specify a page and limit for the transaction. For instance with page=2, limit=4 only transaction 5 to 8 are returned in the Blocks's 'transaction' attribute. If you only use a local bcoin or bitcoind provider, make sure you set the limit to maximum (i.e. 9999) because all transactions are already downloaded when fetching the block. >>> from bitcoinlib.services.services import Service >>> srv = Service() >>> b = srv.getblock(0) >>> b <Block(000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f, 0, transactions: 1)> :param blockid: Hash or block height of block :type blockid: str, int :param parse_transactions: Return Transaction objects or just transaction ID's. Default is return txids. :type parse_transactions: bool :param page: Page number of transaction paging. Default is start from the beginning: 1 :type page: int :param limit: Maximum amount of transaction to return. Default is 10 is parse transaction is enabled, otherwise returns all txid's (9999) :type limit: int :return Block: """ if not limit: limit = 10 if parse_transactions else 99999 block = self.cache.getblock(blockid) is_last_page = False if block: # Block found get transactions from cache block.transactions = self.cache.getblocktransactions( block.height, page, limit) if block.transactions: self.results_cache_n = 1 is_last_page = page * limit > block.tx_count if not block or not len(block.transactions) or (not is_last_page and len(block.transactions) < limit) or \ (is_last_page and ((page-1)*limit - block.tx_count + len(block.transactions)) < 0): self.results_cache_n = 0 bd = self._provider_execute('getblock', blockid, parse_transactions, page, limit) if not bd or isinstance(bd, bool): return False block = Block(bd['block_hash'], bd['version'], bd['prev_block'], bd['merkle_root'], bd['time'], bd['bits'], bd['nonce'], bd['txs'], bd['height'], bd['depth'], self.network) block.tx_count = bd['tx_count'] block.limit = limit block.page = page if parse_transactions and self.min_providers <= 1: order_n = (page - 1) * limit for tx in block.transactions: if isinstance(tx, Transaction): self.cache.store_transaction(tx, order_n, commit=False) order_n += 1 self.cache.session.commit() self.complete = True if len( block.transactions) == block.tx_count else False self.cache.store_block(block) return block
def test_block_serialize(self): b = Block.from_raw(self.rb330000, parse_transactions=True) rb_ser = b.serialize() self.assertEqual(rb_ser, self.rb330000)