diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -93,6 +93,91 @@ return height >= 576 +def create_transaction(node, txid, to_address, amount): + inputs = [{"txid": txid, "vout": 0}] + outputs = {to_address: amount} + rawtx = node.createrawtransaction(inputs, outputs) + tx = FromHex(CTransaction(), rawtx) + return tx + + +def sign_transaction(node, unsignedtx): + rawtx = ToHex(unsignedtx) + signresult = node.signrawtransactionwithwallet(rawtx) + tx = FromHex(CTransaction(), signresult['hex']) + return tx + + +def spend_tx(node, prev_tx, address): + spendtx = create_transaction( + node, prev_tx.hash, address, (prev_tx.vout[0].nValue - 1000) / COIN) + spendtx.nVersion = prev_tx.nVersion + pad_tx(spendtx) + spendtx.rehash() + return spendtx + + +def create_bip112special(node, input, txversion, address): + tx = create_transaction( + node, input, address, Decimal("49.98")) + tx.nVersion = txversion + tx.vout[0].scriptPubKey = CScript( + [-1, OP_CHECKSEQUENCEVERIFY, OP_DROP, OP_TRUE]) + tx.rehash() + signtx = sign_transaction(node, tx) + signtx.rehash() + + return signtx + + +def send_generic_input_tx(node, coinbases, address): + amount = Decimal("49.99") + return node.sendrawtransaction(ToHex(sign_transaction(node, create_transaction(node, node.getblock(coinbases.pop())['tx'][0], address, amount)))) + + +def create_bip68txs(node, bip68inputs, txversion, address, locktime_delta=0): + """Returns a list of bip68 transactions with different bits set.""" + txs = [] + assert(len(bip68inputs) >= 16) + for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)): + locktime = relative_locktime(sdf, srhb, stf, srlb) + tx = create_transaction( + node, bip68inputs[i], address, Decimal("49.98")) + tx.nVersion = txversion + tx.vin[0].nSequence = locktime + locktime_delta + tx = sign_transaction(node, tx) + tx.rehash() + txs.append({'tx': tx, 'sdf': sdf, 'stf': stf}) + + return txs + + +def create_bip112txs(node, bip112inputs, varyOP_CSV, txversion, address, locktime_delta=0): + """Returns a list of bip112 transactions with different bits set.""" + txs = [] + assert(len(bip112inputs) >= 16) + for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)): + locktime = relative_locktime(sdf, srhb, stf, srlb) + tx = create_transaction( + node, bip112inputs[i], address, Decimal("49.98")) + if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed + tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME + locktime_delta + else: # vary nSequence instead, OP_CSV is fixed + tx.vin[0].nSequence = locktime + locktime_delta + tx.nVersion = txversion + if (varyOP_CSV): + tx.vout[0].scriptPubKey = CScript( + [locktime, OP_CHECKSEQUENCEVERIFY, OP_DROP, OP_TRUE]) + else: + tx.vout[0].scriptPubKey = CScript( + [BASE_RELATIVE_LOCKTIME, OP_CHECKSEQUENCEVERIFY, OP_DROP, OP_TRUE]) + tx.rehash() + signtx = sign_transaction(node, tx) + signtx.rehash() + txs.append({'tx': signtx, 'sdf': sdf, 'stf': stf}) + return txs + + class BIP68_112_113Test(ComparisonTestFramework): def set_test_params(self): self.num_nodes = 1 @@ -105,31 +190,6 @@ network_thread_start() test.run() - def send_generic_input_tx(self, node, coinbases): - amount = Decimal("49.99") - return node.sendrawtransaction(ToHex(self.sign_transaction(node, self.create_transaction(node, node.getblock(coinbases.pop())['tx'][0], self.nodeaddress, amount)))) - - def create_transaction(self, node, txid, to_address, amount): - inputs = [{"txid": txid, "vout": 0}] - outputs = {to_address: amount} - rawtx = node.createrawtransaction(inputs, outputs) - tx = FromHex(CTransaction(), rawtx) - return tx - - def sign_transaction(self, node, unsignedtx): - rawtx = ToHex(unsignedtx) - signresult = node.signrawtransactionwithwallet(rawtx) - tx = FromHex(CTransaction(), signresult['hex']) - return tx - - def spend_tx(self, node, prev_tx): - spendtx = self.create_transaction( - node, prev_tx.hash, self.nodeaddress, (prev_tx.vout[0].nValue - 1000) / COIN) - spendtx.nVersion = prev_tx.nVersion - pad_tx(spendtx) - spendtx.rehash() - return spendtx - def generate_blocks(self, number): test_blocks = [] for i in range(number): @@ -157,66 +217,13 @@ # method should not be used. def create_test_block_spend_utxos(self, node, txs, version=536870912): block = self.create_test_block(txs, version) - block.vtx.extend([self.spend_tx(node, tx) for tx in txs]) + block.vtx.extend([spend_tx(node, tx, self.nodeaddress) for tx in txs]) make_conform_to_ctor(block) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() return block - def create_bip68txs(self, bip68inputs, txversion, locktime_delta=0): - """Returns a list of bip68 transactions with different bits set.""" - txs = [] - assert(len(bip68inputs) >= 16) - for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)): - locktime = relative_locktime(sdf, srhb, stf, srlb) - tx = self.create_transaction( - self.nodes[0], bip68inputs[i], self.nodeaddress, Decimal("49.98")) - tx.nVersion = txversion - tx.vin[0].nSequence = locktime + locktime_delta - tx = self.sign_transaction(self.nodes[0], tx) - tx.rehash() - txs.append({'tx': tx, 'sdf': sdf, 'stf': stf}) - - return txs - - def create_bip112special(self, input, txversion): - tx = self.create_transaction( - self.nodes[0], input, self.nodeaddress, Decimal("49.98")) - tx.nVersion = txversion - tx.vout[0].scriptPubKey = CScript( - [-1, OP_CHECKSEQUENCEVERIFY, OP_DROP, OP_TRUE]) - tx.rehash() - signtx = self.sign_transaction(self.nodes[0], tx) - signtx.rehash() - - return signtx - - def create_bip112txs(self, bip112inputs, varyOP_CSV, txversion, locktime_delta=0): - """Returns a list of bip112 transactions with different bits set.""" - txs = [] - assert(len(bip112inputs) >= 16) - for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)): - locktime = relative_locktime(sdf, srhb, stf, srlb) - tx = self.create_transaction( - self.nodes[0], bip112inputs[i], self.nodeaddress, Decimal("49.98")) - if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed - tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME + locktime_delta - else: # vary nSequence instead, OP_CSV is fixed - tx.vin[0].nSequence = locktime + locktime_delta - tx.nVersion = txversion - if (varyOP_CSV): - tx.vout[0].scriptPubKey = CScript( - [locktime, OP_CHECKSEQUENCEVERIFY, OP_DROP, OP_TRUE]) - else: - tx.vout[0].scriptPubKey = CScript( - [BASE_RELATIVE_LOCKTIME, OP_CHECKSEQUENCEVERIFY, OP_DROP, OP_TRUE]) - tx.rehash() - signtx = self.sign_transaction(self.nodes[0], tx) - signtx.rehash() - txs.append({'tx': signtx, 'sdf': sdf, 'stf': stf}) - return txs - def get_tests(self): self.log.info("Generate blocks in the past for coinbase outputs.") # Enough to build up to 1000 blocks 10 minutes apart without worrying @@ -252,16 +259,16 @@ # 16 normal inputs bip68inputs = [] for i in range(16): - bip68inputs.append(self.send_generic_input_tx( - self.nodes[0], self.coinbase_blocks)) + bip68inputs.append(send_generic_input_tx( + self.nodes[0], self.coinbase_blocks, self.nodeaddress)) # 2 sets of 16 inputs with 10 OP_CSV OP_DROP (actually will be prepended to spending scriptSig) bip112basicinputs = [] for j in range(2): inputs = [] for i in range(16): - inputs.append(self.send_generic_input_tx( - self.nodes[0], self.coinbase_blocks)) + inputs.append(send_generic_input_tx( + self.nodes[0], self.coinbase_blocks, self.nodeaddress)) bip112basicinputs.append(inputs) # 2 sets of 16 varied inputs with (relative_lock_time) OP_CSV OP_DROP (actually will be prepended to spending scriptSig) @@ -269,17 +276,17 @@ for j in range(2): inputs = [] for i in range(16): - inputs.append(self.send_generic_input_tx( - self.nodes[0], self.coinbase_blocks)) + inputs.append(send_generic_input_tx( + self.nodes[0], self.coinbase_blocks, self.nodeaddress)) bip112diverseinputs.append(inputs) # 1 special input with -1 OP_CSV OP_DROP (actually will be prepended to spending scriptSig) - bip112specialinput = self.send_generic_input_tx( - self.nodes[0], self.coinbase_blocks) + bip112specialinput = send_generic_input_tx( + self.nodes[0], self.coinbase_blocks, self.nodeaddress) # 1 normal input - bip113input = self.send_generic_input_tx( - self.nodes[0], self.coinbase_blocks) + bip113input = send_generic_input_tx( + self.nodes[0], self.coinbase_blocks, self.nodeaddress) self.nodes[0].setmocktime(self.last_block_time + 600) # 1 block generated for inputs to be in chain at height 572 @@ -303,43 +310,47 @@ # Test both version 1 and version 2 transactions for all tests # BIP113 test transaction will be modified before each use to # put in appropriate block time - bip113tx_v1 = self.create_transaction( + bip113tx_v1 = create_transaction( self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98")) bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE bip113tx_v1.nVersion = 1 - bip113tx_v2 = self.create_transaction( + bip113tx_v2 = create_transaction( self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98")) bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE bip113tx_v2.nVersion = 2 # For BIP68 test all 16 relative sequence locktimes - bip68txs_v1 = self.create_bip68txs(bip68inputs, 1) - bip68txs_v2 = self.create_bip68txs(bip68inputs, 2) + bip68txs_v1 = create_bip68txs( + self.nodes[0], bip68inputs, 1, self.nodeaddress) + bip68txs_v2 = create_bip68txs( + self.nodes[0], bip68inputs, 2, self.nodeaddress) # For BIP112 test: # 16 relative sequence locktimes of 10 against 10 OP_CSV OP_DROP inputs - bip112txs_vary_nSequence_v1 = self.create_bip112txs( - bip112basicinputs[0], False, 1) - bip112txs_vary_nSequence_v2 = self.create_bip112txs( - bip112basicinputs[0], False, 2) + bip112txs_vary_nSequence_v1 = create_bip112txs( + self.nodes[0], bip112basicinputs[0], False, 1, self.nodeaddress) + bip112txs_vary_nSequence_v2 = create_bip112txs( + self.nodes[0], bip112basicinputs[0], False, 2, self.nodeaddress) # 16 relative sequence locktimes of 9 against 10 OP_CSV OP_DROP inputs - bip112txs_vary_nSequence_9_v1 = self.create_bip112txs( - bip112basicinputs[1], False, 1, -1) - bip112txs_vary_nSequence_9_v2 = self.create_bip112txs( - bip112basicinputs[1], False, 2, -1) + bip112txs_vary_nSequence_9_v1 = create_bip112txs( + self.nodes[0], bip112basicinputs[1], False, 1, self.nodeaddress, -1) + bip112txs_vary_nSequence_9_v2 = create_bip112txs( + self.nodes[0], bip112basicinputs[1], False, 2, self.nodeaddress, -1) # sequence lock time of 10 against 16 (relative_lock_time) OP_CSV OP_DROP inputs - bip112txs_vary_OP_CSV_v1 = self.create_bip112txs( - bip112diverseinputs[0], True, 1) - bip112txs_vary_OP_CSV_v2 = self.create_bip112txs( - bip112diverseinputs[0], True, 2) + bip112txs_vary_OP_CSV_v1 = create_bip112txs( + self.nodes[0], bip112diverseinputs[0], True, 1, self.nodeaddress) + bip112txs_vary_OP_CSV_v2 = create_bip112txs( + self.nodes[0], bip112diverseinputs[0], True, 2, self.nodeaddress) # sequence lock time of 9 against 16 (relative_lock_time) OP_CSV OP_DROP inputs - bip112txs_vary_OP_CSV_9_v1 = self.create_bip112txs( - bip112diverseinputs[1], True, 1, -1) - bip112txs_vary_OP_CSV_9_v2 = self.create_bip112txs( - bip112diverseinputs[1], True, 2, -1) + bip112txs_vary_OP_CSV_9_v1 = create_bip112txs( + self.nodes[0], bip112diverseinputs[1], True, 1, self.nodeaddress, -1) + bip112txs_vary_OP_CSV_9_v2 = create_bip112txs( + self.nodes[0], bip112diverseinputs[1], True, 2, self.nodeaddress, -1) # -1 OP_CSV OP_DROP input - bip112tx_special_v1 = self.create_bip112special(bip112specialinput, 1) - bip112tx_special_v2 = self.create_bip112special(bip112specialinput, 2) + bip112tx_special_v1 = create_bip112special( + self.nodes[0], bip112specialinput, 1, self.nodeaddress) + bip112tx_special_v2 = create_bip112special( + self.nodes[0], bip112specialinput, 2, self.nodeaddress) self.log.info("TESTING") @@ -350,25 +361,26 @@ # add BIP113 tx and -1 CSV tx # = MTP of prior block (not <) but < time put on current block bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) + bip113signed1 = sign_transaction(self.nodes[0], bip113tx_v1) success_txs.append(bip113signed1) success_txs.append(bip112tx_special_v1) - success_txs.append(self.spend_tx(self.nodes[0], bip112tx_special_v1)) + success_txs.append( + spend_tx(self.nodes[0], bip112tx_special_v1, self.nodeaddress)) # add BIP 68 txs success_txs.extend(all_rlt_txs(bip68txs_v1)) # add BIP 112 with seq=10 txs success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_nSequence_v1)]) success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v1)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_OP_CSV_v1)]) # try BIP 112 with seq=9 txs success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_nSequence_9_v1)]) success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v1)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_OP_CSV_9_v1)]) # Test #3 yield TestInstance([[self.create_test_block(success_txs), True]]) @@ -380,25 +392,26 @@ # add BIP113 tx and -1 CSV tx # = MTP of prior block (not <) but < time put on current block bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) + bip113signed2 = sign_transaction(self.nodes[0], bip113tx_v2) success_txs.append(bip113signed2) success_txs.append(bip112tx_special_v2) - success_txs.append(self.spend_tx(self.nodes[0], bip112tx_special_v2)) + success_txs.append( + spend_tx(self.nodes[0], bip112tx_special_v2, self.nodeaddress)) # add BIP 68 txs success_txs.extend(all_rlt_txs(bip68txs_v2)) # add BIP 112 with seq=10 txs success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v2)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_nSequence_v2)]) success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v2)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_OP_CSV_v2)]) # try BIP 112 with seq=9 txs success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_nSequence_9_v2)]) success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v2)) - success_txs.extend([self.spend_tx(self.nodes[0], tx) + success_txs.extend([spend_tx(self.nodes[0], tx, self.nodeaddress) for tx in all_rlt_txs(bip112txs_vary_OP_CSV_9_v2)]) # Test #4 yield TestInstance([[self.create_test_block(success_txs), True]]) @@ -422,10 +435,10 @@ # if nLockTime isn't satisfied by new rules # = MTP of prior block (not <) but < time put on current block bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) + bip113signed1 = sign_transaction(self.nodes[0], bip113tx_v1) # = MTP of prior block (not <) but < time put on current block bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) + bip113signed2 = sign_transaction(self.nodes[0], bip113tx_v2) for bip113tx in [bip113signed1, bip113signed2]: # Test #6, Test #7 yield TestInstance([[self.create_test_block([bip113tx]), False]]) @@ -433,10 +446,10 @@ # < MTP of prior block bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 - bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) + bip113signed1 = sign_transaction(self.nodes[0], bip113tx_v1) # < MTP of prior block bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 - bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) + bip113signed2 = sign_transaction(self.nodes[0], bip113tx_v2) for bip113tx in [bip113signed1, bip113signed2]: # Test #8, Test #9 yield TestInstance([[self.create_test_block([bip113tx]), True]]) @@ -593,7 +606,7 @@ spend_txs = [] for tx in success_txs: - raw_tx = self.spend_tx(self.nodes[0], tx) + raw_tx = spend_tx(self.nodes[0], tx, self.nodeaddress) raw_tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME raw_tx.rehash() spend_txs.append(raw_tx) @@ -604,7 +617,7 @@ # Additional test, of checking that comparison of two time types works properly time_txs = [] for tx in [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if not tx['sdf'] and tx['stf']]: - signtx = self.sign_transaction(self.nodes[0], tx) + signtx = sign_transaction(self.nodes[0], tx) time_txs.append(signtx) # Test #124 @@ -622,7 +635,7 @@ spend_txs = [] for tx in time_txs: - raw_tx = self.spend_tx(self.nodes[0], tx) + raw_tx = spend_tx(self.nodes[0], tx, self.nodeaddress) raw_tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME | SEQ_TYPE_FLAG raw_tx.rehash() spend_txs.append(raw_tx)