From a3ae4158ed4726a5d7e6ca29867969e0edc920fd Mon Sep 17 00:00:00 2001 From: Cryp Toon Date: Tue, 13 Feb 2024 20:40:47 +0100 Subject: [PATCH] Add index, transaction order in block --- bitcoinlib/blocks.py | 4 +- bitcoinlib/db.py | 2 +- bitcoinlib/db_cache.py | 2 +- bitcoinlib/services/bcoin.py | 1 + bitcoinlib/services/services.py | 32 +++++----- bitcoinlib/transactions.py | 12 ++-- tests/benchmark.py | 104 -------------------------------- tests/test_blocks.py | 1 + tests/test_keys.py | 16 ++--- tests/test_services.py | 40 +++++++----- tests/test_transactions.py | 2 - 11 files changed, 61 insertions(+), 155 deletions(-) delete mode 100644 tests/benchmark.py diff --git a/bitcoinlib/blocks.py b/bitcoinlib/blocks.py index f051e61c..d0526d13 100644 --- a/bitcoinlib/blocks.py +++ b/bitcoinlib/blocks.py @@ -251,11 +251,13 @@ def parse_bytesio(cls, raw, block_hash=None, height=None, parse_transactions=Fal raw.seek(tx_start_pos) transactions = [] + index = 0 while parse_transactions and raw.tell() < txs_data_size: if limit != 0 and len(transactions) >= limit: break - t = Transaction.parse_bytesio(raw, strict=False) + t = Transaction.parse_bytesio(raw, strict=False, index=index) transactions.append(t) + index += 1 # TODO: verify transactions, need input value from previous txs # if verify and not t.verify(): # raise ValueError("Could not verify transaction %s in block %s" % (t.txid, block_hash)) diff --git a/bitcoinlib/db.py b/bitcoinlib/db.py index 821d0df0..c8965d0e 100644 --- a/bitcoinlib/db.py +++ b/bitcoinlib/db.py @@ -413,7 +413,7 @@ class DbTransaction(Base): raw = Column(LargeBinary, doc="Raw transaction hexadecimal string. Transaction is included in raw format on the blockchain") verified = Column(Boolean, default=False, doc="Is transaction verified. Default is False") - order_n = Column(Integer, doc="Order of transaction in block") + index = Column(Integer, doc="Index of transaction in block") __table_args__ = ( UniqueConstraint('wallet_id', 'txid', name='constraint_wallet_transaction_hash_unique'), diff --git a/bitcoinlib/db_cache.py b/bitcoinlib/db_cache.py index c386606a..811e6119 100644 --- a/bitcoinlib/db_cache.py +++ b/bitcoinlib/db_cache.py @@ -136,7 +136,7 @@ class DbCacheTransaction(Base): fee = Column(BigInteger, doc="Transaction fee") nodes = relationship("DbCacheTransactionNode", cascade="all,delete", doc="List of all inputs and outputs as DbCacheTransactionNode objects") - order_n = Column(Integer, doc="Order of transaction in block") + index = Column(Integer, doc="Index of transaction in block") witness_type = Column(Enum(WitnessTypeTransactions), default=WitnessTypeTransactions.legacy, doc="Transaction type enum: legacy or segwit") diff --git a/bitcoinlib/services/bcoin.py b/bitcoinlib/services/bcoin.py index bfe33ed8..5a06f77c 100644 --- a/bitcoinlib/services/bcoin.py +++ b/bitcoinlib/services/bcoin.py @@ -59,6 +59,7 @@ def _parse_transaction(self, tx): t.block_height = tx['height'] if tx['height'] > 0 else None t.block_hash = tx['block'] t.status = status + t.index = tx['index'] if not t.coinbase: for i in t.inputs: i.value = tx['inputs'][t.inputs.index(i)]['coin']['value'] diff --git a/bitcoinlib/services/services.py b/bitcoinlib/services/services.py index 2219e29c..dd5a22cc 100644 --- a/bitcoinlib/services/services.py +++ b/bitcoinlib/services/services.py @@ -382,11 +382,11 @@ def gettransactions(self, address, after_txid='', limit=MAX_TRANSACTIONS): if len(txs): last_txid = bytes.fromhex(txs[-1:][0].txid) if len(self.results): - order_n = 0 + index = 0 for t in txs: if t.confirmations != 0: - res = self.cache.store_transaction(t, order_n, commit=False) - order_n += 1 + res = self.cache.store_transaction(t, index, commit=False) + index += 1 # Failure to store transaction: stop caching transaction and store last tx block height - 1 if res is False: if t.block_height: @@ -556,11 +556,11 @@ def getblock(self, blockid, parse_transactions=True, page=1, limit=None): block.page = page if parse_transactions and self.min_providers <= 1: - order_n = (page-1)*limit + index = (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.store_transaction(tx, index, commit=False) + index += 1 self.cache.commit() self.complete = True if len(block.transactions) == block.tx_count else False self.cache.store_block(block) @@ -717,7 +717,7 @@ def _parse_db_transaction(db_tx): t = Transaction(locktime=db_tx.locktime, version=db_tx.version, network=db_tx.network_name, fee=db_tx.fee, txid=db_tx.txid.hex(), date=db_tx.date, confirmations=db_tx.confirmations, block_height=db_tx.block_height, status='confirmed', witness_type=db_tx.witness_type.value, - order_n=db_tx.order_n) + index=db_tx.index) for n in db_tx.nodes: if n.is_input: if n.ref_txid == b'\00' * 32: @@ -794,7 +794,7 @@ def gettransactions(self, address, after_txid='', limit=MAX_TRANSACTIONS): filter(DbCacheTransactionNode.address == address, DbCacheTransaction.block_height >= after_tx.block_height, DbCacheTransaction.block_height <= db_addr.last_block).\ - order_by(DbCacheTransaction.block_height, DbCacheTransaction.order_n).all() + order_by(DbCacheTransaction.block_height, DbCacheTransaction.index).all() db_txs2 = [] for d in db_txs: db_txs2.append(d) @@ -806,7 +806,7 @@ def gettransactions(self, address, after_txid='', limit=MAX_TRANSACTIONS): else: db_txs = self.session.query(DbCacheTransaction).join(DbCacheTransactionNode). \ filter(DbCacheTransactionNode.address == address). \ - order_by(DbCacheTransaction.block_height, DbCacheTransaction.order_n).all() + order_by(DbCacheTransaction.block_height, DbCacheTransaction.index).all() for db_tx in db_txs: t = self._parse_db_transaction(db_tx) if t: @@ -836,8 +836,8 @@ def getblocktransactions(self, height, page, limit): n_from = (page-1) * limit n_to = page * limit db_txs = self.session.query(DbCacheTransaction).\ - filter(DbCacheTransaction.block_height == height, DbCacheTransaction.order_n >= n_from, - DbCacheTransaction.order_n < n_to).all() + filter(DbCacheTransaction.block_height == height, DbCacheTransaction.index >= n_from, + DbCacheTransaction.index < n_to).all() txs = [] for db_tx in db_txs: t = self._parse_db_transaction(db_tx) @@ -881,7 +881,7 @@ def getutxos(self, address, after_txid=''): DbCacheTransactionNode.value, DbCacheTransaction.confirmations, DbCacheTransaction.block_height, DbCacheTransaction.fee, DbCacheTransaction.date, DbCacheTransaction.txid).join(DbCacheTransaction). \ - order_by(DbCacheTransaction.block_height, DbCacheTransaction.order_n). \ + order_by(DbCacheTransaction.block_height, DbCacheTransaction.index). \ filter(DbCacheTransactionNode.address == address, DbCacheTransactionNode.is_input == False, DbCacheTransaction.network_name == self.network.name).all() utxos = [] @@ -991,14 +991,14 @@ def store_blockcount(self, blockcount): self.session.merge(dbvar) self.commit() - def store_transaction(self, t, order_n=None, commit=True): + def store_transaction(self, t, index=None, commit=True): """ Store transaction in cache. Use order number to determine order in a block :param t: Transaction :type t: Transaction - :param order_n: Order in block - :type order_n: int + :param index: Order in block + :type index: int :param commit: Commit transaction to database. Default is True. Can be disabled if a larger number of transactions are added to cache, so you can commit outside this method. :type commit: bool @@ -1023,7 +1023,7 @@ def store_transaction(self, t, order_n=None, commit=True): return new_tx = DbCacheTransaction(txid=txid, date=t.date, confirmations=t.confirmations, block_height=t.block_height, network_name=t.network.name, - fee=t.fee, order_n=order_n, version=t.version_int, + fee=t.fee, index=index, version=t.version_int, locktime=t.locktime, witness_type=t.witness_type) self.session.add(new_tx) for i in t.inputs: diff --git a/bitcoinlib/transactions.py b/bitcoinlib/transactions.py index a4b703e6..02fdf274 100644 --- a/bitcoinlib/transactions.py +++ b/bitcoinlib/transactions.py @@ -890,7 +890,7 @@ def parse(cls, rawtx, strict=True, network=DEFAULT_NETWORK): return cls.parse_bytesio(rawtx, strict, network) @classmethod - def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK): + def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK, index=None): """ Parse a raw transaction and create a Transaction object @@ -997,7 +997,7 @@ def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK): raw_bytes = rawtx.read(raw_len) return Transaction(inputs, outputs, locktime, version, network, size=raw_len, output_total=output_total, - coinbase=coinbase, flag=flag, witness_type=witness_type, rawtx=raw_bytes) + coinbase=coinbase, flag=flag, witness_type=witness_type, rawtx=raw_bytes, index=index) @classmethod def parse_hex(cls, rawtx, strict=True, network=DEFAULT_NETWORK): @@ -1066,7 +1066,7 @@ def __init__(self, inputs=None, outputs=None, locktime=0, version=None, network=DEFAULT_NETWORK, fee=None, fee_per_kb=None, size=None, txid='', txhash='', date=None, confirmations=None, block_height=None, block_hash=None, input_total=0, output_total=0, rawtx=b'', status='new', coinbase=False, verified=False, witness_type='segwit', flag=None, replace_by_fee=False, - order_n=None): + index=None): """ Create a new transaction class with provided inputs and outputs. @@ -1119,8 +1119,8 @@ def __init__(self, inputs=None, outputs=None, locktime=0, version=None, :type witness_type: str :param flag: Transaction flag to indicate version, for example for SegWit :type flag: bytes, str - :param order_n: Order of transaction in block. Used when parsing blocks - :type order_n: int + :param index: Index of transaction in block. Used when parsing blocks + :type index: int """ @@ -1181,7 +1181,7 @@ def __init__(self, inputs=None, outputs=None, locktime=0, version=None, self.witness_type = witness_type self.replace_by_fee = replace_by_fee self.change = 0 - self.order_n = order_n + self.index = index self.calc_weight_units() if self.witness_type not in ['legacy', 'segwit']: raise TransactionError("Please specify a valid witness type: legacy or segwit") diff --git a/tests/benchmark.py b/tests/benchmark.py deleted file mode 100644 index c59ca846..00000000 --- a/tests/benchmark.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -# -# BitcoinLib - Python Cryptocurrency Library -# Benchmark - test library speed -# © 2020 October - 1200 Web Development -# - - -import time -import random -from bitcoinlib.keys import * -from bitcoinlib.wallets import * -from bitcoinlib.transactions import * -from bitcoinlib.mnemonic import * - -try: - wallet_method = Wallet -except NameError: - wallet_method = HDWallet - -try: - BITCOINLIB_VERSION -except: - BITCOINLIB_VERSION = '<0.4.10' - - -class Benchmark: - - def __init__(self): - wallet_delete_if_exists('wallet_multisig_huge', force=True) - - @staticmethod - def benchmark_bip38(): - # Encrypt and decrypt BIP38 key - k = Key() - bip38_key = k.encrypt(password='satoshi') - k2 = Key(bip38_key, password='satoshi') - assert(k.wif() == k2.wif()) - - @staticmethod - def benchmark_encoding(): - # Convert very large numbers to and from base58 / bech32 - pk = random.randint(0, 10 ** 10240) - large_b58 = change_base(pk, 10, 58, 6000) - large_b32 = change_base(pk, 10, 32, 7000) - assert(change_base(large_b58, 58, 10) == pk) - assert(change_base(large_b32, 32, 10) == pk) - - @staticmethod - def benchmark_mnemonic(): - # Generate Mnemonic passphrases - for i in range(100): - m = Mnemonic().generate(256) - Mnemonic().to_entropy(m) - - @staticmethod - def benchmark_transactions(): - # Deserialize transaction and verify - raw_hex = "02000000000101b7006080d9d1d2928f70be1140d4af199d6ba4f9a7b0096b6461d7d4d16a96470600000000fdffffff11205c0600000000001976a91416e7a7d921edff13eaf5831eefd6aaca5728d7fb88acad960700000000001600140dd69a4ce74f03342cd46748fc40a877c7ccef0e808b08000000000017a914bd27a59ba92179389515ecea6b87824a42e002ee873efb0b0000000000160014b4a3a8da611b66123c19408c289faa04c71818d178b21100000000001976a914496609abfa498b6edbbf83e93fd45c1934e05b9888ac34d01900000000001976a9144d1ce518b35e19f413963172bd2c84bd90f8f23488ace06e1f00000000001976a914440d99e9e2879c1b0f8e9a1d5a288a4b6cfcc15288acff762c000000000016001401429b4b17e97f8d4419b4594ffe9f54e85037e7241e4500000000001976a9146083df8eb862f759ea0f1c04d3f13a3dfa9aff5888acf09056000000000017a9144fcaf4edac9da6890c09a819d0d7b8f300edbe478740fa97000000000017a9147431dcb6061217b0c80c6fa0c0256c1221d74b4a87208e9c000000000017a914a3e1e764fefa92fc5befa179b2b80afd5a9c20bd87ecf09f000000000017a9142ca7dc95f76530521a1edfc439586866997a14828754900101000000001976a9142e6c1941e2f9c47b535d0cf5dc4be5038e02336588acc0996d01000000001976a91492268fb9d7b8a3c825a4efc486a0679dbf006fae88acd790ae0300000000160014fe350625e2887e9bc984a69a7a4f60439e7ee7152182c81300000000160014f60834ef165253c571b11ce9fa74e46692fc5ec10248304502210081cb31e1b53a36409743e7c785e00d5df7505ca2373a1e652fec91f00c15746b02203167d7cc1fa43e16d411c620b90d9516cddac31d9e44e452651f50c950dc94150121026e5628506ecd33242e5ceb5fdafe4d3066b5c0f159b3c05a621ef65f177ea28600000000" - for i in range(100): - t = Transaction.import_raw(raw_hex) - t.inputs[0].value = 485636658 - t.verify() - assert(t.verified is True) - - @staticmethod - def benchmark_wallets_multisig(): - # Create large multisig wallet - network = 'bitcoinlib_test' - n_keys = 8 - sigs_req = 5 - key_list = [HDKey(network=network) for _ in range(0, n_keys)] - pk_n = random.randint(0, n_keys - 1) - key_list_cosigners = [k.public_master(multisig=True) for k in key_list if k is not key_list[pk_n]] - key_list_wallet = [key_list[pk_n]] + key_list_cosigners - w = wallet_method.create('wallet_multisig_huge', keys=key_list_wallet, sigs_required=sigs_req, network=network) - w.get_keys(number_of_keys=2) - w.utxos_update() - to_address = HDKey(network=network).address() - t = w.sweep(to_address, offline=True) - key_pool = [i for i in range(0, n_keys - 1) if i != pk_n] - while len(t.inputs[0].signatures) < sigs_req: - co_id = random.choice(key_pool) - t.sign(key_list[co_id]) - key_pool.remove(co_id) - assert(t.verify() is True) - - def run(self): - start_time = time.time() - print("Running BitcoinLib benchmarks speed test for version %s" % BITCOINLIB_VERSION) - - benchmark_methods = [m for m in dir(self) if callable(getattr(self, m)) if m.startswith('benchmark_')] - for method in benchmark_methods: - m_start_time = time.time() - getattr(self, method)() - m_duration = time.time() - m_start_time - print("%s, %.5f seconds" % (method, m_duration)) - - duration = time.time() - start_time - print("Total running time: %.5f seconds" % duration) - - -if __name__ == '__main__': - Benchmark().run() diff --git a/tests/test_blocks.py b/tests/test_blocks.py index 92d5bad3..e107cf9c 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -150,6 +150,7 @@ def test_blocks_parse_block_and_transactions_2(self): self.assertEqual(b.tx_count, 81) self.assertEqual(b.transactions[0].txid, 'dfd63430f8d14f6545117d74b20da63efd4a75c7e28f723b3dead431b88469ee') self.assertEqual(b.transactions[4].txid, '717bc8b42f12baf771b6719c2e3b2742925fe3912917c716abef03e35fe49020') + self.assertEqual(b.transactions[4].index, 4) self.assertEqual(len(b.transactions), 5) b.parse_transactions(70) self.assertEqual(len(b.transactions), 75) diff --git a/tests/test_keys.py b/tests/test_keys.py index 529f7ad2..e5efb0a8 100644 --- a/tests/test_keys.py +++ b/tests/test_keys.py @@ -566,7 +566,7 @@ def test_encrypt_private_key(self): return for v in self.vectors["valid"]: k = Key(v['wif']) - print("Check %s + %s = %s " % (v['wif'], v['passphrase'], v['bip38'])) + # print("Check %s + %s = %s " % (v['wif'], v['passphrase'], v['bip38'])) self.assertEqual(str(v['bip38']), k.encrypt(str(v['passphrase']))) def test_decrypt_bip38_key(self): @@ -574,14 +574,14 @@ def test_decrypt_bip38_key(self): return for v in self.vectors["valid"]: k = Key(v['bip38'], password=str(v['passphrase'])) - print("Check %s - %s = %s " % (v['bip38'], v['passphrase'], v['wif'])) + # print("Check %s - %s = %s " % (v['bip38'], v['passphrase'], v['wif'])) self.assertEqual(str(v['wif']), k.wif()) def test_bip38_invalid_keys(self): if not USING_MODULE_SCRYPT: return for v in self.vectors["invalid"]["verify"]: - print("Checking invalid key %s" % v['base58']) + # print("Checking invalid key %s" % v['base58']) self.assertRaisesRegex(Exception, "", Key, str(v['base58'])) def test_bip38_other_networks(self): @@ -622,8 +622,8 @@ def test_hdkey_derive_from_public_and_private_index(self): for i in range(BULKTESTCOUNT): pub_with_pubparent = self.K.child_public(i).address() pub_with_privparent = self.k.child_private(i).address() - if pub_with_privparent != pub_with_pubparent: - print("Error index %4d: pub-child %s, priv-child %s" % (i, pub_with_privparent, pub_with_pubparent)) + # if pub_with_privparent != pub_with_pubparent: + # print("Error index %4d: pub-child %s, priv-child %s" % (i, pub_with_privparent, pub_with_pubparent)) self.assertEqual(pub_with_pubparent, pub_with_privparent) def test_hdkey_derive_from_public_and_private_random(self): @@ -635,9 +635,9 @@ def test_hdkey_derive_from_public_and_private_random(self): pubk = HDKey(k.wif_public()) pub_with_pubparent = pubk.child_public().address() pub_with_privparent = k.child_private().address() - if pub_with_privparent != pub_with_pubparent: - print("Error random key: %4d: pub-child %s, priv-child %s" % - (i, pub_with_privparent, pub_with_pubparent)) + # if pub_with_privparent != pub_with_pubparent: + # print("Error random key: %4d: pub-child %s, priv-child %s" % + # (i, pub_with_privparent, pub_with_pubparent)) self.assertEqual(pub_with_pubparent, pub_with_privparent) diff --git a/tests/test_services.py b/tests/test_services.py index 47f3b5a2..b6a23817 100644 --- a/tests/test_services.py +++ b/tests/test_services.py @@ -111,7 +111,7 @@ def test_service_sendrawtransaction(self): except ServiceError: pass for provider in srv.errors: - print("Provider %s" % provider) + # print("Provider %s" % provider) prov_error = str(srv.errors[provider]) if isinstance(srv.errors[provider], Exception) or 'response [429]' in prov_error \ or 'response [503]' in prov_error: @@ -128,7 +128,7 @@ def test_service_get_balance(self): if len(srv.results) < 2: self.fail("Only 1 or less service providers found, nothing to compare. Errors %s" % srv.errors) for provider in srv.results: - print("Provider %s" % provider) + # print("Provider %s" % provider) balance = srv.results[provider] if prev is not None and balance != prev: self.fail("Different address balance from service providers: %d != %d" % (balance, prev)) @@ -142,7 +142,7 @@ def test_service_get_balance_litecoin(self): if len(srv.results) < 2: self.skipTest("Only 1 or less service providers found, nothing to compare. Errors %s" % srv.errors) for provider in srv.results: - print("Provider %s" % provider) + # print("Provider %s" % provider) balance = srv.results[provider] if prev is not None and balance != prev: self.fail("Different address balance from service providers: %d != %d" % (balance, prev)) @@ -166,7 +166,7 @@ def test_service_get_utxos(self): srv = ServiceTest(min_providers=3) srv.getutxos('1Mxww5Q2AK3GxG4R2KyCEao6NJXyoYgyAx') for provider in srv.results: - print("Provider %s" % provider) + # print("Provider %s" % provider) self.assertDictEqualExt(srv.results[provider][0], expected_dict, ['date', 'block_height']) def test_service_get_utxos_after_txid(self): @@ -175,7 +175,7 @@ def test_service_get_utxos_after_txid(self): srv.getutxos('1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1', after_txid='9293869acee7d90661ee224135576b45b4b0dbf2b61e4ce30669f1099fecac0c') for provider in srv.results: - print("Testing provider %s" % provider) + # print("Testing provider %s" % provider) self.assertEqual(srv.results[provider][0]['txid'], txid) def test_service_get_utxos_litecoin(self): @@ -183,7 +183,7 @@ def test_service_get_utxos_litecoin(self): srv.getutxos('Lct7CEpiN7e72rUXmYucuhqnCy5F5Vc6Vg') txid = '832518d58e9678bcdb9fe0e417a138daeb880c3a2ee1fb1659f1179efc383c25' for provider in srv.results: - print("Provider %s" % provider) + # print("Provider %s" % provider) self.assertEqual(srv.results[provider][0]['txid'], txid) def test_service_get_utxos_litecoin_after_txid(self): @@ -192,7 +192,7 @@ def test_service_get_utxos_litecoin_after_txid(self): srv.getutxos('Lfx4mFjhRvqyRKxXKqn6jyb17D6NDmosEV', after_txid='b328a91dd15b8b82fef5b01738aaf1f486223d34ee54357e1430c22e46ddd04e') for provider in srv.results: - print("Comparing provider %s" % provider) + # print("Comparing provider %s" % provider) self.assertEqual(srv.results[provider][0]['txid'], txid) def test_service_estimatefee(self): @@ -206,7 +206,7 @@ def test_service_estimatefee(self): # Normalize with dust amount, to avoid errors on small differences dust = Network().dust_amount for provider in srv.results: - print("Provider %s" % provider) + # print("Provider %s" % provider) if srv.results[provider] < average_fee and average_fee - srv.results[provider] > dust: srv.results[provider] += dust elif srv.results[provider] > average_fee and srv.results[provider] - average_fee > dust: @@ -264,7 +264,7 @@ def test_service_gettransactions(self): srv = ServiceTest(min_providers=3) srv.gettransactions(address) for provider in srv.results: - print("Testing: %s" % provider) + # print("Testing: %s" % provider) res = srv.results[provider] t = [r for r in res if r.txid == txid][0] @@ -419,7 +419,7 @@ def test_service_gettransaction(self): srv.gettransaction('2ae77540ec3ef7b5001de90194ed0ade7522239fe0fc57c12c772d67274e2700') for provider in srv.results: - print("Comparing provider %s" % provider) + # print("Comparing provider %s" % provider) self.assertTrue(srv.results[provider].verify()) self.assertDictEqualExt(srv.results[provider].as_dict(), expected_dict, ['block_hash', 'block_height', 'spent', 'value']) @@ -444,7 +444,7 @@ def test_service_gettransactions_litecoin(self): srv = ServiceTest(min_providers=3, network='litecoin') srv.gettransactions(address) for provider in srv.results: - print("Provider %s" % provider) + # print("Provider %s" % provider) res = srv.results[provider] txs = [r for r in res if r.txid == txid] t = txs[0] @@ -571,7 +571,7 @@ def test_service_gettransaction_segwit_p2wpkh(self): srv.gettransaction('299dab85f10c37c6296d4fb10eaa323fb456a5e7ada9adf41389c447daa9c0e4') for provider in srv.results: - print("\nComparing provider %s" % provider) + # print("\nComparing provider %s" % provider) self.assertDictEqualExt(srv.results[provider].as_dict(), expected_dict, ['block_hash', 'block_height', 'spent', 'value', 'flag']) @@ -675,7 +675,7 @@ def test_service_getblock_id(self): def test_service_getblock_height(self): srv = ServiceTest(timeout=TIMEOUT_TEST, cache_uri='') b = srv.getblock(599999, parse_transactions=True, limit=3) - print("Test getblock using provider %s" % list(srv.results.keys())[0]) + # print("Test getblock using provider %s" % list(srv.results.keys())[0]) self.assertEqual(b.height, 599999) self.assertEqual(to_hexstring(b.block_hash), '00000000000000000003ecd827f336c6971f6f77a0b9fba362398dd867975645') self.assertEqual(to_hexstring(b.merkle_root), 'ca13ce7f21619f73fb5a062696ec06a4427c6ad9e523e7bc1cf5287c137ddcea') @@ -701,7 +701,7 @@ def test_service_getblock_height(self): def test_service_getblock_parse_tx_paging(self): srv = ServiceTest(timeout=TIMEOUT_TEST, cache_uri='') b = srv.getblock(120000, parse_transactions=True, limit=25, page=2) - print("Test getblock using provider %s" % list(srv.results.keys())[0]) + # print("Test getblock using provider %s" % list(srv.results.keys())[0]) self.assertEqual(to_hexstring(b.block_hash), '0000000000000e07595fca57b37fea8522e95e0f6891779cfd34d7e537524471') self.assertEqual(b.height, 120000) @@ -720,7 +720,7 @@ def test_service_getblock_parse_tx_paging_last_page(self): def test_service_getblock_litecoin(self): srv = ServiceTest(timeout=TIMEOUT_TEST, network='litecoin', cache_uri='') b = srv.getblock(1000000, parse_transactions=True, limit=2) - print("Test getblock using provider %s" % list(srv.results.keys())[0]) + # print("Test getblock using provider %s" % list(srv.results.keys())[0]) self.assertEqual(b.height, 1000000) self.assertEqual(to_hexstring(b.block_hash), '8ceae698f0a2d338e39b213eb9c253a91a270ca6451a4d9bba7bf2c9e637dfda') self.assertEqual(to_hexstring(b.merkle_root), @@ -971,7 +971,7 @@ def check_block_128594(b): for cache_db in DATABASES_CACHE: srv = ServiceTest(cache_uri=cache_db, exclude_providers=['blockchair', 'bitcoind']) b = srv.getblock('0000000000001a7dcac3c01bf10c5d5fe53dc8cc4b9c94001662e9d7bd36f6cc', limit=1) - print("Test getblock with hash using provider %s" % list(srv.results.keys())[0]) + # print("Test getblock with hash using provider %s" % list(srv.results.keys())[0]) check_block_128594(b) self.assertEqual(srv.results_cache_n, 0) @@ -996,3 +996,11 @@ def test_service_cache_transaction_p2sh_p2wpkh_input(self): t2 = srv.gettransaction(txid) self.assertEqual(t2.size, 249) self.assertEqual(srv.results_cache_n, 1) + + def test_service_cache_transaction_index(self): + srv = ServiceTest(cache_uri=DATABASE_CACHE_UNITTESTS2) + srv.getblock(104444, parse_transactions=True) + t = srv.gettransaction('d7795eb181ef87a35298e8689cabf852e831824ded4c23b1a7f711df119a6599') + if not srv.results_cache_n: + self.skipTest('Transaction not indexed for selected provider') + self.assertEqual(t.index, 5) \ No newline at end of file diff --git a/tests/test_transactions.py b/tests/test_transactions.py index 063e0f99..9aabe40c 100644 --- a/tests/test_transactions.py +++ b/tests/test_transactions.py @@ -1723,7 +1723,6 @@ def test_transactions_segwit_p2sh_p2wpkh(self): '64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6') t.sign([pk1], 0) self.assertTrue(t.verify()) - print(t.raw_hex()) t2 = Transaction.parse(t.raw()) t2.inputs[0].value = int(10 * 100000000) self.assertEqual(t2.signature_hash(0).hex(), @@ -1768,7 +1767,6 @@ def test_transaction_segwit_p2sh_p2wsh(self): t = Transaction(inputs, outputs, witness_type='segwit') t.sign(key2) self.assertTrue(t.verify()) - print(t.raw_hex()) self.assertEqual(t.signature_hash(0).hex(), '1926c08d8c0f54498382e97704e7b2d8b4181ffa524b4c0d8a43aba61e3fc656') self.assertEqual(t.txid, txid)