Compare commits

...

6 commits

Author SHA1 Message Date
Chris Stewart
b43fc22c16
Merge 024c3bf3c7 into c5e44a0435 2025-04-29 11:52:41 +02:00
merge-script
c5e44a0435
Merge bitcoin/bitcoin#32369: test: Use the correct node for doubled keypath test
Some checks are pending
CI / macOS 14 native, arm64, fuzz (push) Waiting to run
CI / Windows native, VS 2022 (push) Waiting to run
CI / Windows native, fuzz, VS 2022 (push) Waiting to run
CI / Linux->Windows cross, no tests (push) Waiting to run
CI / Windows, test cross-built (push) Blocked by required conditions
CI / ASan + LSan + UBSan + integer, no depends, USDT (push) Waiting to run
CI / test each commit (push) Waiting to run
CI / macOS 14 native, arm64, no depends, sqlite only, gui (push) Waiting to run
32d55e28af test: Use the correct node for doubled keypath test (Ava Chow)

Pull request description:

  #29124 had a silent merge conflict with #32350 which resulted in it using the wrong node. Fix the test to use the correct v22 node.

ACKs for top commit:
  maflcko:
    lgtm ACK 32d55e28af
  rkrux:
    ACK 32d55e28af
  BrandonOdiwuor:
    Code Review ACK 32d55e28af

Tree-SHA512: 1e0231985beb382b16e1d608c874750423d0502388db0c8ad450b22d17f9d96f5e16a6b44948ebda5efc750f62b60d0de8dd20131f449427426a36caf374af92
2025-04-29 09:59:42 +01:00
Ava Chow
32d55e28af test: Use the correct node for doubled keypath test 2025-04-28 14:44:17 -07:00
Chris Stewart
024c3bf3c7 Address codreview from mabu44 2025-04-10 12:03:39 -05:00
Chris Stewart
01d2068fb6 Add assertion to check that the max locktime satisfiable under BIP113 is UINT32_MAX - 2 2025-04-08 11:48:00 -05:00
Chris Stewart
062c31b72e tests: Add unix timestamp tests for OP_CLTV 2025-04-08 11:32:42 -05:00
2 changed files with 67 additions and 6 deletions

View file

@ -7,6 +7,7 @@
Test that the CHECKLOCKTIMEVERIFY soft-fork activates.
"""
import time
from test_framework.blocktools import (
TIME_GENESIS_BLOCK,
create_block,
@ -26,7 +27,7 @@ from test_framework.script import (
OP_DROP,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
from test_framework.util import assert_equal, assert_not_equal
from test_framework.wallet import (
MiniWallet,
MiniWalletMode,
@ -72,12 +73,12 @@ def cltv_invalidate(tx, failure_reason):
def cltv_validate(tx, height):
# Modify the signature in vin 0 and nSequence/nLockTime of the tx to pass CLTV
scheme = [[CScriptNum(height), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, height]
scheme = [[CScriptNum.encode(CScriptNum(height))[1:], OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, height]
cltv_modify_tx(tx, prepend_scriptsig=scheme[0], nsequence=scheme[1], nlocktime=scheme[2])
CLTV_HEIGHT = 111
CLTV_HEIGHT = 112
class BIP65Test(BitcoinTestFramework):
@ -107,8 +108,9 @@ class BIP65Test(BitcoinTestFramework):
self.test_cltv_info(is_active=False)
self.log.info("Mining %d blocks", CLTV_HEIGHT - 2)
self.generate(wallet, 10)
self.generate(self.nodes[0], CLTV_HEIGHT - 2 - 10)
num_utxos = 12
self.generate(wallet, num_utxos)
self.generate(self.nodes[0], CLTV_HEIGHT - 2 - num_utxos)
assert_equal(self.nodes[0].getblockcount(), CLTV_HEIGHT - 2)
self.log.info("Test that invalid-according-to-CLTV transactions can still appear in a block")
@ -199,6 +201,65 @@ class BIP65Test(BitcoinTestFramework):
self.test_cltv_info(is_active=True) # Active as of current tip
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256)
# test wall clock time
tip = block.sha256
current_time = int(time.time())
locktime = current_time + (60 * 60) # 1 hour
spendtx = wallet.create_self_transfer()['tx']
self.log.info("Test that one block mined with correct wall clock time does not satisfy median-time-past")
cltv_validate(spendtx,locktime)
block2 = create_block(tip, create_coinbase(CLTV_HEIGHT + 1), ntime=locktime, version=4)
block2.vtx.append(spendtx)
block2.hashMerkleRoot = block2.calc_merkle_root()
block2.solve()
peer.send_and_ping(msg_block(block2))
# expect failure as we haven't satisfied wall clock time yet
assert_not_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256)
self.log.info("Test 7 blocks mined with current wall clock time can satisfy the median-time-past")
num = 7
for i in range(num):
b = create_block(tip, create_coinbase(CLTV_HEIGHT + i + 1), ntime=locktime + i, version=4)
b.solve()
peer.send_and_ping(msg_block(b))
tip = b.sha256
# now our median-past-time should allow for a transaction with
# a locktime of +1 hour to be confirmed
cltv_validate(spendtx,locktime)
block2 = create_block(tip, create_coinbase(CLTV_HEIGHT + num + 1), ntime=locktime + num, version=4)
block2.vtx.append(spendtx)
block2.hashMerkleRoot = block2.calc_merkle_root()
block2.solve()
peer.send_and_ping(msg_block(block2))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256)
self.log.info("Test that we cannot mine locktimes that are UINT32_MAX")
UINT32_MAX = 2**32 - 1
self.nodes[0].setmocktime(UINT32_MAX)
# need to re-add connection as setting mocktime times out the p2p connection
peer = self.nodes[0].add_p2p_connection(P2PInterface())
tip = block2.sha256
# mine 6 blocks with UINT32_MAX -1 ntime
for i in range(6):
b = create_block(tip, create_coinbase(CLTV_HEIGHT + num + i + 2), ntime=UINT32_MAX - 1, version=4)
b.solve()
peer.send_and_ping(msg_block(b))
tip = b.sha256
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
spendtx = wallet.create_self_transfer()['tx']
# create the next block with ntime=UINT32_MAX so we monotonically increase block time
block3 = create_block(tip, create_coinbase(CLTV_HEIGHT + num + 6 + 2), ntime=UINT32_MAX, version=4)
# the max locktime we can include in this block is UINT32_MAX - 2 due to the fact
# our current median-time-past is UINT32_MAX - 1
cltv_validate(spendtx,UINT32_MAX - 2)
block3.vtx.append(spendtx)
block3.hashMerkleRoot = block3.calc_merkle_root()
block3.solve()
peer.send_and_ping(msg_block(block3))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block3.sha256)
if __name__ == '__main__':
BIP65Test(__file__).main()

View file

@ -87,7 +87,7 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
# 0.21.x and 22.x would both produce bad derivation paths when topping up an inactive hd chain
# Make sure that this is being automatically cleaned up by migration
node_master = self.nodes[1]
node_v22 = self.nodes[self.num_nodes - 5]
node_v22 = self.nodes[self.num_nodes - 3]
wallet_name = "bad_deriv_path"
node_v22.createwallet(wallet_name=wallet_name, descriptors=False)
bad_deriv_wallet = node_v22.get_wallet_rpc(wallet_name)