diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py --- a/test/functional/wallet_txn_clone.py +++ b/test/functional/wallet_txn_clone.py @@ -4,12 +4,14 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs.""" +import io from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, connect_nodes, disconnect_nodes, ) +from test_framework.messages import CTransaction, COIN class TxnMallTest(BitcoinTestFramework): @@ -72,24 +74,21 @@ clone_raw = self.nodes[0].createrawtransaction( clone_inputs, clone_outputs, clone_locktime) - # createrawtransaction randomizes the order of its outputs, so swap them if necessary. - # output 0 is at version+#inputs+input+sigstub+sequence+#outputs - # 40 BCH serialized is 00286bee00000000 - pos0 = 2 * (4 + 1 + 36 + 1 + 4 + 1) - hex40 = "00286bee00000000" - output_len = 16 + 2 + 2 * \ - int("0x" + clone_raw[pos0 + 16: pos0 + 16 + 2], 0) - if (rawtx1["vout"][0]["value"] == 40 and clone_raw[pos0: pos0 + 16] != hex40 or - rawtx1["vout"][0]["value"] != 40 and clone_raw[pos0: pos0 + 16] == hex40): - output0 = clone_raw[pos0: pos0 + output_len] - output1 = clone_raw[pos0 + output_len: pos0 + 2 * output_len] - clone_raw = clone_raw[:pos0] + output1 + \ - output0 + clone_raw[pos0 + 2 * output_len:] + # createrawtransaction randomizes the order of its outputs, so swap + # them if necessary. + clone_tx = CTransaction() + clone_tx.deserialize(io.BytesIO(bytes.fromhex(clone_raw))) + if (rawtx1["vout"][0]["value"] == 40 and + clone_tx.vout[0].nValue != 40 * COIN or + rawtx1["vout"][0]["value"] != 40 and + clone_tx.vout[0].nValue == 40 * COIN): + (clone_tx.vout[0], clone_tx.vout[1]) = (clone_tx.vout[1], + clone_tx.vout[0]) # Use a different signature hash type to sign. This creates an equivalent but malleated clone. # Don't send the clone anywhere yet tx1_clone = self.nodes[0].signrawtransactionwithwallet( - clone_raw, None, "ALL|FORKID|ANYONECANPAY") + clone_tx.serialize().hex(), None, "ALL|FORKID|ANYONECANPAY") assert_equal(tx1_clone["complete"], True) # Have node0 mine a block, if requested: