Changeset View
Changeset View
Standalone View
Standalone View
test/functional/feature_cltv.py
Show All 11 Lines | |||||
from test_framework.messages import ( | from test_framework.messages import ( | ||||
CTransaction, | CTransaction, | ||||
FromHex, | FromHex, | ||||
msg_block, | msg_block, | ||||
msg_tx, | msg_tx, | ||||
ToHex, | ToHex, | ||||
) | ) | ||||
from test_framework.mininode import ( | from test_framework.mininode import ( | ||||
mininode_lock, | |||||
network_thread_start, | network_thread_start, | ||||
P2PInterface, | P2PInterface, | ||||
) | ) | ||||
from test_framework.script import ( | from test_framework.script import ( | ||||
CScript, | CScript, | ||||
CScriptNum, | CScriptNum, | ||||
OP_1NEGATE, | OP_1NEGATE, | ||||
OP_CHECKLOCKTIMEVERIFY, | OP_CHECKLOCKTIMEVERIFY, | ||||
OP_DROP, | OP_DROP, | ||||
OP_TRUE, | OP_TRUE, | ||||
) | ) | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.txtools import pad_tx | from test_framework.txtools import pad_tx | ||||
from test_framework.util import assert_equal, wait_until | from test_framework.util import assert_equal | ||||
CLTV_HEIGHT = 1351 | CLTV_HEIGHT = 1351 | ||||
# Reject codes that we might receive in this test | # Reject codes that we might receive in this test | ||||
REJECT_INVALID = 16 | REJECT_INVALID = 16 | ||||
REJECT_OBSOLETE = 17 | REJECT_OBSOLETE = 17 | ||||
REJECT_NONSTANDARD = 64 | REJECT_NONSTANDARD = 64 | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
assert_equal(self.nodes[0].getbestblockhash(), block.hash) | assert_equal(self.nodes[0].getbestblockhash(), block.hash) | ||||
self.log.info("Test that blocks must now be at least version 4") | self.log.info("Test that blocks must now be at least version 4") | ||||
tip = block.sha256 | tip = block.sha256 | ||||
block_time += 1 | block_time += 1 | ||||
block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time) | block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time) | ||||
block.nVersion = 3 | block.nVersion = 3 | ||||
block.solve() | block.solve() | ||||
with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000003)'.format(block.hash)]): | |||||
self.nodes[0].p2p.send_and_ping(msg_block(block)) | self.nodes[0].p2p.send_and_ping(msg_block(block)) | ||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) | assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) | ||||
self.nodes[0].p2p.sync_with_ping() | |||||
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), | |||||
lock=mininode_lock) | |||||
with mininode_lock: | |||||
assert_equal( | |||||
self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE) | |||||
assert_equal( | |||||
self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000003)') | |||||
assert_equal( | |||||
self.nodes[0].p2p.last_message["reject"].data, block.sha256) | |||||
del self.nodes[0].p2p.last_message["reject"] | |||||
self.log.info( | self.log.info( | ||||
"Test that invalid-according-to-cltv transactions cannot appear in a block") | "Test that invalid-according-to-cltv transactions cannot appear in a block") | ||||
block.nVersion = 4 | block.nVersion = 4 | ||||
fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[1], | fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[1], | ||||
self.nodeaddress, 49.99) | self.nodeaddress, 49.99) | ||||
fundtx, spendtx = cltv_lock_to_height( | fundtx, spendtx = cltv_lock_to_height( | ||||
Show All 31 Lines | def run_test(self): | ||||
block_time += 1 | block_time += 1 | ||||
block = create_block( | block = create_block( | ||||
block.sha256, create_coinbase(CLTV_HEIGHT+1), block_time) | block.sha256, create_coinbase(CLTV_HEIGHT+1), block_time) | ||||
block.nVersion = 4 | block.nVersion = 4 | ||||
block.vtx.append(spendtx) | block.vtx.append(spendtx) | ||||
block.hashMerkleRoot = block.calc_merkle_root() | block.hashMerkleRoot = block.calc_merkle_root() | ||||
block.solve() | block.solve() | ||||
with self.nodes[0].assert_debug_log(expected_msgs=['ConnectBlock {} failed (blk-bad-inputs'.format(block.hash)]): | |||||
self.nodes[0].p2p.send_and_ping(msg_block(block)) | self.nodes[0].p2p.send_and_ping(msg_block(block)) | ||||
# This block is invalid | |||||
assert_equal(self.nodes[0].getbestblockhash(), tip) | assert_equal(self.nodes[0].getbestblockhash(), tip) | ||||
self.nodes[0].p2p.sync_with_ping() | |||||
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), | |||||
lock=mininode_lock) | |||||
with mininode_lock: | |||||
assert self.nodes[0].p2p.last_message["reject"].code in [ | |||||
REJECT_INVALID, REJECT_NONSTANDARD] | |||||
assert_equal( | |||||
self.nodes[0].p2p.last_message["reject"].data, block.sha256) | |||||
if self.nodes[0].p2p.last_message["reject"].code == REJECT_INVALID: | |||||
# Generic rejection when a block is invalid | |||||
assert_equal( | |||||
self.nodes[0].p2p.last_message["reject"].reason, b'blk-bad-inputs') | |||||
else: | |||||
assert b'Negative locktime' in self.nodes[0].p2p.last_message["reject"].reason | |||||
self.log.info( | self.log.info( | ||||
"Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") | "Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") | ||||
fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[2], | fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[2], | ||||
self.nodeaddress, 49.99) | self.nodeaddress, 49.99) | ||||
fundtx, spendtx = cltv_lock_to_height( | fundtx, spendtx = cltv_lock_to_height( | ||||
self.nodes[0], fundtx, self.nodeaddress, 49.98, CLTV_HEIGHT) | self.nodes[0], fundtx, self.nodeaddress, 49.98, CLTV_HEIGHT) | ||||
Show All 23 Lines |