diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -8,7 +8,9 @@ from test_framework.util import * import urllib.parse + class AbandonConflictTest(BitcoinTestFramework): + def __init__(self): super().__init__() self.num_nodes = 2 @@ -16,54 +18,66 @@ def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-logtimemicros"])) + self.nodes.append( + start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros", "-minrelaytxfee=0.00001"])) + self.nodes.append( + start_node(1, self.options.tmpdir, ["-debug", "-logtimemicros"])) connect_nodes(self.nodes[0], 1) def run_test(self): self.nodes[1].generate(100) sync_blocks(self.nodes) balance = self.nodes[0].getbalance() - txA = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) - txB = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) - txC = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + txA = self.nodes[0].sendtoaddress( + self.nodes[0].getnewaddress(), Decimal("10")) + txB = self.nodes[0].sendtoaddress( + self.nodes[0].getnewaddress(), Decimal("10")) + txC = self.nodes[0].sendtoaddress( + self.nodes[0].getnewaddress(), Decimal("10")) sync_mempools(self.nodes) self.nodes[1].generate(1) sync_blocks(self.nodes) newbalance = self.nodes[0].getbalance() - assert(balance - newbalance < Decimal("0.001")) #no more than fees lost + assert(balance - newbalance < Decimal("0.001")) + # no more than fees lost balance = newbalance url = urllib.parse.urlparse(self.nodes[1].url) - self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) + self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) # Identify the 10btc outputs - nA = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txA, 1)["vout"]) if vout["value"] == Decimal("10")) - nB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txB, 1)["vout"]) if vout["value"] == Decimal("10")) - nC = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txC, 1)["vout"]) if vout["value"] == Decimal("10")) + nA = next(i for i, vout in enumerate( + self.nodes[0].getrawtransaction(txA, 1)["vout"]) if vout["value"] == Decimal("10")) + nB = next(i for i, vout in enumerate( + self.nodes[0].getrawtransaction(txB, 1)["vout"]) if vout["value"] == Decimal("10")) + nC = next(i for i, vout in enumerate( + self.nodes[0].getrawtransaction(txC, 1)["vout"]) if vout["value"] == Decimal("10")) - inputs =[] + inputs = [] # spend 10btc outputs from txA and txB - inputs.append({"txid":txA, "vout":nA}) - inputs.append({"txid":txB, "vout":nB}) + inputs.append({"txid": txA, "vout": nA}) + inputs.append({"txid": txB, "vout": nB}) outputs = {} outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998") outputs[self.nodes[1].getnewaddress()] = Decimal("5") - signed = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs), None, None, "ALL") + signed = self.nodes[0].signrawtransaction( + self.nodes[0].createrawtransaction(inputs, outputs), None, None, "ALL") txAB1 = self.nodes[0].sendrawtransaction(signed["hex"]) # Identify the 14.99998btc output - nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998")) + nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction( + txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998")) - #Create a child tx spending AB1 and C + # Create a child tx spending AB1 and C inputs = [] - inputs.append({"txid":txAB1, "vout":nAB}) - inputs.append({"txid":txC, "vout":nC}) + inputs.append({"txid": txAB1, "vout": nAB}) + inputs.append({"txid": txC, "vout": nC}) outputs = {} outputs[self.nodes[0].getnewaddress()] = Decimal("24.9996") - signed2 = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs), None, None, "ALL") + signed2 = self.nodes[0].signrawtransaction( + self.nodes[0].createrawtransaction(inputs, outputs), None, None, "ALL") txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"]) # In mempool txs from self should increase balance from change @@ -74,8 +88,9 @@ # Restart the node with a higher min relay fee so the parent tx is no longer in mempool # TODO: redo with eviction # Note had to make sure tx did not have AllowFree priority - stop_node(self.nodes[0],0) - self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, [ + "-debug", "-logtimemicros", "-minrelaytxfee=0.0001"]) # Verify txs no longer in mempool assert_equal(len(self.nodes[0].getrawmempool()), 0) @@ -86,10 +101,12 @@ assert_equal(newbalance, balance - Decimal("24.9996")) # Unconfirmed received funds that are not in mempool, also shouldn't show # up in unconfirmed balance - unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance() + unconfbalance = self.nodes[ + 0].getunconfirmedbalance() + self.nodes[0].getbalance() assert_equal(unconfbalance, newbalance) # Also shouldn't show up in listunspent - assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)]) + assert(not txABC2 in [utxo["txid"] + for utxo in self.nodes[0].listunspent(0)]) balance = newbalance # Abandon original transaction and verify inputs are available again @@ -99,9 +116,11 @@ assert_equal(newbalance, balance + Decimal("30")) balance = newbalance - # Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned - stop_node(self.nodes[0],0) - self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"]) + # Verify that even with a low min relay fee, the tx is not reaccepted + # from wallet on startup once abandoned + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, [ + "-debug", "-logtimemicros", "-minrelaytxfee=0.00001"]) assert_equal(len(self.nodes[0].getrawmempool()), 0) assert_equal(self.nodes[0].getbalance(), balance) @@ -116,12 +135,14 @@ # Send child tx again so its unabandoned self.nodes[0].sendrawtransaction(signed2["hex"]) newbalance = self.nodes[0].getbalance() - assert_equal(newbalance, balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("10") + - Decimal("14.99998") + Decimal("24.9996")) balance = newbalance # Remove using high relay fee again - stop_node(self.nodes[0],0) - self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, [ + "-debug", "-logtimemicros", "-minrelaytxfee=0.0001"]) assert_equal(len(self.nodes[0].getrawmempool()), 0) newbalance = self.nodes[0].getbalance() assert_equal(newbalance, balance - Decimal("24.9996")) @@ -129,8 +150,8 @@ # Create a double spend of AB1 by spending again from only A's 10 output # Mine double spend from node 1 - inputs =[] - inputs.append({"txid":txA, "vout":nA}) + inputs = [] + inputs.append({"txid": txA, "vout": nA}) outputs = {} outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999") tx = self.nodes[0].createrawtransaction(inputs, outputs) @@ -141,7 +162,8 @@ connect_nodes(self.nodes[0], 1) sync_blocks(self.nodes) - # Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted + # Verify that B and C's 10 BTC outputs are available for spending again + # because AB1 is now conflicted newbalance = self.nodes[0].getbalance() assert_equal(newbalance, balance + Decimal("20")) balance = newbalance @@ -151,9 +173,11 @@ # Don't think C's should either self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) newbalance = self.nodes[0].getbalance() - #assert_equal(newbalance, balance - Decimal("10")) - print("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer") - print("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315") + # assert_equal(newbalance, balance - Decimal("10")) + print( + "If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer") + print( + "conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315") print(str(balance) + " -> " + str(newbalance) + " ?") if __name__ == '__main__': diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -12,6 +12,7 @@ from io import BytesIO import time + def cltv_invalidate(tx): '''Modify the signature in vin 0 of the tx to fail CLTV @@ -33,6 +34,8 @@ Mine 1 new version block. Mine 1 old version block, see that the node rejects. ''' + + class BIP65Test(ComparisonTestFramework): def __init__(self): @@ -42,19 +45,20 @@ def setup_network(self): # Must set the blockversion for this test self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, - extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=3']], + extra_args=[ + ['-debug', '-whitelist=127.0.0.1', '-blockversion=3']], binary=[self.options.testbinary]) def run_test(self): test = TestManager(self, self.options.tmpdir) test.add_all_connections(self.nodes) - NetworkThread().start() # Start up network handling in another thread + NetworkThread().start() # Start up network handling in another thread test.run() def create_transaction(self, node, coinbase, to_address, amount): from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } + inputs = [{"txid": from_txid, "vout": 0}] + outputs = {to_address: amount} rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx, None, None, "ALL") tx = CTransaction() @@ -73,7 +77,8 @@ ''' 398 more version 3 blocks ''' test_blocks = [] for i in range(398): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() @@ -86,7 +91,8 @@ ''' Mine 749 version 4 blocks ''' test_blocks = [] for i in range(749): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.rehash() block.solve() @@ -101,11 +107,12 @@ version 3 block. ''' spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) + self.coinbase_blocks[0], self.nodeaddress, 1.0) cltv_invalidate(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -120,7 +127,8 @@ ''' Mine 199 new version blocks on last valid tip ''' test_blocks = [] for i in range(199): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.rehash() block.solve() @@ -131,7 +139,8 @@ yield TestInstance(test_blocks, sync_every_block=False) ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() @@ -141,7 +150,8 @@ yield TestInstance([[block, True]]) ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.rehash() block.solve() @@ -155,11 +165,12 @@ block. ''' spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) + self.coinbase_blocks[1], self.nodeaddress, 1.0) cltv_invalidate(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -169,7 +180,8 @@ yield TestInstance([[block, False]]) ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -13,15 +13,17 @@ from test_framework.mininode import * from test_framework.blocktools import * -SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) -SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height) -SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift +SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31) +SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22) # this means use time (0 means height) +SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift SEQUENCE_LOCKTIME_MASK = 0x0000ffff # RPC error for non-BIP68 final transactions NOT_FINAL_ERROR = "64: non-BIP68-final" + class BIP68Test(BitcoinTestFramework): + def __init__(self): super().__init__() self.num_nodes = 2 @@ -29,8 +31,10 @@ def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"])) + self.nodes.append( + start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"])) + self.nodes.append( + start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"])) self.is_network_split = False self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] connect_nodes(self.nodes[0], 1) @@ -67,7 +71,7 @@ def test_disable_flag(self): # Create some unconfirmed inputs new_addr = self.nodes[0].getnewaddress() - self.nodes[0].sendtoaddress(new_addr, 2) # send 2 BTC + self.nodes[0].sendtoaddress(new_addr, 2) # send 2 BTC utxos = self.nodes[0].listunspent(0, 0) assert(len(utxos) > 0) @@ -75,16 +79,18 @@ utxo = utxos[0] tx1 = CTransaction() - value = int(satoshi_round(utxo["amount"] - self.relayfee)*COIN) + value = int(satoshi_round(utxo["amount"] - self.relayfee) * COIN) # Check that the disable flag disables relative locktime. # If sequence locks were used, this would require 1 block for the # input to mature. sequence_value = SEQUENCE_LOCKTIME_DISABLE_FLAG | 1 - tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)] + tx1.vin = [ + CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)] tx1.vout = [CTxOut(value, CScript([b'a']))] - tx1_signed = self.nodes[0].signrawtransaction(ToHex(tx1), None, None, "ALL")["hex"] + tx1_signed = self.nodes[0].signrawtransaction( + ToHex(tx1), None, None, "ALL")["hex"] tx1_id = self.nodes[0].sendrawtransaction(tx1_signed) tx1_id = int(tx1_id, 16) @@ -94,7 +100,7 @@ tx2.nVersion = 2 sequence_value = sequence_value & 0x7fffffff tx2.vin = [CTxIn(COutPoint(tx1_id, 0), nSequence=sequence_value)] - tx2.vout = [CTxOut(int(value-self.relayfee*COIN), CScript([b'a']))] + tx2.vout = [CTxOut(int(value - self.relayfee * COIN), CScript([b'a']))] tx2.rehash() try: @@ -113,10 +119,12 @@ # Calculate the median time past of a prior block ("confirmations" before # the current tip). def get_median_time_past(self, confirmations): - block_hash = self.nodes[0].getblockhash(self.nodes[0].getblockcount()-confirmations) + block_hash = self.nodes[0].getblockhash( + self.nodes[0].getblockcount() - confirmations) return self.nodes[0].getblockheader(block_hash)["mediantime"] - # Test that sequence locks are respected for transactions spending confirmed inputs. + # Test that sequence locks are respected for transactions spending + # confirmed inputs. def test_sequence_lock_confirmed_inputs(self): # Create lots of confirmed utxos, and use them to generate lots of random # transactions. @@ -130,7 +138,7 @@ num_outputs = random.randint(1, max_outputs) outputs = {} for i in range(num_outputs): - outputs[addresses[i]] = random.randint(1, 20)*0.01 + outputs[addresses[i]] = random.randint(1, 20) * 0.01 self.nodes[0].sendmany("", outputs) self.nodes[0].generate(1) @@ -148,7 +156,7 @@ # Track whether any sequence locks used should fail should_pass = True - + # Track whether this transaction was built with sequence locks using_sequence_locks = False @@ -156,14 +164,14 @@ tx.nVersion = 2 value = 0 for j in range(num_inputs): - sequence_value = 0xfffffffe # this disables sequence locks + sequence_value = 0xfffffffe # this disables sequence locks # 50% chance we enable sequence locks - if random.randint(0,1): + if random.randint(0, 1): using_sequence_locks = True # 10% of the time, make the input sequence value pass - input_will_pass = (random.randint(1,10) == 1) + input_will_pass = (random.randint(1, 10) == 1) sequence_value = utxos[j]["confirmations"] if not input_will_pass: sequence_value += 1 @@ -172,30 +180,41 @@ # Figure out what the median-time-past was for the confirmed input # Note that if an input has N confirmations, we're going back N blocks # from the tip so that we're looking up MTP of the block - # PRIOR to the one the input appears in, as per the BIP68 spec. - orig_time = self.get_median_time_past(utxos[j]["confirmations"]) - cur_time = self.get_median_time_past(0) # MTP of the tip - - # can only timelock this input if it's not too old -- otherwise use height + # PRIOR to the one the input appears in, as per the BIP68 + # spec. + orig_time = self.get_median_time_past( + utxos[j]["confirmations"]) + cur_time = self.get_median_time_past(0) # MTP of the tip + + # can only timelock this input if it's not too old -- + # otherwise use height can_time_lock = True if ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) >= SEQUENCE_LOCKTIME_MASK: can_time_lock = False - # if time-lockable, then 50% chance we make this a time lock - if random.randint(0,1) and can_time_lock: - # Find first time-lock value that fails, or latest one that succeeds + # if time-lockable, then 50% chance we make this a time + # lock + if random.randint(0, 1) and can_time_lock: + # Find first time-lock value that fails, or latest one + # that succeeds time_delta = sequence_value << SEQUENCE_LOCKTIME_GRANULARITY if input_will_pass and time_delta > cur_time - orig_time: - sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) + sequence_value = ( + (cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) elif (not input_will_pass and time_delta <= cur_time - orig_time): - sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY)+1 + sequence_value = ( + (cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) + 1 sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG - tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value)) - value += utxos[j]["amount"]*COIN - # Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output - tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50 - tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a']))) - rawtx = self.nodes[0].signrawtransaction(ToHex(tx), None, None, "ALL")["hex"] + tx.vin.append( + CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value)) + value += utxos[j]["amount"] * COIN + # Overestimate the size of the tx - signatures should be less than + # 120 bytes, and leave 50 for the output + tx_size = len(ToHex(tx)) // 2 + 120 * num_inputs + 50 + tx.vout.append( + CTxOut(int(value - self.relayfee * tx_size * COIN / 1000), CScript([b'a']))) + rawtx = self.nodes[0].signrawtransaction( + ToHex(tx), None, None, "ALL")["hex"] try: self.nodes[0].sendrawtransaction(rawtx) @@ -225,8 +244,10 @@ tx2 = CTransaction() tx2.nVersion = 2 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] - tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] - tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2), None, None, "ALL")["hex"] + tx2.vout = [ + CTxOut(int(tx1.vout[0].nValue - self.relayfee * COIN), CScript([b'a']))] + tx2_raw = self.nodes[0].signrawtransaction( + ToHex(tx2), None, None, "ALL")["hex"] tx2 = FromHex(tx2, tx2_raw) tx2.rehash() @@ -242,8 +263,10 @@ tx = CTransaction() tx.nVersion = 2 - tx.vin = [CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)] - tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee*COIN), CScript([b'a']))] + tx.vin = [ + CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)] + tx.vout = [ + CTxOut(int(orig_tx.vout[0].nValue - relayfee * COIN), CScript([b'a']))] tx.rehash() try: @@ -256,12 +279,15 @@ assert(orig_tx.hash not in node.getrawmempool()) return tx - test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True) - test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False) + test_nonzero_locks( + tx2, self.nodes[0], self.relayfee, use_height_lock=True) + test_nonzero_locks( + tx2, self.nodes[0], self.relayfee, use_height_lock=False) # Now mine some blocks, but make sure tx2 doesn't get mined. # Use prioritisetransaction to lower the effective feerate to 0 - self.nodes[0].prioritisetransaction(tx2.hash, -1e15, int(-self.relayfee*COIN)) + self.nodes[0].prioritisetransaction( + tx2.hash, -1e15, int(-self.relayfee * COIN)) cur_time = int(time.time()) for i in range(10): self.nodes[0].setmocktime(cur_time + 600) @@ -270,37 +296,45 @@ assert(tx2.hash in self.nodes[0].getrawmempool()) - test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True) - test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False) + test_nonzero_locks( + tx2, self.nodes[0], self.relayfee, use_height_lock=True) + test_nonzero_locks( + tx2, self.nodes[0], self.relayfee, use_height_lock=False) # Mine tx2, and then try again - self.nodes[0].prioritisetransaction(tx2.hash, 1e15, int(self.relayfee*COIN)) + self.nodes[0].prioritisetransaction( + tx2.hash, 1e15, int(self.relayfee * COIN)) # Advance the time on the node so that we can test timelocks - self.nodes[0].setmocktime(cur_time+600) + self.nodes[0].setmocktime(cur_time + 600) self.nodes[0].generate(1) assert(tx2.hash not in self.nodes[0].getrawmempool()) # Now that tx2 is not in the mempool, a sequence locked spend should # succeed - tx3 = test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False) + tx3 = test_nonzero_locks( + tx2, self.nodes[0], self.relayfee, use_height_lock=False) assert(tx3.hash in self.nodes[0].getrawmempool()) self.nodes[0].generate(1) assert(tx3.hash not in self.nodes[0].getrawmempool()) # One more test, this time using height locks - tx4 = test_nonzero_locks(tx3, self.nodes[0], self.relayfee, use_height_lock=True) + tx4 = test_nonzero_locks( + tx3, self.nodes[0], self.relayfee, use_height_lock=True) assert(tx4.hash in self.nodes[0].getrawmempool()) # Now try combining confirmed and unconfirmed inputs - tx5 = test_nonzero_locks(tx4, self.nodes[0], self.relayfee, use_height_lock=True) + tx5 = test_nonzero_locks( + tx4, self.nodes[0], self.relayfee, use_height_lock=True) assert(tx5.hash not in self.nodes[0].getrawmempool()) utxos = self.nodes[0].listunspent() - tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1)) - tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN) - raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5), None, None, "ALL")["hex"] + tx5.vin.append( + CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1)) + tx5.vout[0].nValue += int(utxos[0]["amount"] * COIN) + raw_tx5 = self.nodes[0].signrawtransaction( + ToHex(tx5), None, None, "ALL")["hex"] try: self.nodes[0].sendrawtransaction(raw_tx5) @@ -326,7 +360,8 @@ # diagram above). # This would cause tx2 to be added back to the mempool, which in turn causes # tx3 to be removed. - tip = int(self.nodes[0].getblockhash(self.nodes[0].getblockcount()-1), 16) + tip = int(self.nodes[0].getblockhash( + self.nodes[0].getblockcount() - 1), 16) height = self.nodes[0].getblockcount() for i in range(2): block = create_block(tip, create_coinbase(height), cur_time) @@ -344,7 +379,8 @@ # Reset the chain and get rid of the mocktimed-blocks self.nodes[0].setmocktime(0) - self.nodes[0].invalidateblock(self.nodes[0].getblockhash(cur_height+1)) + self.nodes[0].invalidateblock( + self.nodes[0].getblockhash(cur_height + 1)) self.nodes[0].generate(10) # Make sure that BIP68 isn't being used to validate blocks, prior to @@ -362,22 +398,25 @@ tx2 = CTransaction() tx2.nVersion = 1 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] - tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] + tx2.vout = [ + CTxOut(int(tx1.vout[0].nValue - self.relayfee * COIN), CScript([b'a']))] # sign tx2 - tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2), None, None, "ALL")["hex"] + tx2_raw = self.nodes[0].signrawtransaction( + ToHex(tx2), None, None, "ALL")["hex"] tx2 = FromHex(tx2, tx2_raw) tx2.rehash() self.nodes[0].sendrawtransaction(ToHex(tx2)) - + # Now make an invalid spend of tx2 according to BIP68 - sequence_value = 100 # 100 block relative locktime + sequence_value = 100 # 100 block relative locktime tx3 = CTransaction() tx3.nVersion = 2 tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), nSequence=sequence_value)] - tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] + tx3.vout = [ + CTxOut(int(tx2.vout[0].nValue - self.relayfee * COIN), CScript([b'a']))] tx3.rehash() try: @@ -389,7 +428,8 @@ # make a block that violates bip68; ensure that the tip updates tip = int(self.nodes[0].getbestblockhash(), 16) - block = create_block(tip, create_coinbase(self.nodes[0].getblockcount()+1)) + block = create_block( + tip, create_coinbase(self.nodes[0].getblockcount() + 1)) block.nVersion = 3 block.vtx.extend([tx1, tx2, tx3]) block.hashMerkleRoot = block.calc_merkle_root() @@ -404,19 +444,20 @@ min_activation_height = 432 height = self.nodes[0].getblockcount() assert(height < 432) - self.nodes[0].generate(432-height) + self.nodes[0].generate(432 - height) assert(get_bip9_status(self.nodes[0], 'csv')['status'] == 'active') sync_blocks(self.nodes) # Use self.nodes[1] to test standardness relay policy def test_version2_relay(self, before_activation): - inputs = [ ] - outputs = { self.nodes[1].getnewaddress() : 1.0 } + inputs = [] + outputs = {self.nodes[1].getnewaddress(): 1.0} rawtx = self.nodes[1].createrawtransaction(inputs, outputs) rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex'] tx = FromHex(CTransaction(), rawtxfund) tx.nVersion = 2 - tx_signed = self.nodes[1].signrawtransaction(ToHex(tx), None, None, "ALL")["hex"] + tx_signed = self.nodes[1].signrawtransaction( + ToHex(tx), None, None, "ALL")["hex"] try: tx_id = self.nodes[1].sendrawtransaction(tx_signed) assert(before_activation == False) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -37,19 +37,20 @@ def setup_network(self): self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, - extra_args=[['-debug', '-whitelist=127.0.0.1']], + extra_args=[ + ['-debug', '-whitelist=127.0.0.1']], binary=[self.options.testbinary]) def run_test(self): self.test = TestManager(self, self.options.tmpdir) self.test.add_all_connections(self.nodes) - NetworkThread().start() # Start up network handling in another thread + NetworkThread().start() # Start up network handling in another thread self.test.run() def create_transaction(self, node, coinbase, to_address, amount): from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } + inputs = [{"txid": from_txid, "vout": 0}] + outputs = {to_address: amount} rawtx = node.createrawtransaction(inputs, outputs) tx = CTransaction() f = BytesIO(hex_str_to_bytes(rawtx)) @@ -58,15 +59,17 @@ return tx def sign_transaction(self, node, tx): - signresult = node.signrawtransaction(bytes_to_hex_str(tx.serialize()), None, None, "ALL") + signresult = node.signrawtransaction( + bytes_to_hex_str(tx.serialize()), None, None, "ALL") tx = CTransaction() f = BytesIO(hex_str_to_bytes(signresult['hex'])) tx.deserialize(f) return tx - def generate_blocks(self, number, version, test_blocks = []): + def generate_blocks(self, number, version, test_blocks=[]): for i in range(number): - block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = version block.rehash() block.solve() @@ -115,10 +118,14 @@ # Test 2 # Fail to achieve LOCKED_IN 100 out of 144 signal bit 1 # using a variety of bits to simulate multiple parallel softforks - test_blocks = self.generate_blocks(50, activated_version) # 0x20000001 (signalling ready) - test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not) - test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready) - test_blocks = self.generate_blocks(24, 4, test_blocks) # 0x20010000 (signalling not) + test_blocks = self.generate_blocks( + 50, activated_version) # 0x20000001 (signalling ready) + test_blocks = self.generate_blocks( + 20, 4, test_blocks) # 0x00000004 (signalling not) + test_blocks = self.generate_blocks( + 50, activated_version, test_blocks) # 0x20000101 (signalling ready) + test_blocks = self.generate_blocks( + 24, 4, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') @@ -132,10 +139,14 @@ # Test 3 # 108 out of 144 signal bit 1 to achieve LOCKED_IN # using a variety of bits to simulate multiple parallel softforks - test_blocks = self.generate_blocks(58, activated_version) # 0x20000001 (signalling ready) - test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not) - test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready) - test_blocks = self.generate_blocks(10, 4, test_blocks) # 0x20010000 (signalling not) + test_blocks = self.generate_blocks( + 58, activated_version) # 0x20000001 (signalling ready) + test_blocks = self.generate_blocks( + 26, 4, test_blocks) # 0x00000004 (signalling not) + test_blocks = self.generate_blocks( + 50, activated_version, test_blocks) # 0x20000101 (signalling ready) + test_blocks = self.generate_blocks( + 10, 4, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') @@ -156,13 +167,14 @@ # Test 5 # Check that the new rule is enforced spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) + self.coinbase_blocks[0], self.nodeaddress, 1.0) invalidate(spendtx) spendtx = self.sign_transaction(self.nodes[0], spendtx) spendtx.rehash() invalidatePostSignature(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = activated_version block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -185,14 +197,15 @@ # Test 6 # Check that the new sequence lock rules are enforced spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) + self.coinbase_blocks[1], self.nodeaddress, 1.0) invalidate(spendtx) spendtx = self.sign_transaction(self.nodes[0], spendtx) spendtx.rehash() invalidatePostSignature(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = 5 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -210,14 +223,16 @@ self.test.block_store = BlockStore(self.options.tmpdir) self.test.clear_all_connections() self.test.add_all_connections(self.nodes) - NetworkThread().start() # Start up network handling in another thread - + NetworkThread().start() # Start up network handling in another thread def get_tests(self): for test in itertools.chain( - self.test_BIP('csv', 0x20000001, self.sequence_lock_invalidate, self.donothing, 0), - self.test_BIP('csv', 0x20000001, self.mtp_invalidate, self.donothing, 0), - self.test_BIP('csv', 0x20000001, self.donothing, self.csv_invalidate, 0) + self.test_BIP( + 'csv', 0x20000001, self.sequence_lock_invalidate, self.donothing, 0), + self.test_BIP( + 'csv', 0x20000001, self.mtp_invalidate, self.donothing, 0), + self.test_BIP( + 'csv', 0x20000001, self.donothing, self.csv_invalidate, 0) ): yield test diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -12,8 +12,10 @@ from io import BytesIO import time -# A canonical signature consists of: +# A canonical signature consists of: # <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype> + + def unDERify(tx): ''' Make the signature in vin 0 of a tx non-DER-compliant, @@ -27,7 +29,7 @@ else: newscript.append(i) tx.vin[0].scriptSig = CScript(newscript) - + ''' This test is meant to exercise BIP66 (DER SIG). Connect to a single node. @@ -41,7 +43,8 @@ Mine 1 new version block. Mine 1 old version block, see that the node rejects. ''' - + + class BIP66Test(ComparisonTestFramework): def __init__(self): @@ -51,19 +54,20 @@ def setup_network(self): # Must set the blockversion for this test self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, - extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=2']], + extra_args=[ + ['-debug', '-whitelist=127.0.0.1', '-blockversion=2']], binary=[self.options.testbinary]) def run_test(self): test = TestManager(self, self.options.tmpdir) test.add_all_connections(self.nodes) - NetworkThread().start() # Start up network handling in another thread + NetworkThread().start() # Start up network handling in another thread test.run() def create_transaction(self, node, coinbase, to_address, amount): from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } + inputs = [{"txid": from_txid, "vout": 0}] + outputs = {to_address: amount} rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx, None, None, "ALL") tx = CTransaction() @@ -82,7 +86,8 @@ ''' 298 more version 2 blocks ''' test_blocks = [] for i in range(298): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() block.solve() @@ -95,7 +100,8 @@ ''' Mine 749 version 3 blocks ''' test_blocks = [] for i in range(749): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() @@ -105,16 +111,17 @@ height += 1 yield TestInstance(test_blocks, sync_every_block=False) - ''' + ''' Check that the new DERSIG rules are not enforced in the 750th version 3 block. ''' spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) + self.coinbase_blocks[0], self.nodeaddress, 1.0) unDERify(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -124,12 +131,13 @@ self.last_block_time += 1 self.tip = block.sha256 height += 1 - yield TestInstance([[block, True]]) + yield TestInstance([[block, True]]) ''' Mine 199 new version blocks on last valid tip ''' test_blocks = [] for i in range(199): - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() @@ -140,7 +148,8 @@ yield TestInstance(test_blocks, sync_every_block=False) ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() block.solve() @@ -150,7 +159,8 @@ yield TestInstance([[block, True]]) ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() @@ -159,16 +169,17 @@ height += 1 yield TestInstance([[block, True]]) - ''' + ''' Check that the new DERSIG rules are enforced in the 951st version 3 block. ''' spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) + self.coinbase_blocks[1], self.nodeaddress, 1.0) unDERify(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -178,7 +189,8 @@ yield TestInstance([[block, False]]) ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) + block = create_block( + self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() block.solve() diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -11,7 +11,8 @@ for utx in listunspent: if utx['amount'] == amount: return utx - raise AssertionError('Could not find unspent with amount={}'.format(amount)) + raise AssertionError( + 'Could not find unspent with amount={}'.format(amount)) class RawTransactionsTest(BitcoinTestFramework): @@ -24,12 +25,12 @@ def setup_network(self, split=False): self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) - connect_nodes_bi(self.nodes,0,3) + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + connect_nodes_bi(self.nodes, 0, 2) + connect_nodes_bi(self.nodes, 0, 3) - self.is_network_split=False + self.is_network_split = False self.sync_all() def run_test(self): @@ -47,7 +48,7 @@ # than a minimum sized signature. # = 2 bytes * minRelayTxFeePerByte - feeTolerance = 2 * min_relay_tx_fee/1000 + feeTolerance = 2 * min_relay_tx_fee / 1000 self.nodes[2].generate(1) self.sync_all() @@ -55,11 +56,14 @@ self.sync_all() watchonly_address = self.nodes[0].getnewaddress() - watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"] + watchonly_pubkey = self.nodes[ + 0].validateaddress(watchonly_address)["pubkey"] watchonly_amount = Decimal(200) self.nodes[3].importpubkey(watchonly_pubkey, "", True) - watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) - self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) + watchonly_txid = self.nodes[0].sendtoaddress( + watchonly_address, watchonly_amount) + self.nodes[0].sendtoaddress( + self.nodes[3].getnewaddress(), watchonly_amount / 10) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) @@ -68,57 +72,57 @@ self.nodes[0].generate(1) self.sync_all() - ############### + # # simple test # - ############### - inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 1.0 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + # + inputs = [] + outputs = {self.nodes[0].getnewaddress(): 1.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert(len(dec_tx['vin']) > 0) #test that we have enough inputs + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + assert(len(dec_tx['vin']) > 0) # test that we have enough inputs - ############################## + # # simple test with two coins # - ############################## - inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 2.2 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + # + inputs = [] + outputs = {self.nodes[0].getnewaddress(): 2.2} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert(len(dec_tx['vin']) > 0) #test if we have enough inputs + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + assert(len(dec_tx['vin']) > 0) # test if we have enough inputs - ############################## + # # simple test with two coins # - ############################## - inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 2.6 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + # + inputs = [] + outputs = {self.nodes[0].getnewaddress(): 2.6} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) assert(len(dec_tx['vin']) > 0) assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '') - - ################################ + # # simple test with two outputs # - ################################ - inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + # + inputs = [] + outputs = { + self.nodes[0].getnewaddress(): 2.6, self.nodes[1].getnewaddress(): 2.5} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) totalOut = 0 for out in dec_tx['vout']: totalOut += out['value'] @@ -126,59 +130,59 @@ assert(len(dec_tx['vin']) > 0) assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '') - - ######################################################################### + # # test a fundrawtransaction with a VIN greater than the required amount # - ######################################################################### + # utx = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] - outputs = { self.nodes[0].getnewaddress() : 1.0 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}] + outputs = {self.nodes[0].getnewaddress(): 1.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) totalOut = 0 for out in dec_tx['vout']: totalOut += out['value'] - assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee + assert_equal(fee + totalOut, utx['amount']) + # compare vin total and totalout+fee - - ##################################################################### + # # test a fundrawtransaction with which will not get a change output # - ##################################################################### + # utx = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] - outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}] + outputs = { + self.nodes[0].getnewaddress(): Decimal(5.0) - fee - feeTolerance} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) totalOut = 0 for out in dec_tx['vout']: totalOut += out['value'] assert_equal(rawtxfund['changepos'], -1) - assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee - + assert_equal(fee + totalOut, utx['amount']) + # compare vin total and totalout+fee - #################################################### + # # test a fundrawtransaction with an invalid option # - #################################################### + # utx = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] - outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}] + outputs = {self.nodes[0].getnewaddress(): Decimal(4.0)} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) try: @@ -187,74 +191,75 @@ except JSONRPCException as e: assert("Unexpected key foo" in e.error['message']) - - ############################################################ + # # test a fundrawtransaction with an invalid change address # - ############################################################ + # utx = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] - outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}] + outputs = {self.nodes[0].getnewaddress(): Decimal(4.0)} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) try: - self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': 'foobar'}) + self.nodes[2].fundrawtransaction( + rawtx, {'changeAddress': 'foobar'}) raise AssertionError("Accepted invalid bitcoin address") except JSONRPCException as e: - assert("changeAddress must be a valid bitcoin address" in e.error['message']) + assert( + "changeAddress must be a valid bitcoin address" in e.error['message']) - - ############################################################ + # # test a fundrawtransaction with a provided change address # - ############################################################ + # utx = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] - outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}] + outputs = {self.nodes[0].getnewaddress(): Decimal(4.0)} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) change = self.nodes[2].getnewaddress() try: - rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 2}) + rawtxfund = self.nodes[2].fundrawtransaction( + rawtx, {'changeAddress': change, 'changePosition': 2}) except JSONRPCException as e: assert('changePosition out of bounds' == e.error['message']) else: assert(False) - rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0}) - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + rawtxfund = self.nodes[2].fundrawtransaction( + rawtx, {'changeAddress': change, 'changePosition': 0}) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) out = dec_tx['vout'][0] assert_equal(change, out['scriptPubKey']['addresses'][0]) - - ######################################################################### + # # test a fundrawtransaction with a VIN smaller than the required amount # - ######################################################################### + # utx = get_unspent(self.nodes[2].listunspent(), 1) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] - outputs = { self.nodes[0].getnewaddress() : 1.0 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}] + outputs = {self.nodes[0].getnewaddress(): 1.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) # 4-byte version + 1-byte vin count + 36-byte prevout then script_len rawtx = rawtx[:82] + "0100" + rawtx[84:] - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex']) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) totalOut = 0 matchingOuts = 0 for i, out in enumerate(dec_tx['vout']): totalOut += out['value'] if out['scriptPubKey']['addresses'][0] in outputs: - matchingOuts+=1 + matchingOuts += 1 else: assert_equal(i, rawtxfund['changepos']) @@ -264,28 +269,28 @@ assert_equal(matchingOuts, 1) assert_equal(len(dec_tx['vout']), 2) - - ########################################### + # # test a fundrawtransaction with two VINs # - ########################################### + # utx = get_unspent(self.nodes[2].listunspent(), 1) utx2 = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] - outputs = { self.nodes[0].getnewaddress() : 6.0 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}, + {'txid': utx2['txid'], 'vout': utx2['vout']}] + outputs = {self.nodes[0].getnewaddress(): 6.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) totalOut = 0 matchingOuts = 0 for out in dec_tx['vout']: totalOut += out['value'] if out['scriptPubKey']['addresses'][0] in outputs: - matchingOuts+=1 + matchingOuts += 1 assert_equal(matchingOuts, 1) assert_equal(len(dec_tx['vout']), 2) @@ -294,43 +299,49 @@ for vinOut in dec_tx['vin']: for vinIn in inputs: if vinIn['txid'] == vinOut['txid']: - matchingIns+=1 + matchingIns += 1 - assert_equal(matchingIns, 2) #we now must see two vins identical to vins given as params + assert_equal(matchingIns, 2) + # we now must see two vins identical to vins given as + # params - ######################################################### + # # test a fundrawtransaction with two VINs and two vOUTs # - ######################################################### + # utx = get_unspent(self.nodes[2].listunspent(), 1) utx2 = get_unspent(self.nodes[2].listunspent(), 5) - inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] - outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [{'txid': utx['txid'], 'vout': utx['vout']}, + {'txid': utx2['txid'], 'vout': utx2['vout']}] + outputs = { + self.nodes[0].getnewaddress(): 6.0, self.nodes[0].getnewaddress(): 1.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) totalOut = 0 matchingOuts = 0 for out in dec_tx['vout']: totalOut += out['value'] if out['scriptPubKey']['addresses'][0] in outputs: - matchingOuts+=1 + matchingOuts += 1 assert_equal(matchingOuts, 2) assert_equal(len(dec_tx['vout']), 3) - ############################################## + # # test a fundrawtransaction with invalid vin # - ############################################## + # listunspent = self.nodes[2].listunspent() - inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin! - outputs = { self.nodes[0].getnewaddress() : 1.0} - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + inputs = [ + {'txid': "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout': 0}] + # invalid vin! + outputs = {self.nodes[0].getnewaddress(): 1.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) try: rawtxfund = self.nodes[2].fundrawtransaction(rawtx) @@ -338,41 +349,41 @@ except JSONRPCException as e: assert("Insufficient" in e.error['message']) - - ############################################################ - #compare fee of a standard pubkeyhash transaction + # + # compare fee of a standard pubkeyhash transaction inputs = [] - outputs = {self.nodes[1].getnewaddress():1.1} + outputs = {self.nodes[1].getnewaddress(): 1.1} rawTx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawTx) - #create same transaction over sendtoaddress + # create same transaction over sendtoaddress txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] - #compare fee + # compare fee feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) - ############################################################ + # - ############################################################ - #compare fee of a standard pubkeyhash transaction with multiple outputs + # + # compare fee of a standard pubkeyhash transaction with multiple + # outputs inputs = [] - outputs = {self.nodes[1].getnewaddress():1.1,self.nodes[1].getnewaddress():1.2,self.nodes[1].getnewaddress():0.1,self.nodes[1].getnewaddress():1.3,self.nodes[1].getnewaddress():0.2,self.nodes[1].getnewaddress():0.3} + outputs = {self.nodes[1].getnewaddress(): 1.1, self.nodes[1].getnewaddress(): 1.2, self.nodes[1].getnewaddress(): 0.1, self.nodes[ + 1].getnewaddress(): 1.3, self.nodes[1].getnewaddress(): 0.2, self.nodes[1].getnewaddress(): 0.3} rawTx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawTx) - #create same transaction over sendtoaddress + # create same transaction over sendtoaddress txId = self.nodes[0].sendmany("", outputs) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] - #compare fee + # compare fee feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) - ############################################################ - + # - ############################################################ - #compare fee of a 2of2 multisig p2sh transaction + # + # compare fee of a 2of2 multisig p2sh transaction # create 2of2 addr addr1 = self.nodes[1].getnewaddress() @@ -381,25 +392,25 @@ addr1Obj = self.nodes[1].validateaddress(addr1) addr2Obj = self.nodes[1].validateaddress(addr2) - mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + mSigObj = self.nodes[1].addmultisigaddress( + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) inputs = [] - outputs = {mSigObj:1.1} + outputs = {mSigObj: 1.1} rawTx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawTx) - #create same transaction over sendtoaddress + # create same transaction over sendtoaddress txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] - #compare fee + # compare fee feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) - ############################################################ - + # - ############################################################ - #compare fee of a standard pubkeyhash transaction + # + # compare fee of a standard pubkeyhash transaction # create 4of5 addr addr1 = self.nodes[1].getnewaddress() @@ -414,24 +425,24 @@ addr4Obj = self.nodes[1].validateaddress(addr4) addr5Obj = self.nodes[1].validateaddress(addr5) - mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']]) + mSigObj = self.nodes[1].addmultisigaddress( + 4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']]) inputs = [] - outputs = {mSigObj:1.1} + outputs = {mSigObj: 1.1} rawTx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawTx) - #create same transaction over sendtoaddress + # create same transaction over sendtoaddress txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] - #compare fee + # compare fee feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) - ############################################################ + # - - ############################################################ + # # spend a 2of2 multisig transaction over fundraw # create 2of2 addr @@ -441,8 +452,8 @@ addr1Obj = self.nodes[2].validateaddress(addr1) addr2Obj = self.nodes[2].validateaddress(addr2) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) - + mSigObj = self.nodes[2].addmultisigaddress( + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) # send 1.2 BTC to msig addr txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) @@ -452,20 +463,22 @@ oldBalance = self.nodes[1].getbalance() inputs = [] - outputs = {self.nodes[1].getnewaddress():1.1} + outputs = {self.nodes[1].getnewaddress(): 1.1} rawTx = self.nodes[2].createrawtransaction(inputs, outputs) fundedTx = self.nodes[2].fundrawtransaction(rawTx) - signedTx = self.nodes[2].signrawtransaction(fundedTx['hex'], None, None, "ALL") + signedTx = self.nodes[2].signrawtransaction( + fundedTx['hex'], None, None, "ALL") txId = self.nodes[2].sendrawtransaction(signedTx['hex']) self.sync_all() self.nodes[1].generate(1) self.sync_all() # make sure funds are received at node1 - assert_equal(oldBalance+Decimal('1.10000000'), self.nodes[1].getbalance()) + assert_equal( + oldBalance + Decimal('1.10000000'), self.nodes[1].getbalance()) - ############################################################ + # # locked wallet test self.nodes[1].encryptwallet("test") self.nodes.pop(1) @@ -479,17 +492,17 @@ for node in self.nodes: node.settxfee(min_relay_tx_fee) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) - connect_nodes_bi(self.nodes,0,3) - self.is_network_split=False + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + connect_nodes_bi(self.nodes, 0, 2) + connect_nodes_bi(self.nodes, 0, 3) + self.is_network_split = False self.sync_all() # drain the keypool self.nodes[1].getnewaddress() inputs = [] - outputs = {self.nodes[0].getnewaddress():1.1} + 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 @@ -499,7 +512,7 @@ except JSONRPCException as e: assert('Keypool ran out' in e.error['message']) - #refill the keypool + # refill the keypool self.nodes[1].walletpassphrase("test", 100) self.nodes[1].walletlock() @@ -512,106 +525,112 @@ oldBalance = self.nodes[0].getbalance() inputs = [] - outputs = {self.nodes[0].getnewaddress():1.1} + outputs = {self.nodes[0].getnewaddress(): 1.1} rawTx = self.nodes[1].createrawtransaction(inputs, outputs) fundedTx = self.nodes[1].fundrawtransaction(rawTx) - #now we need to unlock + # now we need to unlock self.nodes[1].walletpassphrase("test", 600) - signedTx = self.nodes[1].signrawtransaction(fundedTx['hex'], None, None, "ALL") + signedTx = self.nodes[1].signrawtransaction( + fundedTx['hex'], None, None, "ALL") txId = self.nodes[1].sendrawtransaction(signedTx['hex']) self.nodes[1].generate(1) self.sync_all() # make sure funds are received at node1 - assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance()) - + assert_equal( + oldBalance + Decimal('51.10000000'), self.nodes[0].getbalance()) - ############################################### + # # multiple (~19) inputs tx test | Compare fee # - ############################################### + # - #empty node1, send some small coins from node0 to node1 - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) + # empty node1, send some small coins from node0 to node1 + self.nodes[1].sendtoaddress( + self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) self.sync_all() self.nodes[0].generate(1) self.sync_all() - for i in range(0,20): + for i in range(0, 20): self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) self.nodes[0].generate(1) self.sync_all() - #fund a tx with ~20 small inputs + # fund a tx with ~20 small inputs inputs = [] - outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04} + outputs = { + self.nodes[0].getnewaddress(): 0.15, self.nodes[0].getnewaddress(): 0.04} rawTx = self.nodes[1].createrawtransaction(inputs, outputs) fundedTx = self.nodes[1].fundrawtransaction(rawTx) - #create same transaction over sendtoaddress + # create same transaction over sendtoaddress txId = self.nodes[1].sendmany("", outputs) signedFee = self.nodes[1].getrawmempool(True)[txId]['fee'] - #compare fee + # compare fee feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) - assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs + assert(feeDelta >= 0 and feeDelta <= feeTolerance * 19) # ~19 inputs - - ############################################# + # # multiple (~19) inputs tx test | sign/send # - ############################################# + # - #again, empty node1, send some small coins from node0 to node1 - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) + # again, empty node1, send some small coins from node0 to node1 + self.nodes[1].sendtoaddress( + self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) self.sync_all() self.nodes[0].generate(1) self.sync_all() - for i in range(0,20): + for i in range(0, 20): self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) self.nodes[0].generate(1) self.sync_all() - #fund a tx with ~20 small inputs + # fund a tx with ~20 small inputs oldBalance = self.nodes[0].getbalance() inputs = [] - outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04} + outputs = { + self.nodes[0].getnewaddress(): 0.15, self.nodes[0].getnewaddress(): 0.04} rawTx = self.nodes[1].createrawtransaction(inputs, outputs) fundedTx = self.nodes[1].fundrawtransaction(rawTx) - fundedAndSignedTx = self.nodes[1].signrawtransaction(fundedTx['hex'], None, None, "ALL") + fundedAndSignedTx = self.nodes[1].signrawtransaction( + fundedTx['hex'], None, None, "ALL") txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex']) self.sync_all() self.nodes[0].generate(1) self.sync_all() - assert_equal(oldBalance+Decimal('50.19000000'), self.nodes[0].getbalance()) #0.19+block reward + assert_equal(oldBalance + Decimal('50.19000000'), + self.nodes[0].getbalance()) # 0.19+block reward - ##################################################### + # # test fundrawtransaction with OP_RETURN and no vin # - ##################################################### + # - rawtx = "0100000000010000000000000000066a047465737400000000" - dec_tx = self.nodes[2].decoderawtransaction(rawtx) + rawtx = "0100000000010000000000000000066a047465737400000000" + dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(len(dec_tx['vin']), 0) assert_equal(len(dec_tx['vout']), 1) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) - dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - - assert_greater_than(len(dec_tx['vin']), 0) # at least one vin - assert_equal(len(dec_tx['vout']), 2) # one change output added + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + assert_greater_than(len(dec_tx['vin']), 0) # at least one vin + assert_equal(len(dec_tx['vout']), 2) # one change output added - ################################################## + # # test a fundrawtransaction using only watchonly # - ################################################## + # inputs = [] - outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2} + outputs = {self.nodes[2].getnewaddress(): watchonly_amount / 2} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) - result = self.nodes[3].fundrawtransaction(rawtx, {'includeWatching': True }) + result = self.nodes[3].fundrawtransaction( + rawtx, {'includeWatching': True}) res_dec = self.nodes[0].decoderawtransaction(result["hex"]) assert_equal(len(res_dec["vin"]), 1) assert_equal(res_dec["vin"][0]["txid"], watchonly_txid) @@ -619,54 +638,65 @@ assert("fee" in result.keys()) assert_greater_than(result["changepos"], -1) - ############################################################### + # # test fundrawtransaction using the entirety of watched funds # - ############################################################### + # inputs = [] - outputs = {self.nodes[2].getnewaddress() : watchonly_amount} + outputs = {self.nodes[2].getnewaddress(): watchonly_amount} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) # Backward compatibility test (2nd param is includeWatching) result = self.nodes[3].fundrawtransaction(rawtx, True) res_dec = self.nodes[0].decoderawtransaction(result["hex"]) assert_equal(len(res_dec["vin"]), 2) - assert(res_dec["vin"][0]["txid"] == watchonly_txid or res_dec["vin"][1]["txid"] == watchonly_txid) + assert(res_dec["vin"][0]["txid"] == watchonly_txid or res_dec[ + "vin"][1]["txid"] == watchonly_txid) assert_greater_than(result["fee"], 0) assert_greater_than(result["changepos"], -1) - assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10) + assert_equal(result["fee"] + res_dec["vout"][ + result["changepos"]]["value"], watchonly_amount / 10) - signedtx = self.nodes[3].signrawtransaction(result["hex"], None, None, "ALL") + signedtx = self.nodes[3].signrawtransaction( + result["hex"], None, None, "ALL") assert(not signedtx["complete"]) - signedtx = self.nodes[0].signrawtransaction(signedtx["hex"], None, None, "ALL") + signedtx = self.nodes[0].signrawtransaction( + signedtx["hex"], None, None, "ALL") assert(signedtx["complete"]) self.nodes[0].sendrawtransaction(signedtx["hex"]) self.nodes[0].generate(1) self.sync_all() - ####################### + # # Test feeRate option # - ####################### + # - # Make sure there is exactly one input so coin selection can't skew the result + # Make sure there is exactly one input so coin selection can't skew the + # result assert_equal(len(self.nodes[3].listunspent(1)), 1) inputs = [] - outputs = {self.nodes[3].getnewaddress() : 1} + outputs = {self.nodes[3].getnewaddress(): 1} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) - result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee) - result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}) - result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee}) + result = self.nodes[3].fundrawtransaction( + rawtx) # uses min_relay_tx_fee (set by settxfee) + result2 = self.nodes[3].fundrawtransaction( + rawtx, {"feeRate": 2 * min_relay_tx_fee}) + result3 = self.nodes[3].fundrawtransaction( + rawtx, {"feeRate": 10 * min_relay_tx_fee}) result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex']) - assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) - assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) + assert_fee_amount( + result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) + assert_fee_amount( + result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) - ############################# + # # Test address reuse option # - ############################# + # - result3 = self.nodes[3].fundrawtransaction(rawtx, {"reserveChangeKey": False}) + result3 = self.nodes[3].fundrawtransaction( + rawtx, {"reserveChangeKey": False}) res_dec = self.nodes[0].decoderawtransaction(result3["hex"]) changeaddress = "" for out in res_dec['vout']: @@ -688,26 +718,33 @@ # Now the change address key should be removed from the keypool assert(changeaddress != nextaddr) - ###################################### + # # Test subtractFeeFromOutputs option # - ###################################### + # - # Make sure there is exactly one input so coin selection can't skew the result + # Make sure there is exactly one input so coin selection can't skew the + # result assert_equal(len(self.nodes[3].listunspent(1)), 1) inputs = [] outputs = {self.nodes[2].getnewaddress(): 1} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) - result = [self.nodes[3].fundrawtransaction(rawtx), # uses min_relay_tx_fee (set by settxfee) - self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": []}), # empty subtraction list - self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": [0]}), # uses min_relay_tx_fee (set by settxfee) - self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}), - self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee, "subtractFeeFromOutputs": [0]})] - - dec_tx = [self.nodes[3].decoderawtransaction(tx['hex']) for tx in result] - output = [d['vout'][1 - r['changepos']]['value'] for d, r in zip(dec_tx, result)] - change = [d['vout'][r['changepos']]['value'] for d, r in zip(dec_tx, result)] + result = [self.nodes[3].fundrawtransaction(rawtx), # uses min_relay_tx_fee (set by settxfee) + self.nodes[3].fundrawtransaction( + rawtx, {"subtractFeeFromOutputs": []}), # empty subtraction list + self.nodes[3].fundrawtransaction( + rawtx, {"subtractFeeFromOutputs": [0]}), # uses min_relay_tx_fee (set by settxfee) + self.nodes[3].fundrawtransaction( + rawtx, {"feeRate": 2 * min_relay_tx_fee}), + self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2 * min_relay_tx_fee, "subtractFeeFromOutputs": [0]})] + + dec_tx = [self.nodes[3].decoderawtransaction(tx['hex']) + for tx in result] + output = [d['vout'][1 - r['changepos']]['value'] + for d, r in zip(dec_tx, result)] + change = [d['vout'][r['changepos']]['value'] + for d, r in zip(dec_tx, result)] assert_equal(result[0]['fee'], result[1]['fee'], result[2]['fee']) assert_equal(result[3]['fee'], result[4]['fee']) @@ -719,7 +756,8 @@ assert_equal(change[3] + result[3]['fee'], change[4]) inputs = [] - outputs = {self.nodes[2].getnewaddress(): value for value in (1.0, 1.1, 1.2, 1.3)} + outputs = { + self.nodes[2].getnewaddress(): value for value in (1.0, 1.1, 1.2, 1.3)} keys = list(outputs.keys()) rawtx = self.nodes[3].createrawtransaction(inputs, outputs) @@ -734,7 +772,8 @@ output = [[out['value'] for i, out in enumerate(d['vout']) if i != r['changepos']] for d, r in zip(dec_tx, result)] - # List of differences in output amounts between normal and subtractFee transactions + # List of differences in output amounts between normal and subtractFee + # transactions share = [o0 - o1 for o0, o1 in zip(output[0], output[1])] # output 1 is the same in both transactions @@ -748,7 +787,8 @@ # outputs 2 and 3 take the same share of the fee assert_equal(share[2], share[3]) - # output 0 takes at least as much share of the fee, and no more than 2 satoshis more, than outputs 2 and 3 + # output 0 takes at least as much share of the fee, and no more than 2 + # satoshis more, than outputs 2 and 3 assert_greater_than_or_equal(share[0], share[2]) assert_greater_than_or_equal(share[2] + Decimal(2e-8), share[0]) diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -14,10 +14,16 @@ ''' # Use the ComparisonTestFramework with 1 node: only use --testbinary. + + class InvalidTxRequestTest(ComparisonTestFramework): - ''' Can either run this test as 1 node with expected answers, or two and compare them. - Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + ''' + Can either run this test as 1 node with expected answers, or two and + compare them. Change the "outcome" variable from each TestInstance object + to only do the comparison. + ''' + def __init__(self): super().__init__() self.num_nodes = 1 @@ -27,19 +33,20 @@ test.add_all_connections(self.nodes) self.tip = None self.block_time = None - NetworkThread().start() # Start up network handling in another thread + NetworkThread().start() # Start up network handling in another thread test.run() def get_tests(self): if self.tip is None: self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) - self.block_time = int(time.time())+1 + self.block_time = int(time.time()) + 1 ''' Create a new block with an anyone-can-spend coinbase ''' height = 1 - block = create_block(self.tip, create_coinbase(height), self.block_time) + block = create_block( + self.tip, create_coinbase(height), self.block_time) self.block_time += 1 block.solve() # Save the coinbase for later @@ -53,7 +60,8 @@ ''' test = TestInstance(sync_every_block=False) for i in range(100): - block = create_block(self.tip, create_coinbase(height), self.block_time) + block = create_block( + self.tip, create_coinbase(height), self.block_time) block.solve() self.tip = block.sha256 self.block_time += 1 @@ -63,7 +71,8 @@ # b'\x64' is OP_NOTIF # Transaction will be rejected with code 16 (REJECT_INVALID) - tx1 = create_transaction(self.block1.vtx[0], 0, b'\x64', 50 * COIN - 12000) + tx1 = create_transaction( + self.block1.vtx[0], 0, b'\x64', 50 * COIN - 12000) yield TestInstance([[tx1, RejectResult(16, b'mandatory-script-verify-flag-failed')]]) # TODO: test further transactions... diff --git a/qa/rpc-tests/mempool-accept-txn.py b/qa/rpc-tests/mempool-accept-txn.py --- a/qa/rpc-tests/mempool-accept-txn.py +++ b/qa/rpc-tests/mempool-accept-txn.py @@ -21,17 +21,23 @@ # Error for too many sigops in one TX TXNS_TOO_MANY_SIGOPS_ERROR = b'bad-txns-too-many-sigops' -RPC_TXNS_TOO_MANY_SIGOPS_ERROR = "64: " + TXNS_TOO_MANY_SIGOPS_ERROR.decode("utf-8") +RPC_TXNS_TOO_MANY_SIGOPS_ERROR = "64: " + \ + TXNS_TOO_MANY_SIGOPS_ERROR.decode("utf-8") + class PreviousSpendableOutput(object): - def __init__(self, tx = CTransaction(), n = -1): + + def __init__(self, tx=CTransaction(), n=-1): self.tx = tx self.n = n # the output we're spending + class FullBlockTest(ComparisonTestFramework): # Can either run this test as 1 node with expected answers, or two and compare them. - # Change the "outcome" variable from each TestInstance object to only do the comparison. + # Change the "outcome" variable from each TestInstance object to only do + # the comparison. + def __init__(self): super().__init__() self.num_nodes = 1 @@ -50,7 +56,8 @@ def add_options(self, parser): super().add_options(parser) - parser.add_option("--runbarelyexpensive", dest="runbarelyexpensive", default=True) + parser.add_option( + "--runbarelyexpensive", dest="runbarelyexpensive", default=True) def run_test(self): self.test = TestManager(self, self.options.tmpdir) @@ -60,7 +67,7 @@ self.test.run() def add_transactions_to_block(self, block, tx_list): - [ tx.rehash() for tx in tx_list ] + [tx.rehash() for tx in tx_list] block.vtx.extend(tx_list) # this is a little handier to use than the version in blocktools.py @@ -69,14 +76,17 @@ return tx # sign a transaction, using the key we know about - # this signs input 0 in tx, which is assumed to be spending output n in spend_tx + # this signs input 0 in tx, which is assumed to be spending output n in + # spend_tx def sign_tx(self, tx, spend_tx, n): scriptPubKey = bytearray(spend_tx.vout[n].scriptPubKey) if (scriptPubKey[0] == OP_TRUE): # an anyone-can-spend tx.vin[0].scriptSig = CScript() return - (sighash, err) = SignatureHash(spend_tx.vout[n].scriptPubKey, tx, 0, SIGHASH_ALL) - tx.vin[0].scriptSig = CScript([self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))]) + (sighash, err) = SignatureHash( + spend_tx.vout[n].scriptPubKey, tx, 0, SIGHASH_ALL) + tx.vin[0].scriptSig = CScript( + [self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))]) def create_and_sign_transaction(self, spend_tx, n, value, script=CScript([OP_TRUE])): tx = self.create_tx(spend_tx, n, value, script) @@ -87,7 +97,7 @@ def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), solve=True): if self.tip == None: base_block_hash = self.genesis_hash - block_time = int(time.time())+1 + block_time = int(time.time()) + 1 else: base_block_hash = self.tip.sha256 block_time = self.tip.nTime + 1 @@ -99,10 +109,12 @@ if spend == None: block = create_block(base_block_hash, coinbase, block_time) else: - coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees + coinbase.vout[0].nValue += spend.tx.vout[ + spend.n].nValue - 1 # all but one satoshi to fees coinbase.rehash() block = create_block(base_block_hash, coinbase, block_time) - tx = create_transaction(spend.tx, spend.n, b"", 1, script) # spend 1 satoshi + tx = create_transaction( + spend.tx, spend.n, b"", 1, script) # spend 1 satoshi self.sign_tx(tx, spend.tx, spend.n) self.add_transactions_to_block(block, [tx]) block.hashMerkleRoot = block.calc_merkle_root() @@ -132,7 +144,7 @@ return TestInstance([[self.tip, True]]) # returns a test case that asserts that the current tip was rejected - def rejected(reject = None): + def rejected(reject=None): if reject is None: return TestInstance([[self.tip, False]]) else: @@ -152,7 +164,8 @@ # Update the internal state just like in next_block self.tip = block if block.sha256 != old_sha256: - self.block_heights[block.sha256] = self.block_heights[old_sha256] + self.block_heights[ + block.sha256] = self.block_heights[old_sha256] del self.block_heights[old_sha256] self.blocks[block_number] = block return block @@ -184,26 +197,31 @@ # P2SH # Build the redeem script, hash it, use hash to create the p2sh script - redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY]*5 + [OP_CHECKSIG]) + redeem_script = CScript([self.coinbase_pubkey] + [ + OP_2DUP, OP_CHECKSIGVERIFY] * 5 + [OP_CHECKSIG]) redeem_script_hash = hash160(redeem_script) p2sh_script = CScript([OP_HASH160, redeem_script_hash, OP_EQUAL]) # Creates a new transaction using a p2sh transaction as input - def spend_p2sh_tx (p2sh_tx_to_spend, output_script=CScript([OP_TRUE])): + def spend_p2sh_tx(p2sh_tx_to_spend, output_script=CScript([OP_TRUE])): # Create the transaction spent_p2sh_tx = CTransaction() - spent_p2sh_tx.vin.append(CTxIn(COutPoint(p2sh_tx_to_spend.sha256, 0), b'')) + spent_p2sh_tx.vin.append( + CTxIn(COutPoint(p2sh_tx_to_spend.sha256, 0), b'')) spent_p2sh_tx.vout.append(CTxOut(1, output_script)) # Sign the transaction using the redeem script - (sighash, err) = SignatureHash(redeem_script, spent_p2sh_tx, 0, SIGHASH_ALL) - sig = self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL])) + (sighash, err) = SignatureHash( + redeem_script, spent_p2sh_tx, 0, SIGHASH_ALL) + sig = self.coinbase_key.sign( + sighash) + bytes(bytearray([SIGHASH_ALL])) spent_p2sh_tx.vin[0].scriptSig = CScript([sig, redeem_script]) spent_p2sh_tx.rehash() return spent_p2sh_tx # P2SH tests # Create a p2sh transaction - p2sh_tx = self.create_and_sign_transaction(out[0].tx, out[0].n, 1, p2sh_script) + p2sh_tx = self.create_and_sign_transaction( + out[0].tx, out[0].n, 1, p2sh_script) # Add the transaction to the block block(1) @@ -211,13 +229,16 @@ yield accepted() # Sigops p2sh limit for the mempool test - p2sh_sigops_limit_mempool = MAX_STANDARD_TX_SIGOPS - redeem_script.GetSigOpCount(True) + p2sh_sigops_limit_mempool = MAX_STANDARD_TX_SIGOPS - \ + redeem_script.GetSigOpCount(True) # Too many sigops in one p2sh script - too_many_p2sh_sigops_mempool = CScript([OP_CHECKSIG] * (p2sh_sigops_limit_mempool + 1)) + too_many_p2sh_sigops_mempool = CScript( + [OP_CHECKSIG] * (p2sh_sigops_limit_mempool + 1)) # A transaction with this output script can't get into the mempool try: - node.sendrawtransaction(ToHex(spend_p2sh_tx(p2sh_tx, too_many_p2sh_sigops_mempool))) + node.sendrawtransaction( + ToHex(spend_p2sh_tx(p2sh_tx, too_many_p2sh_sigops_mempool))) except JSONRPCException as exp: assert_equal(exp.error["message"], RPC_TXNS_TOO_MANY_SIGOPS_ERROR) else: @@ -227,11 +248,13 @@ assert_equal(set(node.getrawmempool()), set()) # Max sigops in one p2sh txn - max_p2sh_sigops_mempool = CScript([OP_CHECKSIG] * (p2sh_sigops_limit_mempool)) + max_p2sh_sigops_mempool = CScript( + [OP_CHECKSIG] * (p2sh_sigops_limit_mempool)) # A transaction with this output script can get into the mempool max_p2sh_sigops_txn = spend_p2sh_tx(p2sh_tx, max_p2sh_sigops_mempool) - max_p2sh_sigops_txn_id = node.sendrawtransaction(ToHex(max_p2sh_sigops_txn)) + max_p2sh_sigops_txn_id = node.sendrawtransaction( + ToHex(max_p2sh_sigops_txn)) assert_equal(set(node.getrawmempool()), {max_p2sh_sigops_txn_id}) # Mine the transaction diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -8,11 +8,13 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * + class MempoolLimitTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) + self.nodes.append( + start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) self.is_network_split = False self.sync_all() self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] @@ -28,27 +30,29 @@ txids = [] utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 91) - #create a mempool tx that will be evicted + # create a mempool tx that will be evicted us0 = utxos.pop() - inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] - outputs = {self.nodes[0].getnewaddress() : 0.0001} + inputs = [{"txid": us0["txid"], "vout": us0["vout"]}] + outputs = {self.nodes[0].getnewaddress(): 0.0001} tx = self.nodes[0].createrawtransaction(inputs, outputs) - self.nodes[0].settxfee(self.relayfee) # specifically fund this tx with low fee + self.nodes[0].settxfee(self.relayfee) + # specifically fund this tx with low fee txF = self.nodes[0].fundrawtransaction(tx) - self.nodes[0].settxfee(0) # return to automatic fee selection + self.nodes[0].settxfee(0) # return to automatic fee selection txFS = self.nodes[0].signrawtransaction(txF['hex'], None, None, "ALL") txid = self.nodes[0].sendrawtransaction(txFS['hex']) relayfee = self.nodes[0].getnetworkinfo()['relayfee'] - base_fee = relayfee*100 - for i in range (3): + base_fee = relayfee * 100 + 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], 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()) txdata = self.nodes[0].gettransaction(txid) - assert(txdata['confirmations'] == 0) #confirmation should still be 0 + assert(txdata['confirmations'] == 0) # confirmation should still be 0 if __name__ == '__main__': MempoolLimitTest().main() diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -12,7 +12,10 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: + + class MempoolCoinbaseTest(BitcoinTestFramework): + def __init__(self): super().__init__() self.num_nodes = 2 @@ -46,29 +49,40 @@ # 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1 # Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase), # and make sure the mempool code behaves correctly. - b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ] - coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spend_101_raw = create_tx(self.nodes[0], coinbase_txids[1], node1_address, 49.99) - spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 49.99) - spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 49.99) - - # 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}) + b = [self.nodes[0].getblockhash(n) for n in range(101, 105)] + coinbase_txids = [self.nodes[0].getblock(h)['tx'][0] for h in b] + spend_101_raw = create_tx( + self.nodes[0], coinbase_txids[1], node1_address, 49.99) + spend_102_raw = create_tx( + self.nodes[0], coinbase_txids[2], node0_address, 49.99) + spend_103_raw = create_tx( + self.nodes[0], coinbase_txids[3], node0_address, 49.99) + + # 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", "11111191", 1) - timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" - timelock_tx = self.nodes[0].signrawtransaction(timelock_tx, None, None, "ALL")["hex"] - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + timelock_tx = timelock_tx[:-8] + hex( + self.nodes[0].getblockcount() + 2)[2:] + "000000" + timelock_tx = self.nodes[0].signrawtransaction( + timelock_tx, None, None, "ALL")["hex"] + assert_raises(JSONRPCException, self.nodes[ + 0].sendrawtransaction, timelock_tx) # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) self.nodes[0].generate(1) - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + assert_raises(JSONRPCException, self.nodes[ + 0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: - spend_102_1_raw = create_tx(self.nodes[0], spend_102_id, node1_address, 49.98) - spend_103_1_raw = create_tx(self.nodes[0], spend_103_id, node1_address, 49.98) + spend_102_1_raw = create_tx( + self.nodes[0], spend_102_id, node1_address, 49.98) + spend_103_1_raw = create_tx( + self.nodes[0], spend_103_id, node1_address, 49.98) # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) @@ -81,11 +95,13 @@ self.sync_all() - assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, timelock_tx_id}) + assert_equal(set(self.nodes[0].getrawmempool()), { + spend_101_id, spend_102_1_id, timelock_tx_id}) for node in self.nodes: node.invalidateblock(last_block[0]) - assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, spend_103_1_id}) + assert_equal(set(self.nodes[0].getrawmempool()), { + spend_101_id, spend_102_1_id, spend_103_1_id}) # Use invalidateblock to re-org back and make all those coinbase spends # immature/invalid: diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -10,6 +10,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * + class MerkleBlockTest(BitcoinTestFramework): def __init__(self): @@ -24,7 +25,8 @@ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) # Nodes 2/3 are used for testing self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) - self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-txindex"])) + self.nodes.append( + start_node(3, self.options.tmpdir, ["-debug", "-txindex"])) connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[0], 2) connect_nodes(self.nodes[0], 3) @@ -43,10 +45,14 @@ assert_equal(self.nodes[2].getbalance(), 0) node0utxos = self.nodes[0].listunspent(1) - tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) - txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1, None, None, "ALL")["hex"]) - tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) - txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2, None, None, "ALL")["hex"]) + tx1 = self.nodes[0].createrawtransaction( + [node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) + txid1 = self.nodes[0].sendrawtransaction( + self.nodes[0].signrawtransaction(tx1, None, None, "ALL")["hex"]) + tx2 = self.nodes[0].createrawtransaction( + [node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) + txid2 = self.nodes[0].sendrawtransaction( + self.nodes[0].signrawtransaction(tx2, None, None, "ALL")["hex"]) assert_raises(JSONRPCException, self.nodes[0].gettxoutproof, [txid1]) self.nodes[0].generate(1) @@ -58,13 +64,18 @@ txlist.append(blocktxn[1]) txlist.append(blocktxn[2]) - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1])), [txid1]) - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist) - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid1])), [txid1]) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid1, txid2])), txlist) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist) txin_spent = self.nodes[1].listunspent(1).pop() - tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 49.98}) - self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3, None, None, "ALL")["hex"]) + tx3 = self.nodes[1].createrawtransaction( + [txin_spent], {self.nodes[0].getnewaddress(): 49.98}) + self.nodes[0].sendrawtransaction( + self.nodes[1].signrawtransaction(tx3, None, None, "ALL")["hex"]) self.nodes[0].generate(1) self.sync_all() @@ -72,17 +83,23 @@ txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2 # We can't find the block from a fully-spent tx - assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent]) + assert_raises( + JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent]) # ...but we can if we specify the block - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent]) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent]) # ...or if the first tx is not fully-spent - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent]) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent]) try: - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid1, txid2])), txlist) except JSONRPCException: - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid2, txid1])), txlist) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[2].gettxoutproof([txid2, txid1])), txlist) # ...or if we have a -txindex - assert_equal(self.nodes[2].verifytxoutproof(self.nodes[3].gettxoutproof([txid_spent])), [txid_spent]) + assert_equal(self.nodes[2].verifytxoutproof( + self.nodes[3].gettxoutproof([txid_spent])), [txid_spent]) if __name__ == '__main__': MerkleBlockTest().main() diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -13,6 +13,7 @@ NULLDUMMY_ERROR = "64: non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)" + def trueDummy(tx): scriptSig = CScript(tx.vin[0].scriptSig) newscript = [] @@ -36,6 +37,7 @@ [Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. ''' + class NULLDUMMYTest(BitcoinTestFramework): def __init__(self): @@ -50,38 +52,43 @@ def run_test(self): self.address = self.nodes[0].getnewaddress() - self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address]) + self.ms_address = self.nodes[0].addmultisigaddress(1, [self.address]) - NetworkThread().start() # Start up network handling in another thread - self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 + NetworkThread().start() # Start up network handling in another thread + self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 coinbase_txid = [] for i in self.coinbase_blocks: coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0]) - self.nodes[0].generate(427) # Block 429 + self.nodes[0].generate(427) # Block 429 self.lastblockhash = self.nodes[0].getbestblockhash() self.tip = int("0x" + self.lastblockhash, 0) self.lastblockheight = 429 self.lastblocktime = int(time.time()) + 429 - print ("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") - test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] + print ( + "Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") + test1txs = [self.create_transaction( + self.nodes[0], coinbase_txid[0], self.ms_address, 49)] txid1 = self.tx_submit(self.nodes[0], test1txs[0]) - test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48)) + test1txs.append(self.create_transaction( + self.nodes[0], txid1, self.ms_address, 48)) txid2 = self.tx_submit(self.nodes[0], test1txs[1]) self.block_submit(self.nodes[0], test1txs, False, True) - print ("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") - test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 48) + print ( + "Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") + test2tx = self.create_transaction( + self.nodes[0], txid2, self.ms_address, 48) trueDummy(test2tx) txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR) - print ("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") + print ( + "Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") self.block_submit(self.nodes[0], [test2tx], False, True) - def create_transaction(self, node, txid, to_address, amount): - inputs = [{ "txid" : txid, "vout" : 0}] - outputs = { to_address : amount } + inputs = [{"txid": txid, "vout": 0}] + outputs = {to_address: amount} rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx, None, None, "ALL") tx = CTransaction() @@ -89,20 +96,20 @@ tx.deserialize(f) return tx - - def tx_submit(self, node, tx, msg = ""): + def tx_submit(self, node, tx, msg=""): tx.rehash() try: - node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True) + node.sendrawtransaction( + bytes_to_hex_str(tx.serialize_with_witness()), True) except JSONRPCException as exp: assert_equal(exp.error["message"], msg) else: assert_equal('', msg) return tx.hash - - def block_submit(self, node, txs, witness = False, accept = False): - block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1) + def block_submit(self, node, txs, witness=False, accept=False): + block = create_block(self.tip, create_coinbase( + self.lastblockheight + 1), self.lastblocktime + 1) block.nVersion = 4 for tx in txs: tx.rehash() diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -58,7 +58,10 @@ # TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # p2p messages to a node, generating the messages in the main testing logic. + + class TestNode(NodeConnCB): + def __init__(self): NodeConnCB.__init__(self) self.connection = None @@ -106,6 +109,7 @@ class AcceptBlockTest(BitcoinTestFramework): + def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", default=os.getenv("BITCOIND", "bitcoind"), @@ -133,33 +137,36 @@ white_node = TestNode() # connects to node1 (whitelisted) connections = [] - connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node)) - connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], white_node)) + connections.append( + NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node)) + connections.append( + NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], white_node)) test_node.add_connection(connections[0]) white_node.add_connection(connections[1]) - NetworkThread().start() # Start up network handling in another thread + NetworkThread().start() # Start up network handling in another thread # Test logic begins here test_node.wait_for_verack() white_node.wait_for_verack() # 1. Have both nodes mine a block (leave IBD) - [ n.generate(1) for n in self.nodes ] - tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ] + [n.generate(1) for n in self.nodes] + tips = [int("0x" + n.getbestblockhash(), 0) for n in self.nodes] # 2. Send one block that builds on each tip. # This should be accepted. blocks_h2 = [] # the height 2 blocks on each node's chain block_time = int(time.time()) + 1 for i in range(2): - blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) + blocks_h2.append( + create_block(tips[i], create_coinbase(2), block_time)) blocks_h2[i].solve() block_time += 1 test_node.send_message(msg_block(blocks_h2[0])) white_node.send_message(msg_block(blocks_h2[1])) - [ x.sync_with_ping() for x in [test_node, white_node] ] + [x.sync_with_ping() for x in [test_node, white_node]] assert_equal(self.nodes[0].getblockcount(), 2) assert_equal(self.nodes[1].getblockcount(), 2) print("First height 2 block accepted by both nodes") @@ -167,12 +174,13 @@ # 3. Send another block that builds on the original tip. blocks_h2f = [] # Blocks at height 2 that fork off the main chain for i in range(2): - blocks_h2f.append(create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime+1)) + blocks_h2f.append( + create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime + 1)) blocks_h2f[i].solve() test_node.send_message(msg_block(blocks_h2f[0])) white_node.send_message(msg_block(blocks_h2f[1])) - [ x.sync_with_ping() for x in [test_node, white_node] ] + [x.sync_with_ping() for x in [test_node, white_node]] for x in self.nodes[0].getchaintips(): if x['hash'] == blocks_h2f[0].hash: assert_equal(x['status'], "headers-only") @@ -186,12 +194,13 @@ # 4. Now send another block that builds on the forking chain. blocks_h3 = [] for i in range(2): - blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime+1)) + blocks_h3.append( + create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime + 1)) blocks_h3[i].solve() test_node.send_message(msg_block(blocks_h3[0])) white_node.send_message(msg_block(blocks_h3[1])) - [ x.sync_with_ping() for x in [test_node, white_node] ] + [x.sync_with_ping() for x in [test_node, white_node]] # Since the earlier block was not processed by node0, the new block # can't be fully validated. for x in self.nodes[0].getchaintips(): @@ -201,9 +210,11 @@ # But this block should be accepted by node0 since it has more work. try: self.nodes[0].getblock(blocks_h3[0].hash) - print("Unrequested more-work block accepted from non-whitelisted peer") + print( + "Unrequested more-work block accepted from non-whitelisted peer") except: - raise AssertionError("Unrequested more work block was not processed") + raise AssertionError( + "Unrequested more work block was not processed") # Node1 should have accepted and reorged. assert_equal(self.nodes[1].getblockcount(), 3) @@ -217,9 +228,10 @@ all_blocks = [] # node0's blocks for j in range(2): for i in range(288): - next_block = create_block(tips[j].sha256, create_coinbase(i + 4), tips[j].nTime+1) + next_block = create_block( + tips[j].sha256, create_coinbase(i + 4), tips[j].nTime + 1) next_block.solve() - if j==0: + if j == 0: test_node.send_message(msg_block(next_block)) all_blocks.append(next_block) else: @@ -231,22 +243,26 @@ try: self.nodes[0].getblock(x.hash) if x == all_blocks[287]: - raise AssertionError("Unrequested block too far-ahead should have been ignored") + raise AssertionError( + "Unrequested block too far-ahead should have been ignored") except: if x == all_blocks[287]: print("Unrequested block too far-ahead not processed") else: - raise AssertionError("Unrequested block with more work should have been accepted") + raise AssertionError( + "Unrequested block with more work should have been accepted") - headers_message.headers.pop() # Ensure the last block is unrequested - white_node.send_message(headers_message) # Send headers leading to tip + headers_message.headers.pop() # Ensure the last block is unrequested + white_node.send_message(headers_message) # Send headers leading to tip white_node.send_message(msg_block(tips[1])) # Now deliver the tip try: white_node.sync_with_ping() self.nodes[1].getblock(tips[1].hash) - print("Unrequested block far ahead of tip accepted from whitelisted peer") + print( + "Unrequested block far ahead of tip accepted from whitelisted peer") except: - raise AssertionError("Unrequested block from whitelisted peer not accepted") + raise AssertionError( + "Unrequested block from whitelisted peer not accepted") # 5. Test handling of unrequested block on the node that didn't process # Should still not be processed (even though it has a child that has more @@ -260,7 +276,8 @@ # a getdata request for this block. test_node.sync_with_ping() assert_equal(self.nodes[0].getblockcount(), 2) - print("Unrequested block that would complete more-work chain was ignored") + print( + "Unrequested block that would complete more-work chain was ignored") # 6. Try to get node to request the missing block. # Poke the node with an inv for block at height 3 and see if that @@ -285,7 +302,7 @@ assert_equal(self.nodes[0].getblockcount(), 290) print("Successfully reorged to longer chain from non-whitelisted peer") - [ c.disconnect_node() for c in connections ] + [c.disconnect_node() for c in connections] if __name__ == '__main__': AcceptBlockTest().main() diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -14,8 +14,10 @@ import struct from test_framework.cdefs import LEGACY_MAX_BLOCK_SIZE, MAX_BLOCK_SIGOPS_PER_MB + class PreviousSpendableOutput(object): - def __init__(self, tx = CTransaction(), n = -1): + + def __init__(self, tx=CTransaction(), n=-1): self.tx = tx self.n = n # the output we're spending @@ -29,7 +31,10 @@ # Use this class for tests that require behavior other than normal "mininode" behavior. # For now, it is used to serialize a bloated varint (b64). + + class CBrokenBlock(CBlock): + def __init__(self, header=None): super(CBrokenBlock, self).__init__(header) @@ -54,7 +59,9 @@ class FullBlockTest(ComparisonTestFramework): # Can either run this test as 1 node with expected answers, or two and compare them. - # Change the "outcome" variable from each TestInstance object to only do the comparison. + # Change the "outcome" variable from each TestInstance object to only do + # the comparison. + def __init__(self): super().__init__() self.num_nodes = 1 @@ -67,7 +74,8 @@ def add_options(self, parser): super().add_options(parser) - parser.add_option("--runbarelyexpensive", dest="runbarelyexpensive", default=True) + parser.add_option( + "--runbarelyexpensive", dest="runbarelyexpensive", default=True) def run_test(self): self.test = TestManager(self, self.options.tmpdir) @@ -77,7 +85,7 @@ self.test.run() def add_transactions_to_block(self, block, tx_list): - [ tx.rehash() for tx in tx_list ] + [tx.rehash() for tx in tx_list] block.vtx.extend(tx_list) # this is a little handier to use than the version in blocktools.py @@ -86,14 +94,17 @@ return tx # sign a transaction, using the key we know about - # this signs input 0 in tx, which is assumed to be spending output n in spend_tx + # this signs input 0 in tx, which is assumed to be spending output n in + # spend_tx def sign_tx(self, tx, spend_tx, n): scriptPubKey = bytearray(spend_tx.vout[n].scriptPubKey) if (scriptPubKey[0] == OP_TRUE): # an anyone-can-spend tx.vin[0].scriptSig = CScript() return - (sighash, err) = SignatureHash(spend_tx.vout[n].scriptPubKey, tx, 0, SIGHASH_ALL) - tx.vin[0].scriptSig = CScript([self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))]) + (sighash, err) = SignatureHash( + spend_tx.vout[n].scriptPubKey, tx, 0, SIGHASH_ALL) + tx.vin[0].scriptSig = CScript( + [self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))]) def create_and_sign_transaction(self, spend_tx, n, value, script=CScript([OP_TRUE])): tx = self.create_tx(spend_tx, n, value, script) @@ -104,7 +115,7 @@ def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), solve=True): if self.tip == None: base_block_hash = self.genesis_hash - block_time = int(time.time())+1 + block_time = int(time.time()) + 1 else: base_block_hash = self.tip.sha256 block_time = self.tip.nTime + 1 @@ -116,10 +127,12 @@ if spend == None: block = create_block(base_block_hash, coinbase, block_time) else: - coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees + coinbase.vout[0].nValue += spend.tx.vout[ + spend.n].nValue - 1 # all but one satoshi to fees coinbase.rehash() block = create_block(base_block_hash, coinbase, block_time) - tx = create_transaction(spend.tx, spend.n, b"", 1, script) # spend 1 satoshi + tx = create_transaction( + spend.tx, spend.n, b"", 1, script) # spend 1 satoshi self.sign_tx(tx, spend.tx, spend.n) self.add_transactions_to_block(block, [tx]) block.hashMerkleRoot = block.calc_merkle_root() @@ -149,7 +162,7 @@ return TestInstance([[self.tip, True]]) # returns a test case that asserts that the current tip was rejected - def rejected(reject = None): + def rejected(reject=None): if reject is None: return TestInstance([[self.tip, False]]) else: @@ -169,7 +182,8 @@ # Update the internal state just like in next_block self.tip = block if block.sha256 != old_sha256: - self.block_heights[block.sha256] = self.block_heights[old_sha256] + self.block_heights[ + block.sha256] = self.block_heights[old_sha256] del self.block_heights[old_sha256] self.blocks[block_number] = block return block @@ -179,13 +193,11 @@ create_tx = self.create_tx create_and_sign_tx = self.create_and_sign_transaction - # Create a new block block(0) save_spendable_output() yield accepted() - # Now we need that block to mature so we can spend the coinbase. test = TestInstance(sync_every_block=False) for i in range(99): @@ -215,13 +227,13 @@ # genesis -> b1 (0) -> b2 (1) # \-> b3 (1) # - # Nothing should happen at this point. We saw b2 first so it takes priority. + # Nothing should happen at this point. We saw b2 first so it takes + # priority. tip(1) b3 = block(3, spend=out[1]) txout_b3 = PreviousSpendableOutput(b3.vtx[1], 0) yield rejected() - # Now we add another block to make the alternative chain longer. # # genesis -> b1 (0) -> b2 (1) @@ -229,7 +241,6 @@ block(4, spend=out[2]) yield accepted() - # ... and back to the first chain. # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b3 (1) -> b4 (2) @@ -271,7 +282,6 @@ block(11, spend=out[4], additional_coinbase_value=1) yield rejected(RejectResult(16, b'bad-cb-amount')) - # Try again, but with a valid fork first # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b12 (3) -> b13 (4) -> b14 (5) @@ -282,7 +292,8 @@ save_spendable_output() b13 = block(13, spend=out[4]) # Deliver the block header for b12, and the block b13. - # b13 should be accepted but the tip won't advance until b12 is delivered. + # b13 should be accepted but the tip won't advance until b12 is + # delivered. yield TestInstance([[CBlockHeader(b12), None], [b13, False]]) save_spendable_output() @@ -291,7 +302,7 @@ block(14, spend=out[5], additional_coinbase_value=1) yield rejected() - yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. + yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. # Add a block with MAX_BLOCK_SIGOPS_PER_MB and one with one more sigop # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -299,19 +310,18 @@ # \-> b3 (1) -> b4 (2) # Test that a block with a lot of checksigs is okay - lots_of_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS_PER_MB - 1)) + lots_of_checksigs = CScript( + [OP_CHECKSIG] * (MAX_BLOCK_SIGOPS_PER_MB - 1)) tip(13) block(15, spend=out[5], script=lots_of_checksigs) yield accepted() save_spendable_output() - # Test that a block with too many checksigs is rejected too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS_PER_MB)) block(16, spend=out[6], script=too_many_checksigs) yield rejected(RejectResult(16, b'bad-blk-sigops')) - # Attempt to spend a transaction created on a different fork # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1]) @@ -374,10 +384,10 @@ tip(15) b24 = block(24, spend=out[6]) script_length = LEGACY_MAX_BLOCK_SIZE - len(b24.serialize()) - 69 - script_output = CScript([b'\x00' * (script_length+1)]) + script_output = CScript([b'\x00' * (script_length + 1)]) tx.vout = [CTxOut(0, script_output)] b24 = update_block(24, [tx]) - assert_equal(len(b24.serialize()), LEGACY_MAX_BLOCK_SIZE+1) + assert_equal(len(b24.serialize()), LEGACY_MAX_BLOCK_SIZE + 1) yield rejected(RejectResult(16, b'bad-blk-length')) block(25, spend=out[7]) @@ -430,44 +440,49 @@ # \-> b32 (9) # - # MULTISIG: each op code counts as 20 sigops. To create the edge case, pack another 19 sigops at the end. - lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS_PER_MB-1) // 20) + [OP_CHECKSIG] * 19) + # MULTISIG: each op code counts as 20 sigops. To create the edge case, + # pack another 19 sigops at the end. + lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ( + (MAX_BLOCK_SIGOPS_PER_MB - 1) // 20) + [OP_CHECKSIG] * 19) b31 = block(31, spend=out[8], script=lots_of_multisigs) assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS_PER_MB) yield accepted() save_spendable_output() # this goes over the limit because the coinbase has one sigop - too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS_PER_MB // 20)) + too_many_multisigs = CScript( + [OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS_PER_MB // 20)) b32 = block(32, spend=out[9], script=too_many_multisigs) - assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS_PER_MB + 1) + assert_equal(get_legacy_sigopcount_block( + b32), MAX_BLOCK_SIGOPS_PER_MB + 1) yield rejected(RejectResult(16, b'bad-blk-sigops')) - # CHECKMULTISIGVERIFY tip(31) - lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS_PER_MB-1) // 20) + [OP_CHECKSIG] * 19) + lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ( + (MAX_BLOCK_SIGOPS_PER_MB - 1) // 20) + [OP_CHECKSIG] * 19) block(33, spend=out[9], script=lots_of_multisigs) yield accepted() save_spendable_output() - too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS_PER_MB // 20)) + too_many_multisigs = CScript( + [OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS_PER_MB // 20)) block(34, spend=out[10], script=too_many_multisigs) yield rejected(RejectResult(16, b'bad-blk-sigops')) - # CHECKSIGVERIFY tip(33) - lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS_PER_MB - 1)) + lots_of_checksigs = CScript( + [OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS_PER_MB - 1)) b35 = block(35, spend=out[10], script=lots_of_checksigs) yield accepted() save_spendable_output() - too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS_PER_MB)) + too_many_checksigs = CScript( + [OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS_PER_MB)) block(36, spend=out[11], script=too_many_checksigs) yield rejected(RejectResult(16, b'bad-blk-sigops')) - # Check spending of a transaction in a block which failed to connect # # b6 (3) @@ -476,7 +491,8 @@ # \-> b38 (11/37) # - # save 37's spendable output, but then double-spend out11 to invalidate the block + # save 37's spendable output, but then double-spend out11 to invalidate + # the block tip(35) b37 = block(37, spend=out[11]) txout_b37 = PreviousSpendableOutput(b37.vtx[1], 0) @@ -484,7 +500,8 @@ b37 = update_block(37, [tx]) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) - # attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid + # attempt to spend b37's first non-coinbase tx, at which point b37 was + # still considered valid tip(35) block(38, spend=txout_b37) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) @@ -506,7 +523,8 @@ b39_sigops_per_output = 6 # Build the redeem script, hash it, use hash to create the p2sh script - redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY]*5 + [OP_CHECKSIG]) + redeem_script = CScript([self.coinbase_pubkey] + [ + OP_2DUP, OP_CHECKSIGVERIFY] * 5 + [OP_CHECKSIG]) redeem_script_hash = hash160(redeem_script) p2sh_script = CScript([OP_HASH160, redeem_script_hash, OP_EQUAL]) @@ -514,24 +532,27 @@ # This must be signed because it is spending a coinbase spend = out[11] tx = create_tx(spend.tx, spend.n, 1, p2sh_script) - tx.vout.append(CTxOut(spend.tx.vout[spend.n].nValue - 1, CScript([OP_TRUE]))) + tx.vout.append( + CTxOut(spend.tx.vout[spend.n].nValue - 1, CScript([OP_TRUE]))) self.sign_tx(tx, spend.tx, spend.n) tx.rehash() b39 = update_block(39, [tx]) b39_outputs += 1 - # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest to OP_TRUE + # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest + # to OP_TRUE tx_new = None tx_last = tx - total_size=len(b39.serialize()) + total_size = len(b39.serialize()) while(total_size < LEGACY_MAX_BLOCK_SIZE): tx_new = create_tx(tx_last, 1, 1, p2sh_script) - tx_new.vout.append(CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE]))) + tx_new.vout.append( + CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE]))) tx_new.rehash() total_size += len(tx_new.serialize()) if total_size >= LEGACY_MAX_BLOCK_SIZE: break - b39.vtx.append(tx_new) # add tx to block + b39.vtx.append(tx_new) # add tx to block tx_last = tx_new b39_outputs += 1 @@ -539,7 +560,6 @@ yield accepted() save_spendable_output() - # Test sigops in P2SH redeem scripts # # b40 creates 3333 tx's spending the 6-sigop P2SH outputs from b39 for a total of 19998 sigops. @@ -555,15 +575,17 @@ lastOutpoint = COutPoint(b40.vtx[1].sha256, 0) new_txs = [] - for i in range(1, numTxes+1): + for i in range(1, numTxes + 1): tx = CTransaction() tx.vout.append(CTxOut(1, CScript([OP_TRUE]))) tx.vin.append(CTxIn(lastOutpoint, b'')) # second input is corresponding P2SH output from b39 tx.vin.append(CTxIn(COutPoint(b39.vtx[i].sha256, 0), b'')) - # Note: must pass the redeem_script (not p2sh_script) to the signature hash function + # Note: must pass the redeem_script (not p2sh_script) to the + # signature hash function (sighash, err) = SignatureHash(redeem_script, tx, 1, SIGHASH_ALL) - sig = self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL])) + sig = self.coinbase_key.sign( + sighash) + bytes(bytearray([SIGHASH_ALL])) scriptSig = CScript([sig, redeem_script]) tx.vin[1].scriptSig = scriptSig @@ -571,7 +593,8 @@ new_txs.append(tx) lastOutpoint = COutPoint(tx.sha256, 0) - b40_sigops_to_fill = MAX_BLOCK_SIGOPS_PER_MB - (numTxes * b39_sigops_per_output + sigops) + 1 + b40_sigops_to_fill = MAX_BLOCK_SIGOPS_PER_MB - \ + (numTxes * b39_sigops_per_output + sigops) + 1 tx = CTransaction() tx.vin.append(CTxIn(lastOutpoint, b'')) tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b40_sigops_to_fill))) @@ -606,14 +629,14 @@ yield accepted() save_spendable_output() - # Test a number of really invalid scenarios # # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b44 (14) # \-> ??? (15) # The next few blocks are going to be created "by hand" since they'll do funky things, such as having - # the first transaction be non-coinbase, etc. The purpose of b44 is to make sure this works. + # the first transaction be non-coinbase, etc. The purpose of b44 is to + # make sure this works. height = self.block_heights[self.tip.sha256] + 1 coinbase = create_coinbase(height, self.coinbase_pubkey) b44 = CBlock() @@ -638,7 +661,8 @@ b45.hashMerkleRoot = b45.calc_merkle_root() b45.calc_sha256() b45.solve() - self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256]+1 + self.block_heights[b45.sha256] = self.block_heights[ + self.tip.sha256] + 1 self.tip = b45 self.blocks[45] = b45 yield rejected(RejectResult(16, b'bad-cb-missing')) @@ -646,13 +670,13 @@ # A block with no txns tip(44) b46 = CBlock() - b46.nTime = b44.nTime+1 + b46.nTime = b44.nTime + 1 b46.hashPrevBlock = b44.sha256 b46.nBits = 0x207fffff b46.vtx = [] b46.hashMerkleRoot = 0 b46.solve() - self.block_heights[b46.sha256] = self.block_heights[b44.sha256]+1 + self.block_heights[b46.sha256] = self.block_heights[b44.sha256] + 1 self.tip = b46 assert 46 not in self.blocks self.blocks[46] = b46 @@ -663,7 +687,7 @@ tip(44) b47 = block(47, solve=False) target = uint256_from_compact(b47.nBits) - while b47.sha256 < target: #changed > to < + while b47.sha256 < target: # changed > to < b47.nNonce += 1 b47.rehash() yield rejected(RejectResult(16, b'high-hash')) @@ -697,7 +721,8 @@ yield rejected(RejectResult(16, b'bad-tx-coinbase')) # A block w/ duplicate txns - # Note: txns have to be in the right position in the merkle tree to trigger this error + # Note: txns have to be in the right position in the merkle tree to + # trigger this error tip(44) b52 = block(52, spend=out[15]) tx = create_tx(b52.vtx[1], 0, 1) @@ -710,10 +735,11 @@ # tip(43) block(53, spend=out[14]) - yield rejected() # rejected since b44 is at same height + yield rejected() # rejected since b44 is at same height save_spendable_output() - # invalid timestamp (b35 is 5 blocks back, so its time is MedianTimePast) + # invalid timestamp (b35 is 5 blocks back, so its time is + # MedianTimePast) b54 = block(54, spend=out[15]) b54.nTime = b35.nTime - 1 b54.solve() @@ -727,7 +753,6 @@ yield accepted() save_spendable_output() - # Test CVE-2012-2459 # # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57p2 (16) @@ -735,7 +760,7 @@ # \-> b56p2 (16) # \-> b56 (16) # - # Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without + # Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without # affecting the merkle root of a block, while still invalidating it. # See: src/consensus/merkle.h # @@ -766,7 +791,7 @@ tip(55) b56 = copy.deepcopy(b57) self.blocks[56] = b56 - assert_equal(len(b56.vtx),3) + assert_equal(len(b56.vtx), 3) b56 = update_block(56, [tx1]) assert_equal(b56.hash, b57.hash) yield rejected(RejectResult(16, b'bad-txns-duplicate')) @@ -786,7 +811,7 @@ b56p2 = copy.deepcopy(b57p2) self.blocks["b56p2"] = b56p2 assert_equal(b56p2.hash, b57p2.hash) - assert_equal(len(b56p2.vtx),6) + assert_equal(len(b56p2.vtx), 6) b56p2 = update_block("b56p2", [tx3, tx4]) yield rejected(RejectResult(16, b'bad-txns-duplicate')) @@ -794,7 +819,7 @@ yield accepted() tip(57) - yield rejected() #rejected because 57p2 seen first + yield rejected() # rejected because 57p2 seen first save_spendable_output() # Test a few invalid tx types @@ -808,7 +833,8 @@ b58 = block(58, spend=out[17]) tx = CTransaction() assert(len(out[17].tx.vout) < 42) - tx.vin.append(CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff)) + tx.vin.append( + CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff)) tx.vout.append(CTxOut(0, b"")) tx.calc_sha256() b58 = update_block(58, [tx]) @@ -817,7 +843,7 @@ # tx with output value > input value out of range tip(57) b59 = block(59) - tx = create_and_sign_tx(out[17].tx, out[17].n, 51*COIN) + tx = create_and_sign_tx(out[17].tx, out[17].n, 51 * COIN) b59 = update_block(59, [tx]) yield rejected(RejectResult(16, b'bad-txns-in-belowout')) @@ -838,13 +864,13 @@ # tip(60) b61 = block(61, spend=out[18]) - b61.vtx[0].vin[0].scriptSig = b60.vtx[0].vin[0].scriptSig #equalize the coinbases + b61.vtx[0].vin[0].scriptSig = b60.vtx[ + 0].vin[0].scriptSig # equalize the coinbases b61.vtx[0].rehash() b61 = update_block(61, []) assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize()) yield rejected(RejectResult(16, b'bad-txns-BIP30')) - # Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests) # # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) @@ -853,16 +879,16 @@ tip(60) b62 = block(62) tx = CTransaction() - tx.nLockTime = 0xffffffff #this locktime is non-final + tx.nLockTime = 0xffffffff # this locktime is non-final assert(out[18].n < len(out[18].tx.vout)) - tx.vin.append(CTxIn(COutPoint(out[18].tx.sha256, out[18].n))) # don't set nSequence + tx.vin.append( + CTxIn(COutPoint(out[18].tx.sha256, out[18].n))) # don't set nSequence tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) assert(tx.vin[0].nSequence < 0xffffffff) tx.calc_sha256() b62 = update_block(62, [tx]) yield rejected(RejectResult(16, b'bad-txns-nonfinal')) - # Test a non-final coinbase is also rejected # # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) @@ -876,7 +902,6 @@ b63 = update_block(63, []) yield rejected(RejectResult(16, b'bad-txns-nonfinal')) - # This checks that a block with a bloated VARINT between the block_header and the array of tx such that # the block is > LEGACY_MAX_BLOCK_SIZE with the bloated varint, but <= LEGACY_MAX_BLOCK_SIZE without the bloated varint, # does not cause a subsequent, identical block with canonical encoding to be rejected. The test does not @@ -902,7 +927,8 @@ tx = CTransaction() # use canonical serialization to calculate size - script_length = LEGACY_MAX_BLOCK_SIZE - len(b64a.normal_serialize()) - 69 + script_length = LEGACY_MAX_BLOCK_SIZE - \ + len(b64a.normal_serialize()) - 69 script_output = CScript([b'\x00' * script_length]) tx.vout.append(CTxOut(0, script_output)) tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0))) @@ -910,7 +936,8 @@ assert_equal(len(b64a.serialize()), LEGACY_MAX_BLOCK_SIZE + 8) yield TestInstance([[self.tip, None]]) - # comptool workaround: to make sure b64 is delivered, manually erase b64a from blockstore + # comptool workaround: to make sure b64 is delivered, manually erase + # b64a from blockstore self.test.block_store.erase(b64a.sha256) tip(60) @@ -929,7 +956,8 @@ # tip(64) b65 = block(65) - tx1 = create_and_sign_tx(out[19].tx, out[19].n, out[19].tx.vout[0].nValue) + tx1 = create_and_sign_tx( + out[19].tx, out[19].n, out[19].tx.vout[0].nValue) tx2 = create_and_sign_tx(tx1, 0, 0) update_block(65, [tx1, tx2]) yield accepted() @@ -941,7 +969,8 @@ # \-> b66 (20) tip(65) b66 = block(66) - tx1 = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue) + tx1 = create_and_sign_tx( + out[20].tx, out[20].n, out[20].tx.vout[0].nValue) tx2 = create_and_sign_tx(tx1, 0, 1) update_block(66, [tx2, tx1]) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) @@ -954,7 +983,8 @@ # tip(65) b67 = block(67) - tx1 = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue) + tx1 = create_and_sign_tx( + out[20].tx, out[20].n, out[20].tx.vout[0].nValue) tx2 = create_and_sign_tx(tx1, 0, 1) tx3 = create_and_sign_tx(tx1, 0, 2) update_block(67, [tx1, tx2, tx3]) @@ -974,13 +1004,15 @@ # tip(65) b68 = block(68, additional_coinbase_value=10) - tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue-9) + tx = create_and_sign_tx( + out[20].tx, out[20].n, out[20].tx.vout[0].nValue - 9) update_block(68, [tx]) yield rejected(RejectResult(16, b'bad-cb-amount')) tip(65) b69 = block(69, additional_coinbase_value=10) - tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue-10) + tx = create_and_sign_tx( + out[20].tx, out[20].n, out[20].tx.vout[0].nValue - 10) update_block(69, [tx]) yield accepted() save_spendable_output() @@ -993,14 +1025,14 @@ tip(69) block(70, spend=out[21]) bogus_tx = CTransaction() - bogus_tx.sha256 = uint256_from_str(b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c") + bogus_tx.sha256 = uint256_from_str( + b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c") tx = CTransaction() tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff)) tx.vout.append(CTxOut(1, b"")) update_block(70, [tx]) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) - # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) # # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) @@ -1016,7 +1048,8 @@ b72 = update_block(72, [tx1, tx2]) # now tip is 72 b71 = copy.deepcopy(b72) b71.vtx.append(tx2) # add duplicate tx2 - self.block_heights[b71.sha256] = self.block_heights[b69.sha256] + 1 # b71 builds off b69 + self.block_heights[b71.sha256] = self.block_heights[ + b69.sha256] + 1 # b71 builds off b69 self.blocks[71] = b71 assert_equal(len(b71.vtx), 4) @@ -1029,7 +1062,6 @@ yield accepted() save_spendable_output() - # Test some invalid scripts and MAX_BLOCK_SIGOPS_PER_MB # # -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) @@ -1049,19 +1081,21 @@ # tip(72) b73 = block(73) - size = MAX_BLOCK_SIGOPS_PER_MB - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1 + size = MAX_BLOCK_SIGOPS_PER_MB - 1 + \ + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1 a = bytearray([OP_CHECKSIG] * size) - a[MAX_BLOCK_SIGOPS_PER_MB - 1] = int("4e",16) # OP_PUSHDATA4 + a[MAX_BLOCK_SIGOPS_PER_MB - 1] = int("4e", 16) # OP_PUSHDATA4 element_size = MAX_SCRIPT_ELEMENT_SIZE + 1 a[MAX_BLOCK_SIGOPS_PER_MB] = element_size % 256 - a[MAX_BLOCK_SIGOPS_PER_MB+1] = element_size // 256 - a[MAX_BLOCK_SIGOPS_PER_MB+2] = 0 - a[MAX_BLOCK_SIGOPS_PER_MB+3] = 0 + a[MAX_BLOCK_SIGOPS_PER_MB + 1] = element_size // 256 + a[MAX_BLOCK_SIGOPS_PER_MB + 2] = 0 + a[MAX_BLOCK_SIGOPS_PER_MB + 3] = 0 tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) b73 = update_block(73, [tx]) - assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS_PER_MB+1) + assert_equal( + get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS_PER_MB + 1) yield rejected(RejectResult(16, b'bad-blk-sigops')) # b74/75 - if we push an invalid script element, all prevous sigops are counted, @@ -1078,13 +1112,14 @@ # tip(72) b74 = block(74) - size = MAX_BLOCK_SIGOPS_PER_MB - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561 + size = MAX_BLOCK_SIGOPS_PER_MB - 1 + \ + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561 a = bytearray([OP_CHECKSIG] * size) a[MAX_BLOCK_SIGOPS_PER_MB] = 0x4e - a[MAX_BLOCK_SIGOPS_PER_MB+1] = 0xfe - a[MAX_BLOCK_SIGOPS_PER_MB+2] = 0xff - a[MAX_BLOCK_SIGOPS_PER_MB+3] = 0xff - a[MAX_BLOCK_SIGOPS_PER_MB+4] = 0xff + a[MAX_BLOCK_SIGOPS_PER_MB + 1] = 0xfe + a[MAX_BLOCK_SIGOPS_PER_MB + 2] = 0xff + a[MAX_BLOCK_SIGOPS_PER_MB + 3] = 0xff + a[MAX_BLOCK_SIGOPS_PER_MB + 4] = 0xff tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) b74 = update_block(74, [tx]) yield rejected(RejectResult(16, b'bad-blk-sigops')) @@ -1093,22 +1128,24 @@ b75 = block(75) size = MAX_BLOCK_SIGOPS_PER_MB - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 a = bytearray([OP_CHECKSIG] * size) - a[MAX_BLOCK_SIGOPS_PER_MB-1] = 0x4e + a[MAX_BLOCK_SIGOPS_PER_MB - 1] = 0x4e a[MAX_BLOCK_SIGOPS_PER_MB] = 0xff - a[MAX_BLOCK_SIGOPS_PER_MB+1] = 0xff - a[MAX_BLOCK_SIGOPS_PER_MB+2] = 0xff - a[MAX_BLOCK_SIGOPS_PER_MB+3] = 0xff + a[MAX_BLOCK_SIGOPS_PER_MB + 1] = 0xff + a[MAX_BLOCK_SIGOPS_PER_MB + 2] = 0xff + a[MAX_BLOCK_SIGOPS_PER_MB + 3] = 0xff tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) b75 = update_block(75, [tx]) yield accepted() save_spendable_output() - # Check that if we push an element filled with CHECKSIGs, they are not counted + # Check that if we push an element filled with CHECKSIGs, they are not + # counted tip(75) b76 = block(76) size = MAX_BLOCK_SIGOPS_PER_MB - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 a = bytearray([OP_CHECKSIG] * size) - a[MAX_BLOCK_SIGOPS_PER_MB-1] = 0x4e # PUSHDATA4, but leave the following bytes as just checksigs + a[MAX_BLOCK_SIGOPS_PER_MB - + 1] = 0x4e # PUSHDATA4, but leave the following bytes as just checksigs tx = create_and_sign_tx(out[23].tx, 0, 1, CScript(a)) b76 = update_block(76, [tx]) yield accepted() @@ -1134,18 +1171,18 @@ # tip(76) block(77) - tx77 = create_and_sign_tx(out[24].tx, out[24].n, 10*COIN) + tx77 = create_and_sign_tx(out[24].tx, out[24].n, 10 * COIN) update_block(77, [tx77]) yield accepted() save_spendable_output() block(78) - tx78 = create_tx(tx77, 0, 9*COIN) + tx78 = create_tx(tx77, 0, 9 * COIN) update_block(78, [tx78]) yield accepted() block(79) - tx79 = create_tx(tx78, 0, 8*COIN) + tx79 = create_tx(tx78, 0, 8 * COIN) update_block(79, [tx79]) yield accepted() @@ -1158,20 +1195,20 @@ save_spendable_output() block(81, spend=out[26]) - yield rejected() # other chain is same length + yield rejected() # other chain is same length save_spendable_output() block(82, spend=out[27]) yield accepted() # now this chain is longer, triggers re-org save_spendable_output() - # now check that tx78 and tx79 have been put back into the peer's mempool + # now check that tx78 and tx79 have been put back into the peer's + # mempool mempool = self.nodes[0].getrawmempool() assert_equal(len(mempool), 2) assert(tx78.hash in mempool) assert(tx79.hash in mempool) - # Test invalid opcodes in dead execution paths. # # -> b81 (26) -> b82 (27) -> b83 (28) @@ -1179,7 +1216,8 @@ b83 = block(83) op_codes = [OP_IF, OP_INVALIDOPCODE, OP_ELSE, OP_TRUE, OP_ENDIF] script = CScript(op_codes) - tx1 = create_and_sign_tx(out[28].tx, out[28].n, out[28].tx.vout[0].nValue, script) + tx1 = create_and_sign_tx( + out[28].tx, out[28].n, out[28].tx.vout[0].nValue, script) tx2 = create_and_sign_tx(tx1, 0, 0, CScript([OP_TRUE])) tx2.vin[0].scriptSig = CScript([OP_FALSE]) @@ -1189,7 +1227,6 @@ yield accepted() save_spendable_output() - # Reorg on/off blocks that have OP_RETURN in them (and try to spend them) # # -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31) @@ -1213,7 +1250,7 @@ tx4.vout.append(CTxOut(0, CScript([OP_RETURN]))) tx5 = create_tx(tx1, 4, 0, CScript([OP_RETURN])) - update_block(84, [tx1,tx2,tx3,tx4,tx5]) + update_block(84, [tx1, tx2, tx3, tx4, tx5]) yield accepted() save_spendable_output() @@ -1239,7 +1276,6 @@ update_block("89a", [tx]) yield rejected() - # Test re-org of a week's worth of blocks (1088 blocks) # This test takes a minute or two and can be accomplished in memory # @@ -1247,7 +1283,7 @@ tip(88) LARGE_REORG_SIZE = 1088 test1 = TestInstance(sync_every_block=False) - spend=out[32] + spend = out[32] for i in range(89, LARGE_REORG_SIZE + 89): b = block(i, spend) tx = CTransaction() @@ -1268,7 +1304,7 @@ tip(88) test2 = TestInstance(sync_every_block=False) for i in range(89, LARGE_REORG_SIZE + 89): - block("alt"+str(i)) + block("alt" + str(i)) test2.blocks_and_transactions.append([self.tip, False]) yield test2 @@ -1286,6 +1322,5 @@ chain1_tip += 2 - if __name__ == '__main__': FullBlockTest().main() diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -27,14 +27,16 @@ self.nodes = [] self.is_network_split = False - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"])) + self.nodes.append( + start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"])) self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] def run_test(self): utxo_count = 90 - utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], utxo_count) + utxos = create_confirmed_utxos( + self.relayfee, self.nodes[0], utxo_count) # our transactions are smaller than 100kb - base_fee = self.relayfee*100 + base_fee = self.relayfee * 100 txids = [] # Create 3 batches of transactions at 3 different fee rate levels @@ -43,7 +45,8 @@ 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], end_range - start_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 # LEGACY_MAX_BLOCK_SIZE -- otherwise the test needs to be revised to create @@ -60,7 +63,8 @@ # add a fee delta to something in the cheapest bucket and make sure it gets mined # also check that a different entry in the cheapest bucket is NOT mined (lower # the priority to ensure its not mined due to priority) - self.nodes[0].prioritisetransaction(txids[0][0], 0, int(3*base_fee*COIN)) + self.nodes[0].prioritisetransaction( + txids[0][0], 0, int(3 * base_fee * COIN)) self.nodes[0].prioritisetransaction(txids[0][1], -1e15, 0) self.nodes[0].generate(1) @@ -80,7 +84,8 @@ # Add a prioritisation before a tx is in the mempool (de-prioritising a # high-fee transaction so that it's now low fee). - self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN)) + self.nodes[0].prioritisetransaction( + high_fee_tx, -1e15, -int(2 * base_fee * COIN)) # Add everything back to mempool self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) @@ -111,26 +116,29 @@ inputs = [] outputs = {} - inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]}) + inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]}) outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) - tx_hex = self.nodes[0].signrawtransaction(raw_tx, None, None, "ALL")["hex"] + tx_hex = self.nodes[0].signrawtransaction( + raw_tx, None, None, "ALL")["hex"] txid = self.nodes[0].sendrawtransaction(tx_hex) # A tx that spends an in-mempool tx has 0 priority, so we can use it to - # test the effect of using prioritise transaction for mempool acceptance + # test the effect of using prioritise transaction for mempool + # acceptance inputs = [] inputs.append({"txid": txid, "vout": 0}) outputs = {} outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs) - tx2_hex = self.nodes[0].signrawtransaction(raw_tx2, None, None, "ALL")["hex"] + tx2_hex = self.nodes[0].signrawtransaction( + raw_tx2, None, None, "ALL")["hex"] tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"] try: self.nodes[0].sendrawtransaction(tx2_hex) except JSONRPCException as exp: - assert_equal(exp.error['code'], -26) # insufficient fee + assert_equal(exp.error['code'], -26) # insufficient fee assert(tx2_id not in self.nodes[0].getrawmempool()) else: assert(False) @@ -138,9 +146,11 @@ # This is a less than 1000-byte transaction, so just set the fee # to be the minimum for a 1000 byte transaction and check that it is # accepted. - self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN)) + self.nodes[0].prioritisetransaction( + tx2_id, 0, int(self.relayfee * COIN)) - print("Assert that prioritised free transaction is accepted to mempool") + print( + "Assert that prioritised free transaction is accepted to mempool") assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id) assert(tx2_id in self.nodes[0].getrawmempool()) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -16,6 +16,8 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: + + class RawTransactionsTest(BitcoinTestFramework): def __init__(self): @@ -26,52 +28,53 @@ def setup_network(self, split=False): self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) - #connect to a local machine for debugging - #url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18332) - #proxy = AuthServiceProxy(url) - #proxy.url = url # store URL on proxy for info - #self.nodes.append(proxy) + # connect to a local machine for debugging + # url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18332) + # proxy = AuthServiceProxy(url) + # proxy.url = url # store URL on proxy for info + # self.nodes.append(proxy) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + connect_nodes_bi(self.nodes, 0, 2) - self.is_network_split=False + self.is_network_split = False self.sync_all() def run_test(self): - #prepare some coins for multiple *rawtransaction commands + # prepare some coins for multiple *rawtransaction commands self.nodes[2].generate(1) self.sync_all() self.nodes[0].generate(101) self.sync_all() - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0) self.sync_all() self.nodes[0].generate(5) self.sync_all() - ######################################### + # # sendrawtransaction with missing input # - ######################################### - inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists - outputs = { self.nodes[0].getnewaddress() : 4.998 } - rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - rawtx = self.nodes[2].signrawtransaction(rawtx, None, None, "ALL") + # + inputs = [ + {'txid': "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout': 1}] + # won't exists + outputs = {self.nodes[0].getnewaddress(): 4.998} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + rawtx = self.nodes[2].signrawtransaction(rawtx, None, None, "ALL") try: - rawtx = self.nodes[2].sendrawtransaction(rawtx['hex']) + rawtx = self.nodes[2].sendrawtransaction(rawtx['hex']) except JSONRPCException as e: assert("Missing inputs" in e.error['message']) else: assert(False) - - ######################### + # # RAW TX MULTISIG TESTS # - ######################### + # # 2of2 test addr1 = self.nodes[2].getnewaddress() addr2 = self.nodes[2].getnewaddress() @@ -79,10 +82,11 @@ addr1Obj = self.nodes[2].validateaddress(addr1) addr2Obj = self.nodes[2].validateaddress(addr2) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + mSigObj = self.nodes[2].addmultisigaddress( + 2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) mSigObjValid = self.nodes[2].validateaddress(mSigObj) - #use balance deltas instead of absolute values + # use balance deltas instead of absolute values bal = self.nodes[2].getbalance() # send 1.2 BTC to msig adr @@ -90,8 +94,9 @@ self.sync_all() self.nodes[0].generate(1) self.sync_all() - assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance - + assert_equal(self.nodes[2].getbalance(), bal + Decimal('1.20000000')) + # node2 has both keys of the 2of2 ms addr., tx should + # affect the balance # 2of3 test from different nodes bal = self.nodes[2].getbalance() @@ -103,7 +108,8 @@ addr2Obj = self.nodes[2].validateaddress(addr2) addr3Obj = self.nodes[2].validateaddress(addr3) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) + mSigObj = self.nodes[2].addmultisigaddress( + 2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) mSigObjValid = self.nodes[2].validateaddress(mSigObj) txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) @@ -114,9 +120,12 @@ self.nodes[0].generate(1) self.sync_all() - #THIS IS A INCOMPLETE FEATURE - #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION - assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable + # THIS IS A INCOMPLETE FEATURE + # NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND + # COUNT AT BALANCE CALCULATION + assert_equal(self.nodes[2].getbalance(), bal) + # for now, assume the funds of a 2of3 multisig tx are not + # marked as spendable txDetails = self.nodes[0].gettransaction(txId, True) rawTx = self.nodes[0].decoderawtransaction(txDetails['hex']) @@ -127,14 +136,17 @@ break bal = self.nodes[0].getbalance() - inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}] - outputs = { self.nodes[0].getnewaddress() : 2.19 } + inputs = [ + {"txid": txId, "vout": vout['n'], "scriptPubKey": vout['scriptPubKey']['hex']}] + outputs = {self.nodes[0].getnewaddress(): 2.19} rawTx = self.nodes[2].createrawtransaction(inputs, outputs) - rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs, None, "ALL") + rawTxPartialSigned = self.nodes[ + 1].signrawtransaction(rawTx, inputs, None, "ALL") # node1 only has one key, can't comp. sign the tx assert_equal(rawTxPartialSigned['complete'], False) - - rawTxSigned = self.nodes[2].signrawtransaction(rawTx, inputs, None, "ALL") + + rawTxSigned = self.nodes[2].signrawtransaction( + rawTx, inputs, None, "ALL") # node2 can sign the tx compl., own two of three keys assert_equal(rawTxSigned['complete'], True) self.nodes[2].sendrawtransaction(rawTxSigned['hex']) @@ -142,53 +154,69 @@ self.sync_all() self.nodes[0].generate(1) self.sync_all() - assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx + assert_equal(self.nodes[0].getbalance(), bal + Decimal( + '50.00000000') + Decimal('2.19000000')) # block reward + tx # getrawtransaction tests # 1. valid parameters - only supply txid txHash = rawTx["hash"] - assert_equal(self.nodes[0].getrawtransaction(txHash), rawTxSigned['hex']) + assert_equal( + self.nodes[0].getrawtransaction(txHash), rawTxSigned['hex']) # 2. valid parameters - supply txid and 0 for non-verbose - assert_equal(self.nodes[0].getrawtransaction(txHash, 0), rawTxSigned['hex']) + assert_equal( + self.nodes[0].getrawtransaction(txHash, 0), rawTxSigned['hex']) # 3. valid parameters - supply txid and False for non-verbose - assert_equal(self.nodes[0].getrawtransaction(txHash, False), rawTxSigned['hex']) + assert_equal(self.nodes[0].getrawtransaction( + txHash, False), rawTxSigned['hex']) # 4. valid parameters - supply txid and 1 for verbose. - # We only check the "hex" field of the output so we don't need to update this test every time the output format changes. - assert_equal(self.nodes[0].getrawtransaction(txHash, 1)["hex"], rawTxSigned['hex']) + # We only check the "hex" field of the output so we don't need to + # update this test every time the output format changes. + assert_equal(self.nodes[0].getrawtransaction( + txHash, 1)["hex"], rawTxSigned['hex']) # 5. valid parameters - supply txid and True for non-verbose - assert_equal(self.nodes[0].getrawtransaction(txHash, True)["hex"], rawTxSigned['hex']) + assert_equal(self.nodes[0].getrawtransaction( + txHash, True)["hex"], rawTxSigned['hex']) # 6. invalid parameters - supply txid and string "Flase" - assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, txHash, "Flase") + assert_raises(JSONRPCException, self.nodes[ + 0].getrawtransaction, txHash, "Flase") # 7. invalid parameters - supply txid and empty array - assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, txHash, []) + assert_raises( + JSONRPCException, self.nodes[0].getrawtransaction, txHash, []) # 8. invalid parameters - supply txid and empty dict - assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, txHash, {}) - - inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}] - outputs = { self.nodes[0].getnewaddress() : 1 } - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - decrawtx= self.nodes[0].decoderawtransaction(rawtx) + assert_raises( + JSONRPCException, self.nodes[0].getrawtransaction, txHash, {}) + + inputs = [ + {'txid': "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout': 1, 'sequence': 1000}] + outputs = {self.nodes[0].getnewaddress(): 1} + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx = self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['vin'][0]['sequence'], 1000) - - inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : -1}] - outputs = { self.nodes[0].getnewaddress() : 1 } - assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) - - inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967296}] - outputs = { self.nodes[0].getnewaddress() : 1 } - assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) - - inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967294}] - outputs = { self.nodes[0].getnewaddress() : 1 } - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - decrawtx= self.nodes[0].decoderawtransaction(rawtx) + + inputs = [ + {'txid': "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout': 1, 'sequence': -1}] + outputs = {self.nodes[0].getnewaddress(): 1} + assert_raises(JSONRPCException, self.nodes[ + 0].createrawtransaction, inputs, outputs) + + inputs = [ + {'txid': "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout': 1, 'sequence': 4294967296}] + outputs = {self.nodes[0].getnewaddress(): 1} + assert_raises(JSONRPCException, self.nodes[ + 0].createrawtransaction, inputs, outputs) + + inputs = [ + {'txid': "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout': 1, 'sequence': 4294967294}] + outputs = {self.nodes[0].getnewaddress(): 1} + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx = self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['vin'][0]['sequence'], 4294967294) if __name__ == '__main__': diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -6,6 +6,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * + class WalletTest (BitcoinTestFramework): def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size): @@ -18,17 +19,18 @@ super().__init__() self.setup_clean_chain = True self.num_nodes = 4 - self.extra_args = [['-usehd={:d}'.format(i%2==0)] for i in range(4)] + self.extra_args = [['-usehd={:d}'.format(i % 2 == 0)] + for i in range(4)] def setup_network(self, split=False): self.nodes = start_nodes(3, self.options.tmpdir, self.extra_args[:3]) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) - self.is_network_split=False + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False self.sync_all() - def run_test (self): + def run_test(self): # Check that there's no UTXO on none of the nodes assert_equal(len(self.nodes[0].listunspent()), 0) @@ -71,7 +73,8 @@ unspent_0 = self.nodes[2].listunspent()[0] unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} self.nodes[2].lockunspent(False, [unspent_0]) - assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) + assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[ + 2].sendtoaddress, self.nodes[2].getnewaddress(), 20) assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) @@ -82,7 +85,7 @@ # node0 should end up with 100 btc in block rewards plus fees, but # minus the 21 plus fees sent to node2 - assert_equal(self.nodes[0].getbalance(), 100-21) + assert_equal(self.nodes[0].getbalance(), 100 - 21) assert_equal(self.nodes[2].getbalance(), 21) # Node0 should have two unspent outputs. @@ -96,10 +99,11 @@ for utxo in node0utxos: inputs = [] outputs = {} - inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) + inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]}) outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3 raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) - txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx, None, None, "ALL")) + txns_to_send.append( + self.nodes[0].signrawtransaction(raw_tx, None, None, "ALL")) # Have node 1 (miner) send the transactions self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True) @@ -111,7 +115,7 @@ assert_equal(self.nodes[0].getbalance(), 0) assert_equal(self.nodes[2].getbalance(), 94) - assert_equal(self.nodes[2].getbalance("from1"), 94-21) + assert_equal(self.nodes[2].getbalance("from1"), 94 - 21) # Send 10 BTC normal address = self.nodes[0].getnewaddress("test") @@ -120,7 +124,8 @@ txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) self.nodes[2].generate(1) self.sync_all() - node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal( + '84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), Decimal('10')) # Send 10 BTC with subtract fee from amount @@ -129,14 +134,16 @@ self.sync_all() node_2_bal -= Decimal('10') assert_equal(self.nodes[2].getbalance(), node_2_bal) - node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal( + '20'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) # Sendmany 10 BTC txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", []) self.nodes[2].generate(1) self.sync_all() node_0_bal += Decimal('10') - node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal( + '10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), node_0_bal) # Sendmany 10 BTC with subtract fee from amount @@ -145,7 +152,8 @@ self.sync_all() node_2_bal -= Decimal('10') assert_equal(self.nodes[2].getbalance(), node_2_bal) - node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal( + '10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) # Test ResendWalletTransactions: # Create a couple of transactions, then start up a fourth @@ -155,7 +163,8 @@ txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) sync_mempools(self.nodes) - self.nodes.append(start_node(3, self.options.tmpdir, self.extra_args[3])) + self.nodes.append( + start_node(3, self.options.tmpdir, self.extra_args[3])) connect_nodes_bi(self.nodes, 0, 3) sync_blocks(self.nodes) @@ -169,27 +178,31 @@ assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1) assert_equal(self.nodes[0].getunconfirmedbalance(), 1) - #check if we can list zero value tx as available coins - #1. create rawtx - #2. hex-changed one output to 0.0 - #3. sign and send - #4. check if recipient (node0) can list the zero value tx + # check if we can list zero value tx as available coins + # 1. create rawtx + # 2. hex-changed one output to 0.0 + # 3. sign and send + # 4. check if recipient (node0) can list the zero value tx usp = self.nodes[1].listunspent() - inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}] - outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11} + inputs = [{"txid": usp[0]['txid'], "vout":usp[0]['vout']}] + outputs = { + self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11} - rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32) + rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace( + "c0833842", "00000000") # replace 11.11 with 0.0 (int32) decRawTx = self.nodes[1].decoderawtransaction(rawTx) - signedRawTx = self.nodes[1].signrawtransaction(rawTx, None, None, "ALL") + signedRawTx = self.nodes[ + 1].signrawtransaction(rawTx, None, None, "ALL") decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex']) - zeroValueTxid= decRawTx['txid'] + zeroValueTxid = decRawTx['txid'] sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex']) self.sync_all() - self.nodes[1].generate(1) #mine a block + self.nodes[1].generate(1) # mine a block self.sync_all() - unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output + unspentTxs = self.nodes[ + 0].listunspent() # zero value tx must be in listunspents output found = False for uTx in unspentTxs: if uTx['txid'] == zeroValueTxid: @@ -197,21 +210,25 @@ assert_equal(uTx['amount'], Decimal('0')) assert(found) - #do some -walletbroadcast tests + # do some -walletbroadcast tests stop_nodes(self.nodes) - self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]]) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) + self.nodes = start_nodes(3, self.options.tmpdir, [ + ["-walletbroadcast=0"], ["-walletbroadcast=0"], ["-walletbroadcast=0"]]) + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + connect_nodes_bi(self.nodes, 0, 2) self.sync_all() - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) + txIdNotBroadcasted = self.nodes[0].sendtoaddress( + self.nodes[2].getnewaddress(), 2) txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) - self.nodes[1].generate(1) #mine a block, tx should not be in there + self.nodes[1].generate(1) # mine a block, tx should not be in there self.sync_all() - assert_equal(self.nodes[2].getbalance(), node_2_bal) #should not be changed because tx was not broadcasted + assert_equal(self.nodes[2].getbalance(), node_2_bal) + # should not be changed because tx was not broadcasted - #now broadcast from another node, mine a block, sync, and check the balance + # now broadcast from another node, mine a block, sync, and check the + # balance self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) self.nodes[1].generate(1) self.sync_all() @@ -219,46 +236,50 @@ txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) assert_equal(self.nodes[2].getbalance(), node_2_bal) - #create another tx - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) + # create another tx + txIdNotBroadcasted = self.nodes[0].sendtoaddress( + self.nodes[2].getnewaddress(), 2) - #restart the nodes with -walletbroadcast=1 + # restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) self.nodes = start_nodes(3, self.options.tmpdir) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + connect_nodes_bi(self.nodes, 0, 2) sync_blocks(self.nodes) self.nodes[0].generate(1) sync_blocks(self.nodes) node_2_bal += 2 - #tx should be added to balance because after restarting the nodes tx should be broadcastet + # tx should be added to balance because after restarting the nodes tx + # should be broadcastet assert_equal(self.nodes[2].getbalance(), node_2_bal) - #send a tx with value in a string (PR#6380 +) - txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") + # send a tx with value in a string (PR#6380 +) + txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-2')) - txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001") + txId = self.nodes[0].sendtoaddress( + self.nodes[2].getnewaddress(), "0.0001") txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) - #check if JSON parser can handle scientific notation in strings - txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4") + # check if JSON parser can handle scientific notation in strings + txId = self.nodes[0].sendtoaddress( + self.nodes[2].getnewaddress(), "1e-4") txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) try: - txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") + txId = self.nodes[0].sendtoaddress( + self.nodes[2].getnewaddress(), "1f-4") except JSONRPCException as e: assert("Invalid amount" in e.error['message']) else: raise AssertionError("Must not parse invalid amounts") - try: self.nodes[0].generate("2") raise AssertionError("Must not accept strings as numeric") @@ -280,8 +301,8 @@ # 4. Check that the unspents after import are not spendable assert_array_result(self.nodes[1].listunspent(), - {"address": address_to_import}, - {"spendable": False}) + {"address": address_to_import}, + {"spendable": False}) # 5. Import private key of the previously imported address on node1 priv_key = self.nodes[2].dumpprivkey(address_to_import) @@ -289,8 +310,8 @@ # 6. Check that the unspents are now spendable on node1 assert_array_result(self.nodes[1].listunspent(), - {"address": address_to_import}, - {"spendable": True}) + {"address": address_to_import}, + {"spendable": True}) # Mine a block from node0 to an address from node1 cbAddr = self.nodes[1].getnewaddress() @@ -313,13 +334,14 @@ # - False: unicode directly as UTF-8 for mode in [True, False]: self.nodes[0].ensure_ascii = mode - # unicode check: Basic Multilingual Plane, Supplementary Plane respectively + # unicode check: Basic Multilingual Plane, Supplementary Plane + # respectively for s in [u'рыба', u'𝅘𝅥𝅯']: addr = self.nodes[0].getaccountaddress(s) label = self.nodes[0].getaccount(addr) assert_equal(label, s) assert(s in self.nodes[0].listaccounts().keys()) - self.nodes[0].ensure_ascii = True # restore to default + self.nodes[0].ensure_ascii = True # restore to default # maintenance tests maintenance = [ @@ -335,28 +357,34 @@ print("check " + m) stop_nodes(self.nodes) # set lower ancestor limit for later - self.nodes = start_nodes(3, self.options.tmpdir, [[m, "-limitancestorcount="+str(chainlimit)]] * 3) + self.nodes = start_nodes(3, self.options.tmpdir, [ + [m, "-limitancestorcount=" + str(chainlimit)]] * 3) while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: # reindex will leave rpc warm up "early"; Wait for it to finish time.sleep(0.1) - assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) + assert_equal( + balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) # Exercise listsinceblock with the last two blocks coinbase_tx_1 = self.nodes[0].listsinceblock(blocks[0]) assert_equal(coinbase_tx_1["lastblock"], blocks[1]) assert_equal(len(coinbase_tx_1["transactions"]), 1) assert_equal(coinbase_tx_1["transactions"][0]["blockhash"], blocks[1]) - assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) + assert_equal( + len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) - # ==Check that wallet prefers to use coins that don't exceed mempool limits ===== + # ==Check that wallet prefers to use coins that don't exceed mempool li # Get all non-zero utxos together - chain_addrs = [self.nodes[0].getnewaddress(), self.nodes[0].getnewaddress()] - singletxid = self.nodes[0].sendtoaddress(chain_addrs[0], self.nodes[0].getbalance(), "", "", True) + chain_addrs = [ + self.nodes[0].getnewaddress(), self.nodes[0].getnewaddress()] + singletxid = self.nodes[0].sendtoaddress( + chain_addrs[0], self.nodes[0].getbalance(), "", "", True) self.nodes[0].generate(1) node0_balance = self.nodes[0].getbalance() # Split into two chains - rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')}) + rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], { + chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')}) signedtx = self.nodes[0].signrawtransaction(rawtx, None, None, "ALL") singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) self.nodes[0].generate(1) @@ -364,40 +392,49 @@ # Make a long chain of unconfirmed payments without hitting mempool limit # Each tx we make leaves only one output of change on a chain 1 longer # Since the amount to send is always much less than the outputs, we only ever need one output - # So we should be able to generate exactly chainlimit txs for each original output + # So we should be able to generate exactly chainlimit txs for each + # original output sending_addr = self.nodes[1].getnewaddress() txid_list = [] - for i in range(chainlimit*2): - txid_list.append(self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001'))) - assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit*2) - assert_equal(len(txid_list), chainlimit*2) + for i in range(chainlimit * 2): + txid_list.append( + self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001'))) + assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit * 2) + assert_equal(len(txid_list), chainlimit * 2) # Without walletrejectlongchains, we will still generate a txid # The tx will be stored in the wallet but not accepted to the mempool - extra_txid = self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001')) + extra_txid = self.nodes[0].sendtoaddress( + sending_addr, Decimal('0.0001')) assert(extra_txid not in self.nodes[0].getrawmempool()) - assert(extra_txid in [tx["txid"] for tx in self.nodes[0].listtransactions()]) + assert(extra_txid in [tx["txid"] + for tx in self.nodes[0].listtransactions()]) self.nodes[0].abandontransaction(extra_txid) - total_txs = len(self.nodes[0].listtransactions("*",99999)) + total_txs = len(self.nodes[0].listtransactions("*", 99999)) # Try with walletrejectlongchains - # Double chain limit but require combining inputs, so we pass SelectCoinsMinConf - stop_node(self.nodes[0],0) - self.nodes[0] = start_node(0, self.options.tmpdir, ["-walletrejectlongchains", "-limitancestorcount="+str(2*chainlimit)]) + # Double chain limit but require combining inputs, so we pass + # SelectCoinsMinConf + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, [ + "-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)]) # wait for loadmempool timeout = 10 - while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit*2): + while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit * 2): time.sleep(0.5) timeout -= 0.5 - assert_equal(len(self.nodes[0].getrawmempool()), chainlimit*2) + assert_equal(len(self.nodes[0].getrawmempool()), chainlimit * 2) node0_balance = self.nodes[0].getbalance() - # With walletrejectlongchains we will not create the tx and store it in our wallet. - assert_raises_message(JSONRPCException, "mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) + # With walletrejectlongchains we will not create the tx and store it in + # our wallet. + assert_raises_message(JSONRPCException, "mempool chain", self.nodes[ + 0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) # Verify nothing new in wallet - assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999))) + assert_equal( + total_txs, len(self.nodes[0].listtransactions("*", 99999))) if __name__ == '__main__': WalletTest().main()