diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index b1f3ea294ac25..6b491b9dac833 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -78,6 +78,7 @@ def test_disable_flag(self): sequence_value = SEQUENCE_LOCKTIME_DISABLE_FLAG | 1 tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)] tx1.vout = [CTxOut(value, CScript([b'a']))] + tx1.vout.append(CTxOut(int(self.relayfee*COIN))) tx1_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(tx1))["hex"] tx1_id = self.nodes[0].sendrawtransaction(tx1_signed) @@ -90,6 +91,7 @@ def test_disable_flag(self): 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' * 35]))] + tx2.vout.append(CTxOut(int(self.relayfee*COIN))) tx2.rehash() assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx2)) @@ -185,6 +187,7 @@ def test_sequence_lock_confirmed_inputs(self): # 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']))) + tx.vout.append(CTxOut(int(self.relayfee*tx_size*COIN/1000))) rawtx = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))["hex"] if (using_sequence_locks and not should_pass): diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index ce764ff7e279d..6f10587169342 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -6,10 +6,12 @@ from decimal import Decimal -from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut +from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut, CTxOutValue from test_framework.script import CScript, OP_DROP from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_raises_rpc_error, bytes_to_hex_str, satoshi_round, BITCOIN_ASSET +from test_framework.util import assert_equal, assert_raises_rpc_error, bytes_to_hex_str, hex_str_to_bytes, satoshi_round, BITCOIN_ASSET + +from io import BytesIO MAX_REPLACEMENT_LIMIT = 100 @@ -29,9 +31,9 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): node.generate(100) new_addr = node.getnewaddress() - txid = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN)) - tx1 = node.getrawtransaction(txid, 1) - txid = int(txid, 16) + txidstr = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN)) + tx1 = node.getrawtransaction(txidstr, 1) + txid = int(txidstr, 16) i = None for i, txout in enumerate(tx1['vout']): @@ -41,7 +43,10 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): tx2 = CTransaction() tx2.vin = [CTxIn(COutPoint(txid, i))] - tx2.vout = [CTxOut(amount, scriptPubKey)] + tx1raw = CTransaction() + tx1raw.deserialize(BytesIO(hex_str_to_bytes(node.getrawtransaction(txidstr)))) + feeout = CTxOut(CTxOutValue(tx1raw.vout[i].nValue.getAmount() - amount)) + tx2.vout = [CTxOut(amount, scriptPubKey), feeout] tx2.rehash() signed_tx = node.signrawtransactionwithwallet(txToHex(tx2)) @@ -132,9 +137,10 @@ def test_simple_doublespend(self): # transactions might not be accepted by our peers. self.sync_all() + feeout = CTxOut(int(0.1*COIN), CScript()) tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), feeout] tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) @@ -143,7 +149,7 @@ def test_simple_doublespend(self): # Should fail because we haven't changed the fee tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(1 * COIN, CScript([b'b' * 35]))] + tx1b.vout = [CTxOut(1 * COIN, CScript([b'b' * 35])), feeout] tx1b_hex = txToHex(tx1b) # This will raise an exception due to insufficient fee @@ -154,7 +160,7 @@ def test_simple_doublespend(self): # Extra 0.1 BTC fee tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(int(0.9 * COIN), CScript([b'b' * 35]))] + tx1b.vout = [CTxOut(int(0.9 * COIN), CScript([b'b' * 35])), feeout, feeout] tx1b_hex = txToHex(tx1b) # Replacement still disabled even with "enough fee" assert_raises_rpc_error(-26, "txn-mempool-conflict", self.nodes[1].sendrawtransaction, tx1b_hex, True) @@ -186,7 +192,8 @@ def test_doublespend_chain(self): remaining_value -= 1*COIN tx = CTransaction() tx.vin = [CTxIn(prevout, nSequence=0)] - tx.vout = [CTxOut(remaining_value, CScript([1, OP_DROP] * 15 + [1]))] + feeout = CTxOut(1*COIN) + tx.vout = [CTxOut(remaining_value, CScript([1, OP_DROP] * 15 + [1])), feeout] tx_hex = txToHex(tx) txid = self.nodes[0].sendrawtransaction(tx_hex, True) chain_txids.append(txid) @@ -196,7 +203,7 @@ def test_doublespend_chain(self): # child fees - 40 BTC - so this attempt is rejected. dbl_tx = CTransaction() dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] - dbl_tx.vout = [CTxOut(initial_nValue - 30 * COIN, CScript([1] * 35))] + dbl_tx.vout = [CTxOut(initial_nValue - 30 * COIN, CScript([1] * 35)), CTxOut(30*COIN)] dbl_tx_hex = txToHex(dbl_tx) # This will raise an exception due to insufficient fee @@ -205,7 +212,7 @@ def test_doublespend_chain(self): # Accepted with sufficient fee dbl_tx = CTransaction() dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] - dbl_tx.vout = [CTxOut(1 * COIN, CScript([1] * 35))] + dbl_tx.vout = [CTxOut(1 * COIN, CScript([1] * 35)), CTxOut(49*COIN)] dbl_tx_hex = txToHex(dbl_tx) self.nodes[0].sendrawtransaction(dbl_tx_hex, True) @@ -231,6 +238,7 @@ def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _tota vout = [CTxOut(txout_value, CScript([i+1])) for i in range(tree_width)] + vout.append(CTxOut(int(initial_value - tree_width*txout_value))) tx = CTransaction() tx.vin = [CTxIn(prevout, nSequence=0)] tx.vout = vout @@ -244,6 +252,8 @@ def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _tota txid = int(txid, 16) for i, txout in enumerate(tx.vout): + if txout.is_fee(): + continue for x in branch(COutPoint(txid, i), txout_value, max_txs, tree_width=tree_width, fee=fee, @@ -258,7 +268,7 @@ def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _tota # Attempt double-spend, will fail because too little fee paid dbl_tx = CTransaction() dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] - dbl_tx.vout = [CTxOut(initial_nValue - fee * n, CScript([1] * 35))] + dbl_tx.vout = [CTxOut(initial_nValue - fee * n, CScript([1] * 35)), CTxOut(fee*n)] dbl_tx_hex = txToHex(dbl_tx) # This will raise an exception due to insufficient fee assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, dbl_tx_hex, True) @@ -266,7 +276,7 @@ def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _tota # 1 BTC fee is enough dbl_tx = CTransaction() dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] - dbl_tx.vout = [CTxOut(initial_nValue - fee * n - 1 * COIN, CScript([1] * 35))] + dbl_tx.vout = [CTxOut(initial_nValue - fee * n - 1 * COIN, CScript([1] * 35)), CTxOut(fee*n+1*COIN)] dbl_tx_hex = txToHex(dbl_tx) self.nodes[0].sendrawtransaction(dbl_tx_hex, True) @@ -286,7 +296,7 @@ def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _tota dbl_tx = CTransaction() dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] - dbl_tx.vout = [CTxOut(initial_nValue - 2 * fee * n, CScript([1] * 35))] + dbl_tx.vout = [CTxOut(initial_nValue - 2 * fee * n, CScript([1] * 35)), CTxOut(2*fee*n)] dbl_tx_hex = txToHex(dbl_tx) # This will raise an exception assert_raises_rpc_error(-26, "too many potential replacements", self.nodes[0].sendrawtransaction, dbl_tx_hex, True) @@ -301,7 +311,7 @@ def test_replacement_feeperkb(self): tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx1a_hex = txToHex(tx1a) self.nodes[0].sendrawtransaction(tx1a_hex, True) @@ -309,7 +319,7 @@ def test_replacement_feeperkb(self): # rejected. tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))] + tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000])), CTxOut(int(1.1*COIN-0.001*COIN))] tx1b_hex = txToHex(tx1b) # This will raise an exception due to insufficient fee @@ -322,7 +332,7 @@ def test_spends_of_conflicting_outputs(self): tx1a = CTransaction() tx1a.vin = [CTxIn(utxo1, nSequence=0)] - tx1a.vout = [CTxOut(int(1.1 * COIN), CScript([b'a' * 35]))] + tx1a.vout = [CTxOut(int(1.1 * COIN), CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) @@ -332,7 +342,7 @@ def test_spends_of_conflicting_outputs(self): tx2 = CTransaction() tx2.vin = [CTxIn(utxo1, nSequence=0), CTxIn(utxo2, nSequence=0)] tx2.vin.append(CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)) - tx2.vout = tx1a.vout + tx2.vout = tx1a.vout + [CTxOut(3*COIN + int(1.1*COIN))] tx2_hex = txToHex(tx2) # This will raise an exception @@ -341,7 +351,7 @@ def test_spends_of_conflicting_outputs(self): # Spend tx1a's output to test the indirect case. tx1b = CTransaction() tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] - tx1b.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx1b.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx1b_hex = txToHex(tx1b) tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) tx1b_txid = int(tx1b_txid, 16) @@ -349,7 +359,7 @@ def test_spends_of_conflicting_outputs(self): tx2 = CTransaction() tx2.vin = [CTxIn(utxo1, nSequence=0), CTxIn(utxo2, nSequence=0), CTxIn(COutPoint(tx1b_txid, 0))] - tx2.vout = tx1a.vout + tx2.vout = tx1a.vout + [CTxOut(3*COIN + int(1.0*COIN))] tx2_hex = txToHex(tx2) # This will raise an exception @@ -362,13 +372,13 @@ def test_new_unconfirmed_inputs(self): tx1 = CTransaction() tx1.vin = [CTxIn(confirmed_utxo)] - tx1.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx1.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx1_hex = txToHex(tx1) self.nodes[0].sendrawtransaction(tx1_hex, True) tx2 = CTransaction() tx2.vin = [CTxIn(confirmed_utxo), CTxIn(unconfirmed_utxo)] - tx2.vout = tx1.vout + tx2.vout = tx1.vout + [CTxOut(int(0.1*COIN))] tx2_hex = txToHex(tx2) # This will raise an exception @@ -391,7 +401,7 @@ def test_too_many_replacements(self): splitting_tx = CTransaction() splitting_tx.vin = [CTxIn(utxo, nSequence=0)] - splitting_tx.vout = outputs + splitting_tx.vout = outputs + [CTxOut(int(initial_nValue - (MAX_REPLACEMENT_LIMIT+1) * split_value))] splitting_tx_hex = txToHex(splitting_tx) txid = self.nodes[0].sendrawtransaction(splitting_tx_hex, True) @@ -401,7 +411,7 @@ def test_too_many_replacements(self): for i in range(MAX_REPLACEMENT_LIMIT+1): tx_i = CTransaction() tx_i.vin = [CTxIn(COutPoint(txid, i), nSequence=0)] - tx_i.vout = [CTxOut(split_value - fee, CScript([b'a' * 35]))] + tx_i.vout = [CTxOut(split_value - fee, CScript([b'a' * 35])), CTxOut(fee)] tx_i_hex = txToHex(tx_i) self.nodes[0].sendrawtransaction(tx_i_hex, True) @@ -414,7 +424,7 @@ def test_too_many_replacements(self): inputs.append(CTxIn(COutPoint(txid, i), nSequence=0)) double_tx = CTransaction() double_tx.vin = inputs - double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))] + double_tx.vout = [CTxOut(double_spend_value, CScript([b'a'])), CTxOut(int(split_value*(MAX_REPLACEMENT_LIMIT+1)-double_spend_value))] double_tx_hex = txToHex(double_tx) # This will raise an exception @@ -423,7 +433,7 @@ def test_too_many_replacements(self): # If we remove an input, it should pass double_tx = CTransaction() double_tx.vin = inputs[0:-1] - double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))] + double_tx.vout = [CTxOut(double_spend_value, CScript([b'a'])), CTxOut(int(split_value*(MAX_REPLACEMENT_LIMIT)-double_spend_value))] double_tx_hex = txToHex(double_tx) self.nodes[0].sendrawtransaction(double_tx_hex, True) @@ -434,7 +444,7 @@ def test_opt_in(self): # Create a non-opting in transaction tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0xffffffff)] - tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) @@ -455,7 +465,7 @@ def test_opt_in(self): # Create a different non-opting in transaction tx2a = CTransaction() tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0xfffffffe)] - tx2a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx2a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx2a_hex = txToHex(tx2a) tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True) @@ -479,6 +489,7 @@ def test_opt_in(self): tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff), CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)] tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))] + tx3a.vout.append(CTxOut(int(0.2*COIN))) tx3a_hex = txToHex(tx3a) tx3a_txid = self.nodes[0].sendrawtransaction(tx3a_hex, True) @@ -488,12 +499,12 @@ def test_opt_in(self): tx3b = CTransaction() tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] - tx3b.vout = [CTxOut(int(0.5 * COIN), CScript([b'e' * 35]))] + tx3b.vout = [CTxOut(int(0.5 * COIN), CScript([b'e' * 35])), CTxOut(int(0.5*COIN))] tx3b_hex = txToHex(tx3b) tx3c = CTransaction() tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)] - tx3c.vout = [CTxOut(int(0.5 * COIN), CScript([b'f' * 35]))] + tx3c.vout = [CTxOut(int(0.5 * COIN), CScript([b'f' * 35])), CTxOut(int(0.5*COIN))] tx3c_hex = txToHex(tx3c) self.nodes[0].sendrawtransaction(tx3b_hex, True) @@ -510,14 +521,14 @@ def test_prioritised_transactions(self): tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx1a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) # Higher fee, but the actual fee per KB is much lower. tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))] + tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000])), CTxOut(int(1.1*COIN-0.001*COIN))] tx1b_hex = txToHex(tx1b) # Verify tx1b cannot replace tx1a. @@ -536,14 +547,14 @@ def test_prioritised_transactions(self): tx2a = CTransaction() tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)] - tx2a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35]))] + tx2a.vout = [CTxOut(1 * COIN, CScript([b'a' * 35])), CTxOut(int(0.1*COIN))] tx2a_hex = txToHex(tx2a) self.nodes[0].sendrawtransaction(tx2a_hex, True) # Lower fee, but we'll prioritise it tx2b = CTransaction() tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] - tx2b.vout = [CTxOut(int(1.01 * COIN), CScript([b'a' * 35]))] + tx2b.vout = [CTxOut(int(1.01 * COIN), CScript([b'a' * 35])), CTxOut(int(1.1*COIN-1.01*COIN))] tx2b.rehash() tx2b_hex = txToHex(tx2b) @@ -562,6 +573,7 @@ def test_rpc(self): us0 = self.nodes[0].listunspent()[0] ins = [us0] outs = {self.nodes[0].getnewaddress() : Decimal(1.0000000)} + outs["fee"] = us0["amount"] - Decimal(1.0000000) rawtx0 = self.nodes[0].createrawtransaction(ins, outs, 0, True) rawtx1 = self.nodes[0].createrawtransaction(ins, outs, 0, False) json0 = self.nodes[0].decoderawtransaction(rawtx0) diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py index ec1067a4c886f..4dba63b07cc67 100755 --- a/test/functional/feature_segwit.py +++ b/test/functional/feature_segwit.py @@ -17,7 +17,7 @@ ) from test_framework.blocktools import witness_script, send_to_witness from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut, FromHex, sha256, ToHex -from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, OP_TRUE, OP_DROP +from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, OP_TRUE, OP_DROP, OP_RETURN from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, assert_raises_rpc_error, bytes_to_hex_str, connect_nodes, hex_str_to_bytes, sync_blocks, try_rpc, BITCOIN_ASSET @@ -229,6 +229,7 @@ def run_test(self): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(int(txid1, 16), 0), b'')) tx.vout.append(CTxOut(int(49.99 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) + tx.vout.append(CTxOut(int(49.996*COIN - 49.99*COIN))) tx2_hex = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))['hex'] txid2 = self.nodes[0].sendrawtransaction(tx2_hex) tx = FromHex(CTransaction(), tx2_hex) @@ -238,6 +239,7 @@ def run_test(self): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b"")) tx.vout.append(CTxOut(int(49.95 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee + tx.vout.append(CTxOut(int(49.99*COIN - 49.95*COIN))) tx.calc_sha256() txid3 = self.nodes[0].sendrawtransaction(ToHex(tx)) assert(tx.wit.is_null()) @@ -587,8 +589,11 @@ def mine_and_test_listunspent(self, script_list, ismine): utxo = find_spendable_utxo(self.nodes[0], 50) tx = CTransaction() tx.vin.append(CTxIn(COutPoint(int('0x'+utxo['txid'],0), utxo['vout']))) + remaining = 50*COIN for i in script_list: tx.vout.append(CTxOut(10000000, i)) + remaining -= 10000000 + tx.vout.append(CTxOut(remaining)) tx.rehash() signresults = self.nodes[0].signrawtransactionwithwallet(bytes_to_hex_str(tx.serialize_without_witness()))['hex'] txid = self.nodes[0].sendrawtransaction(signresults, True) @@ -633,14 +638,19 @@ def p2pkh_address_to_script(self,v): def create_and_mine_tx_from_txids(self, txids, success = True): tx = CTransaction() + total_in = 0 for i in txids: txtmp = CTransaction() txraw = self.nodes[0].getrawtransaction(i) f = BytesIO(hex_str_to_bytes(txraw)) txtmp.deserialize(f) for j in range(len(txtmp.vout)): + if txtmp.vout[j].is_fee(): + continue + total_in += txtmp.vout[j].nValue.getAmount() tx.vin.append(CTxIn(COutPoint(int('0x'+i,0), j))) - tx.vout.append(CTxOut(0, CScript())) + tx.vout.append(CTxOut(0, CScript([OP_RETURN]))) + tx.vout.append(CTxOut(total_in)) tx.rehash() signresults = self.nodes[0].signrawtransactionwithwallet(bytes_to_hex_str(tx.serialize_without_witness()))['hex'] self.nodes[0].sendrawtransaction(signresults, True) diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py index c0918893cdc9a..ea30d7edfb314 100755 --- a/test/functional/mempool_limit.py +++ b/test/functional/mempool_limit.py @@ -32,7 +32,7 @@ def run_test(self): self.log.info('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} + outputs = {self.nodes[0].getnewaddress() : 0.0001, "fee": us0["amount"] - Decimal('0.0001')} tx = self.nodes[0].createrawtransaction(inputs, outputs) self.nodes[0].settxfee(relayfee) # specifically fund this tx with low fee txF = self.nodes[0].fundrawtransaction(tx) @@ -58,7 +58,7 @@ def run_test(self): self.log.info('Create a mempool tx that will not pass mempoolminfee') us0 = utxos.pop() inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] - outputs = {self.nodes[0].getnewaddress() : 0.0001} + outputs = {self.nodes[0].getnewaddress() : 0.0001, "fee": us0["amount"] - Decimal('0.0001')} tx = self.nodes[0].createrawtransaction(inputs, outputs) # specifically fund this tx with a fee < mempoolminfee, >= than minrelaytxfee txF = self.nodes[0].fundrawtransaction(tx, {'feeRate': relayfee}) diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py index 8ec6b8b78519f..4e9c0e3432995 100755 --- a/test/functional/rpc_txoutproof.py +++ b/test/functional/rpc_txoutproof.py @@ -37,9 +37,9 @@ def run_test(self): assert_equal(self.nodes[2].getbalance()['bitcoin'], 0) node0utxos = self.nodes[0].listunspent(1) - tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) + tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99, "fee": 0.01}) txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransactionwithwallet(tx1)["hex"]) - tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) + tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99, "fee": 0.01}) txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransactionwithwallet(tx2)["hex"]) # This will raise an exception because the transaction is not yet in a block assert_raises_rpc_error(-5, "Transaction not yet in block", self.nodes[0].gettxoutproof, [txid1]) @@ -58,7 +58,7 @@ def run_test(self): 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}) + tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 49.98, "fee": 0.01}) txid3 = self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransactionwithwallet(tx3)["hex"]) self.nodes[0].generate(1) self.sync_all() diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index 13baa3357858c..43fd34288b64f 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -204,7 +204,9 @@ def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount): addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey) if not encode_p2sh: assert_equal(node.getaddressinfo(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey)) - return node.createrawtransaction([utxo], {addr: amount}) + if "amount" not in utxo: + utxo["amount"] = node.gettxout(utxo["txid"], utxo["vout"])["value"] + return node.createrawtransaction([utxo], {addr: amount, "fee": utxo["amount"]-amount}) def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""): """Create a transaction spending a given utxo to a segwit output. diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 229d5dc78a08a..88c5ef238523a 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -316,6 +316,9 @@ def __init__(self, nValue=0, scriptPubKey=b""): self.nValue = nValue self.scriptPubKey = scriptPubKey + def is_fee(self): + return len(self.scriptPubKey) == 0 + def deserialize(self, f): self.nValue = struct.unpack("