diff options
Diffstat (limited to 'qa/rpc-tests')
-rwxr-xr-x | qa/rpc-tests/bip68-112-113-p2p.py | 1 | ||||
-rwxr-xr-x | qa/rpc-tests/fundrawtransaction.py | 19 | ||||
-rwxr-xr-x | qa/rpc-tests/import-rescan.py | 155 | ||||
-rwxr-xr-x | qa/rpc-tests/maxuploadtarget.py | 39 | ||||
-rwxr-xr-x | qa/rpc-tests/mempool_limit.py | 6 | ||||
-rwxr-xr-x | qa/rpc-tests/mempool_packages.py | 4 | ||||
-rwxr-xr-x | qa/rpc-tests/mempool_reorg.py | 2 | ||||
-rwxr-xr-x | qa/rpc-tests/p2p-compactblocks.py | 52 | ||||
-rwxr-xr-x | qa/rpc-tests/prioritise_transaction.py | 2 | ||||
-rwxr-xr-x | qa/rpc-tests/pruning.py | 50 | ||||
-rwxr-xr-x | qa/rpc-tests/replace-by-fee.py | 2 | ||||
-rwxr-xr-x | qa/rpc-tests/segwit.py | 19 | ||||
-rwxr-xr-x | qa/rpc-tests/smartfees.py | 6 | ||||
-rwxr-xr-x | qa/rpc-tests/test_framework/test_framework.py | 11 | ||||
-rw-r--r-- | qa/rpc-tests/test_framework/util.py | 24 |
15 files changed, 295 insertions, 97 deletions
diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index 55b3e2a04a..fc3efb1abf 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -289,6 +289,7 @@ class BIP68_112_113Test(ComparisonTestFramework): # BIP113 test transaction will be modified before each use to put in appropriate block time bip113tx_v1 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98")) bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE + bip113tx_v1.nVersion = 1 bip113tx_v2 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98")) bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE bip113tx_v2.nVersion = 2 diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 8c45578fcf..82e148c55a 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -484,6 +484,23 @@ class RawTransactionsTest(BitcoinTestFramework): self.is_network_split=False self.sync_all() + # drain the keypool + self.nodes[1].getnewaddress() + inputs = [] + outputs = {self.nodes[0].getnewaddress():1.1} + rawTx = self.nodes[1].createrawtransaction(inputs, outputs) + # fund a transaction that requires a new key for the change output + # creating the key must be impossible because the wallet is locked + try: + fundedTx = self.nodes[1].fundrawtransaction(rawTx) + raise AssertionError("Wallet unlocked without passphrase") + except JSONRPCException as e: + assert('Keypool ran out' in e.error['message']) + + #refill the keypool + self.nodes[1].walletpassphrase("test", 100) + self.nodes[1].walletlock() + try: self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) raise AssertionError("Wallet unlocked without passphrase") @@ -498,7 +515,7 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[1].fundrawtransaction(rawTx) #now we need to unlock - self.nodes[1].walletpassphrase("test", 100) + self.nodes[1].walletpassphrase("test", 600) signedTx = self.nodes[1].signrawtransaction(fundedTx['hex']) txId = self.nodes[1].sendrawtransaction(signedTx['hex']) self.nodes[1].generate(1) diff --git a/qa/rpc-tests/import-rescan.py b/qa/rpc-tests/import-rescan.py new file mode 100755 index 0000000000..e683df26db --- /dev/null +++ b/qa/rpc-tests/import-rescan.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import (start_nodes, connect_nodes, sync_blocks, assert_equal) +from decimal import Decimal + +import collections +import enum +import itertools +import functools + +Call = enum.Enum("Call", "single multi") +Data = enum.Enum("Data", "address pub priv") +ImportNode = collections.namedtuple("ImportNode", "rescan") + + +def call_import_rpc(call, data, address, scriptPubKey, pubkey, key, label, node, rescan): + """Helper that calls a wallet import RPC on a bitcoin node.""" + watchonly = data != Data.priv + if call == Call.single: + if data == Data.address: + response = node.importaddress(address, label, rescan) + elif data == Data.pub: + response = node.importpubkey(pubkey, label, rescan) + elif data == Data.priv: + response = node.importprivkey(key, label, rescan) + assert_equal(response, None) + elif call == Call.multi: + response = node.importmulti([{ + "scriptPubKey": { + "address": address + }, + "pubkeys": [pubkey] if data == Data.pub else [], + "keys": [key] if data == Data.priv else [], + "label": label, + "watchonly": watchonly + }], {"rescan": rescan}) + assert_equal(response, [{"success": True}]) + return watchonly + + +# List of RPCs that import a wallet key or address in various ways. +IMPORT_RPCS = [functools.partial(call_import_rpc, call, data) for call, data in itertools.product(Call, Data)] + +# List of bitcoind nodes that will import keys. +IMPORT_NODES = [ + ImportNode(rescan=True), + ImportNode(rescan=False), +] + + +class ImportRescanTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + len(IMPORT_NODES) + + def setup_network(self): + extra_args = [["-debug=1"] for _ in range(self.num_nodes)] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + for i in range(1, self.num_nodes): + connect_nodes(self.nodes[i], 0) + + def run_test(self): + # Create one transaction on node 0 with a unique amount and label for + # each possible type of wallet import RPC. + import_rpc_variants = [] + for i, import_rpc in enumerate(IMPORT_RPCS): + label = "label{}".format(i) + addr = self.nodes[0].validateaddress(self.nodes[0].getnewaddress(label)) + key = self.nodes[0].dumpprivkey(addr["address"]) + amount = 24.9375 - i * .0625 + txid = self.nodes[0].sendtoaddress(addr["address"], amount) + import_rpc = functools.partial(import_rpc, addr["address"], addr["scriptPubKey"], addr["pubkey"], key, + label) + import_rpc_variants.append((import_rpc, label, amount, txid, addr)) + + self.nodes[0].generate(1) + assert_equal(self.nodes[0].getrawmempool(), []) + sync_blocks(self.nodes) + + # For each importing node and variation of wallet import RPC, invoke + # the RPC and check the results from getbalance and listtransactions. + for node, import_node in zip(self.nodes[1:], IMPORT_NODES): + for import_rpc, label, amount, txid, addr in import_rpc_variants: + watchonly = import_rpc(node, import_node.rescan) + + balance = node.getbalance(label, 0, True) + if import_node.rescan: + assert_equal(balance, amount) + else: + assert_equal(balance, 0) + + txs = node.listtransactions(label, 10000, 0, True) + if import_node.rescan: + assert_equal(len(txs), 1) + assert_equal(txs[0]["account"], label) + assert_equal(txs[0]["address"], addr["address"]) + assert_equal(txs[0]["amount"], amount) + assert_equal(txs[0]["category"], "receive") + assert_equal(txs[0]["label"], label) + assert_equal(txs[0]["txid"], txid) + assert_equal(txs[0]["confirmations"], 1) + assert_equal("trusted" not in txs[0], True) + if watchonly: + assert_equal(txs[0]["involvesWatchonly"], True) + else: + assert_equal("involvesWatchonly" not in txs[0], True) + else: + assert_equal(len(txs), 0) + + # Create spends for all the imported addresses. + spend_txids = [] + fee = self.nodes[0].getnetworkinfo()["relayfee"] + for import_rpc, label, amount, txid, addr in import_rpc_variants: + raw_tx = self.nodes[0].getrawtransaction(txid) + decoded_tx = self.nodes[0].decoderawtransaction(raw_tx) + input_vout = next(out["n"] for out in decoded_tx["vout"] + if out["scriptPubKey"]["addresses"] == [addr["address"]]) + inputs = [{"txid": txid, "vout": input_vout}] + outputs = {self.nodes[0].getnewaddress(): Decimal(amount) - fee} + raw_spend_tx = self.nodes[0].createrawtransaction(inputs, outputs) + signed_spend_tx = self.nodes[0].signrawtransaction(raw_spend_tx) + spend_txid = self.nodes[0].sendrawtransaction(signed_spend_tx["hex"]) + spend_txids.append(spend_txid) + + self.nodes[0].generate(1) + assert_equal(self.nodes[0].getrawmempool(), []) + sync_blocks(self.nodes) + + # Check the results from getbalance and listtransactions after the spends. + for node, import_node in zip(self.nodes[1:], IMPORT_NODES): + txs = node.listtransactions("*", 10000, 0, True) + for (import_rpc, label, amount, txid, addr), spend_txid in zip(import_rpc_variants, spend_txids): + balance = node.getbalance(label, 0, True) + spend_tx = [tx for tx in txs if tx["txid"] == spend_txid] + if import_node.rescan: + assert_equal(balance, amount) + assert_equal(len(spend_tx), 1) + assert_equal(spend_tx[0]["account"], "") + assert_equal(spend_tx[0]["amount"] + spend_tx[0]["fee"], -amount) + assert_equal(spend_tx[0]["category"], "send") + assert_equal("label" not in spend_tx[0], True) + assert_equal(spend_tx[0]["confirmations"], 1) + assert_equal("trusted" not in spend_tx[0], True) + assert_equal("involvesWatchonly" not in txs[0], True) + else: + assert_equal(balance, 0) + assert_equal(spend_tx, []) + + +if __name__ == "__main__": + ImportRescanTest().main() diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index d0e9fe9a3f..9340e899eb 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -81,49 +81,19 @@ class TestNode(NodeConnCB): class MaxUploadTest(BitcoinTestFramework): - def add_options(self, parser): - parser.add_option("--testbinary", dest="testbinary", - default=os.getenv("BITCOIND", "bitcoind"), - help="bitcoind binary to test") - def __init__(self): super().__init__() self.setup_clean_chain = True self.num_nodes = 1 - self.utxo = [] - self.txouts = gen_return_txouts() + # Cache for utxos, as the listunspent may take a long time later in the test + self.utxo_cache = [] def setup_network(self): # Start a node with maxuploadtarget of 200 MB (/24h) self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-maxuploadtarget=800", "-blockmaxsize=999000"])) - def mine_full_block(self, node, address): - # Want to create a full block - # We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit - for j in range(14): - if len(self.utxo) < 14: - self.utxo = node.listunspent() - inputs=[] - outputs = {} - t = self.utxo.pop() - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) - remchange = t["amount"] - Decimal("0.001000") - outputs[address]=remchange - # Create a basic transaction that will send change back to ourself after account for a fee - # And then insert the 128 generated transaction outs in the middle rawtx[92] is where the # - # of txouts is stored and is the only thing we overwrite from the original transaction - rawtx = node.createrawtransaction(inputs, outputs) - newtx = rawtx[0:92] - newtx = newtx + self.txouts - newtx = newtx + rawtx[94:] - # Appears to be ever so slightly faster to sign with SIGHASH_NONE - signresult = node.signrawtransaction(newtx,None,None,"NONE") - txid = node.sendrawtransaction(signresult["hex"], True) - # Mine a full sized block which will be these transactions we just created - node.generate(1) - def run_test(self): # Before we connect anything, we first set the time on the node # to be in the past, otherwise things break because the CNode @@ -151,7 +121,7 @@ class MaxUploadTest(BitcoinTestFramework): # Test logic begins here # Now mine a big block - self.mine_full_block(self.nodes[0], self.nodes[0].getnewaddress()) + mine_large_block(self.nodes[0], self.utxo_cache) # Store the hash; we'll request this later big_old_block = self.nodes[0].getbestblockhash() @@ -162,11 +132,10 @@ class MaxUploadTest(BitcoinTestFramework): self.nodes[0].setmocktime(int(time.time()) - 2*60*60*24) # Mine one more block, so that the prior block looks old - self.mine_full_block(self.nodes[0], self.nodes[0].getnewaddress()) + mine_large_block(self.nodes[0], self.utxo_cache) # We'll be requesting this new block too big_new_block = self.nodes[0].getbestblockhash() - new_block_size = self.nodes[0].getblock(big_new_block)['size'] big_new_block = int(big_new_block, 16) # test_nodes[0] will test what happens if we just keep requesting the diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index 4438c152df..154ae59c26 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -26,7 +26,7 @@ class MempoolLimitTest(BitcoinTestFramework): def run_test(self): txids = [] - utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90) + utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 91) #create a mempool tx that will be evicted us0 = utxos.pop() @@ -41,9 +41,9 @@ class MempoolLimitTest(BitcoinTestFramework): relayfee = self.nodes[0].getnetworkinfo()['relayfee'] base_fee = relayfee*100 - for i in range (4): + for i in range (3): txids.append([]) - txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], 30, (i+1)*base_fee) # by now, the tx should be evicted, check confirmation state assert(txid not in self.nodes[0].getrawmempool()) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 45dc0e65c4..f605e7524f 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -20,8 +20,8 @@ class MempoolPackagesTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-relaypriority=0", "-debug"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-maxorphantx=1000", "-relaypriority=0", "-limitancestorcount=5", "-debug"])) + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-maxorphantx=1000", "-limitancestorcount=5", "-debug"])) connect_nodes(self.nodes[0], 1) self.is_network_split = False self.sync_all() diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index 301b094eb0..dd88aae4f2 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -55,7 +55,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # Create a block-height-locked transaction which will be invalid after reorg timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 49.99}) # Set the time lock - timelock_tx = timelock_tx.replace("ffffffff", "11111111", 1) + timelock_tx = timelock_tx.replace("ffffffff", "11111191", 1) timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"] assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index ab4b809ded..fc1f16c6d2 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -764,6 +764,54 @@ class CompactBlocksTest(BitcoinTestFramework): msg.announce = True peer.send_and_ping(msg) + def test_compactblock_reconstruction_multiple_peers(self, node, stalling_peer, delivery_peer): + assert(len(self.utxos)) + + def announce_cmpct_block(node, peer): + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(node, utxo, 5) + + cmpct_block = HeaderAndShortIDs() + cmpct_block.initialize_from_block(block) + msg = msg_cmpctblock(cmpct_block.to_p2p()) + peer.send_and_ping(msg) + with mininode_lock: + assert(peer.last_getblocktxn is not None) + return block, cmpct_block + + block, cmpct_block = announce_cmpct_block(node, stalling_peer) + + for tx in block.vtx[1:]: + delivery_peer.send_message(msg_tx(tx)) + delivery_peer.sync_with_ping() + mempool = node.getrawmempool() + for tx in block.vtx[1:]: + assert(tx.hash in mempool) + + delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + + # Now test that delivering an invalid compact block won't break relay + + block, cmpct_block = announce_cmpct_block(node, stalling_peer) + for tx in block.vtx[1:]: + delivery_peer.send_message(msg_tx(tx)) + delivery_peer.sync_with_ping() + + cmpct_block.prefilled_txn[0].tx.wit.vtxinwit = [ CTxInWitness() ] + cmpct_block.prefilled_txn[0].tx.wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)] + + cmpct_block.use_witness = True + delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) + assert(int(node.getbestblockhash(), 16) != block.sha256) + + msg = msg_blocktxn() + msg.block_transactions.blockhash = block.sha256 + msg.block_transactions.transactions = block.vtx[1:] + stalling_peer.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) def run_test(self): # Setup the p2p connections and start up the network thread. @@ -848,6 +896,10 @@ class CompactBlocksTest(BitcoinTestFramework): self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, False) self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, False) + print("\tTesting reconstructing compact blocks from all peers...") + self.test_compactblock_reconstruction_multiple_peers(self.nodes[1], self.segwit_node, self.old_node) + sync_blocks(self.nodes) + # Advance to segwit activation print ("\nAdvancing to segwit activation\n") self.activate_segwit(self.nodes[1]) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index 85afeab2e3..b7459c80cb 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -39,7 +39,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): txids.append([]) start_range = i * range_size end_range = start_range + range_size - txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], (i+1)*base_fee) + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], end_range - start_range, (i+1)*base_fee) # Make sure that the size of each group of transactions exceeds # MAX_BLOCK_BASE_SIZE -- otherwise the test needs to be revised to create diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 287dbc776e..78b8938e4a 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -13,6 +13,9 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +import time +import os + def calc_usage(blockdir): return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.) @@ -24,9 +27,9 @@ class PruneTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 - self.utxo = [] - self.address = ["",""] - self.txouts = gen_return_txouts() + # Cache for utxos, as the listunspent may take a long time later in the test + self.utxo_cache_0 = [] + self.utxo_cache_1 = [] def setup_network(self): self.nodes = [] @@ -40,12 +43,6 @@ class PruneTest(BitcoinTestFramework): self.nodes.append(start_node(2, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-prune=550"], timewait=900)) self.prunedir = self.options.tmpdir+"/node2/regtest/blocks/" - self.address[0] = self.nodes[0].getnewaddress() - self.address[1] = self.nodes[1].getnewaddress() - - # Determine default relay fee - self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] - connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[1], 2) connect_nodes(self.nodes[2], 0) @@ -58,7 +55,7 @@ class PruneTest(BitcoinTestFramework): self.nodes[0].generate(150) # Then mine enough full blocks to create more than 550MiB of data for i in range(645): - self.mine_full_block(self.nodes[0], self.address[0]) + mine_large_block(self.nodes[0], self.utxo_cache_0) sync_blocks(self.nodes[0:3]) @@ -70,7 +67,7 @@ class PruneTest(BitcoinTestFramework): print("Mining 25 more blocks should cause the first block file to be pruned") # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this for i in range(25): - self.mine_full_block(self.nodes[0],self.address[0]) + mine_large_block(self.nodes[0], self.utxo_cache_0) waitstart = time.time() while os.path.isfile(self.prunedir+"blk00000.dat"): @@ -95,17 +92,15 @@ class PruneTest(BitcoinTestFramework): stop_node(self.nodes[0],0) self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900) # Mine 24 blocks in node 1 - self.utxo = self.nodes[1].listunspent() for i in range(24): if j == 0: - self.mine_full_block(self.nodes[1],self.address[1]) + mine_large_block(self.nodes[1], self.utxo_cache_1) else: self.nodes[1].generate(1) #tx's already in mempool from previous disconnects # Reorg back with 25 block chain from node 0 - self.utxo = self.nodes[0].listunspent() for i in range(25): - self.mine_full_block(self.nodes[0],self.address[0]) + mine_large_block(self.nodes[0], self.utxo_cache_0) # Create connections in the order so both nodes can see the reorg at the same time connect_nodes(self.nodes[1], 0) @@ -217,31 +212,6 @@ class PruneTest(BitcoinTestFramework): # Verify we can now have the data for a block previously pruned assert(self.nodes[2].getblock(self.forkhash)["height"] == self.forkheight) - def mine_full_block(self, node, address): - # Want to create a full block - # We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit - for j in range(14): - if len(self.utxo) < 14: - self.utxo = node.listunspent() - inputs=[] - outputs = {} - t = self.utxo.pop() - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) - remchange = t["amount"] - 100*self.relayfee # Fee must be above min relay rate for 66kb tx - outputs[address]=remchange - # Create a basic transaction that will send change back to ourself after account for a fee - # And then insert the 128 generated transaction outs in the middle rawtx[92] is where the # - # of txouts is stored and is the only thing we overwrite from the original transaction - rawtx = node.createrawtransaction(inputs, outputs) - newtx = rawtx[0:92] - newtx = newtx + self.txouts - newtx = newtx + rawtx[94:] - # Appears to be ever so slightly faster to sign with SIGHASH_NONE - signresult = node.signrawtransaction(newtx,None,None,"NONE") - txid = node.sendrawtransaction(signresult["hex"], True) - # Mine a full sized block which will be these transactions we just created - node.generate(1) - def run_test(self): print("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)") diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index 34c0f9d795..8aba06c60c 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -76,7 +76,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug", - "-relaypriority=0", "-whitelist=127.0.0.1", + "-whitelist=127.0.0.1", "-limitancestorcount=50", "-limitancestorsize=101", "-limitdescendantcount=200", diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index 41a1b3b20f..be6fae5088 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -13,6 +13,7 @@ from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COut from test_framework.address import script_to_p2sh, key_to_p2pkh from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG from io import BytesIO +from test_framework.mininode import FromHex NODE_0 = 0 NODE_1 = 1 @@ -84,8 +85,8 @@ class SegWitTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) + self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness", "-rpcserialversion=0"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1"])) self.nodes.append(start_node(2, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) connect_nodes(self.nodes[1], 0) connect_nodes(self.nodes[2], 1) @@ -211,7 +212,19 @@ class SegWitTest(BitcoinTestFramework): block = self.nodes[2].generate(1) #block 432 (first block with new rules; 432 = 144 * 3) sync_blocks(self.nodes) assert_equal(len(self.nodes[2].getrawmempool()), 0) - assert_equal(len(self.nodes[2].getblock(block[0])["tx"]), 5) + segwit_tx_list = self.nodes[2].getblock(block[0])["tx"] + assert_equal(len(segwit_tx_list), 5) + + print("Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag") + assert(self.nodes[2].getblock(block[0], False) != self.nodes[0].getblock(block[0], False)) + assert(self.nodes[1].getblock(block[0], False) == self.nodes[2].getblock(block[0], False)) + for i in range(len(segwit_tx_list)): + tx = FromHex(CTransaction(), self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[2].getrawtransaction(segwit_tx_list[i]) != self.nodes[0].getrawtransaction(segwit_tx_list[i])) + assert(self.nodes[1].getrawtransaction(segwit_tx_list[i], 0) == self.nodes[2].getrawtransaction(segwit_tx_list[i])) + assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) != self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[1].getrawtransaction(segwit_tx_list[i]) == self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) == bytes_to_hex_str(tx.serialize_without_witness())) print("Verify witness txs without witness data are invalid after the fork") self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False) diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 74a74f679a..2c56f954a2 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -159,7 +159,7 @@ class EstimateFeeTest(BitcoinTestFramework): self.nodes = [] # Use node0 to mine blocks for input splitting self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", - "-relaypriority=0", "-whitelist=127.0.0.1"])) + "-whitelist=127.0.0.1"])) print("This test is time consuming, please be patient") print("Splitting inputs to small size so we can generate low priority tx's") @@ -197,12 +197,12 @@ class EstimateFeeTest(BitcoinTestFramework): # (17k is room enough for 110 or so transactions) self.nodes.append(start_node(1, self.options.tmpdir, ["-blockprioritysize=1500", "-blockmaxsize=17000", - "-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"])) + "-maxorphantx=1000", "-debug=estimatefee"])) connect_nodes(self.nodes[1], 0) # Node2 is a stingy miner, that # produces too small blocks (room for only 55 or so transactions) - node2args = ["-blockprioritysize=0", "-blockmaxsize=8000", "-maxorphantx=1000", "-relaypriority=0"] + node2args = ["-blockprioritysize=0", "-blockmaxsize=8000", "-maxorphantx=1000"] self.nodes.append(start_node(2, self.options.tmpdir, node2args)) connect_nodes(self.nodes[0], 2) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index e6d3e9ab9a..98c4f6070b 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -172,7 +172,16 @@ class BitcoinTestFramework(object): os.rmdir(self.options.root) else: print("Not cleaning up dir %s" % self.options.tmpdir) - + if os.getenv("PYTHON_DEBUG", ""): + # Dump the end of the debug logs, to aid in debugging rare + # travis failures. + import glob + filenames = glob.glob(self.options.tmpdir + "/node*/regtest/debug.log") + MAX_LINES_TO_PRINT = 1000 + for f in filenames: + print("From" , f, ":") + from collections import deque + print("".join(deque(open(f), MAX_LINES_TO_PRINT))) if success: print("Tests successful") sys.exit(0) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 99c30f7651..85898d9f32 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -654,16 +654,15 @@ def create_tx(node, coinbase, to_address, amount): # Create a spend of each passed-in utxo, splicing in "txouts" to each raw # transaction to make it large. See gen_return_txouts() above. -def create_lots_of_big_transactions(node, txouts, utxos, fee): +def create_lots_of_big_transactions(node, txouts, utxos, num, fee): addr = node.getnewaddress() txids = [] - for i in range(len(utxos)): + for _ in range(num): t = utxos.pop() - inputs = [] - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + inputs=[{ "txid" : t["txid"], "vout" : t["vout"]}] outputs = {} - send_value = t['amount'] - fee - outputs[addr] = satoshi_round(send_value) + change = t['amount'] - fee + outputs[addr] = satoshi_round(change) rawtx = node.createrawtransaction(inputs, outputs) newtx = rawtx[0:92] newtx = newtx + txouts @@ -673,6 +672,19 @@ def create_lots_of_big_transactions(node, txouts, utxos, fee): txids.append(txid) return txids +def mine_large_block(node, utxos=None): + # generate a 66k transaction, + # and 14 of them is close to the 1MB block limit + num = 14 + txouts = gen_return_txouts() + utxos = utxos if utxos is not None else [] + if len(utxos) < num: + utxos.clear() + utxos.extend(node.listunspent()) + fee = 100 * node.getnetworkinfo()["relayfee"] + create_lots_of_big_transactions(node, txouts, utxos, num, fee=fee) + node.generate(1) + def get_bip9_status(node, key): info = node.getblockchaininfo() return info['bip9_softforks'][key] |