Skip to content

Commit

Permalink
Port python tests part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
timemarkovqtum committed Aug 9, 2024
1 parent 9bd1be3 commit ece590d
Show file tree
Hide file tree
Showing 35 changed files with 569 additions and 315 deletions.
14 changes: 7 additions & 7 deletions test/functional/feature_assumeutxo.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
MiniWallet,
)

START_HEIGHT = 199
SNAPSHOT_BASE_HEIGHT = 299
FINAL_HEIGHT = 399
START_HEIGHT = 2099
SNAPSHOT_BASE_HEIGHT = 2199
FINAL_HEIGHT = 2299
COMPLETE_IDX = {'synced': True, 'best_block_height': FINAL_HEIGHT}


Expand Down Expand Up @@ -96,7 +96,7 @@ def expected_error(log_msg="", rpc_details=""):
f.write(valid_snapshot_contents[:32])
f.write((valid_num_coins + off).to_bytes(8, "little"))
f.write(valid_snapshot_contents[32 + 8:])
expected_error(log_msg=f"bad snapshot - coins left over after deserializing 298 coins" if off == -1 else f"bad snapshot format or truncated snapshot after deserializing 299 coins")
expected_error(log_msg=f"bad snapshot - coins left over after deserializing 2198 coins" if off == -1 else f"bad snapshot format or truncated snapshot after deserializing 2199 coins")

self.log.info(" - snapshot file with alternated UTXO data")
cases = [
Expand All @@ -111,7 +111,7 @@ def expected_error(log_msg="", rpc_details=""):
f.write(valid_snapshot_contents[:(32 + 8 + offset)])
f.write(content)
f.write(valid_snapshot_contents[(32 + 8 + offset + len(content)):])
expected_error(log_msg=f"[snapshot] bad snapshot content hash: expected a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27, got {wrong_hash}")
expected_error(log_msg=f"[snapshot] bad snapshot content hash: expected a9e20f6c0c6531e44789f7a29df1939fa1c2e7d5c451b25c5201880628c57940, got {wrong_hash}")

def test_invalid_chainstate_scenarios(self):
self.log.info("Test different scenarios of invalid snapshot chainstate in datadir")
Expand Down Expand Up @@ -197,8 +197,8 @@ def run_test(self):

assert_equal(
dump_output['txoutset_hash'],
"a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27")
assert_equal(dump_output["nchaintx"], 334)
"a9e20f6c0c6531e44789f7a29df1939fa1c2e7d5c451b25c5201880628c57940")
assert_equal(dump_output["nchaintx"], 2200)
assert_equal(n0.getblockchaininfo()["blocks"], SNAPSHOT_BASE_HEIGHT)

# Mine more blocks on top of the snapshot that n1 hasn't yet seen. This
Expand Down
58 changes: 45 additions & 13 deletions test/functional/feature_assumevalid.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
block 200. node2 will reject block 102 since it's assumed valid, but it
isn't buried by at least two weeks' work.
"""
import time

from test_framework.blocktools import (
COINBASE_MATURITY,
Expand All @@ -52,6 +53,7 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
from test_framework.wallet_util import generate_keypair
import inspect


class BaseNode(P2PInterface):
Expand Down Expand Up @@ -85,6 +87,25 @@ def send_blocks_until_disconnected(self, p2p_conn):
assert not p2p_conn.is_connected
break

def assert_blockchain_height(self, node, height):
"""Wait until the blockchain is no longer advancing and verify it's reached the expected height."""
last_height = node.getblock(node.getbestblockhash())['height']
timeout = 10
while True:
if timeout < 0:
assert False, "blockchain too short after timeout: %d" % current_height

time.sleep(0.25)
current_height = node.getblock(node.getbestblockhash())['height']
if current_height > height:
assert False, "blockchain too long: %d" % current_height
elif current_height != last_height:
last_height = current_height
timeout = 10 # reset the timeout
elif current_height == height:
break
timeout = timeout - 0.25

def run_test(self):
# Build the blockchain
self.tip = int(self.nodes[0].getbestblockhash(), 16)
Expand All @@ -107,7 +128,7 @@ def run_test(self):
height += 1

# Bury the block 100 deep so the coinbase output is spendable
for _ in range(100):
for _ in range(COINBASE_MATURITY):
block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve()
self.blocks.append(block)
Expand All @@ -130,7 +151,7 @@ def run_test(self):
height += 1

# Bury the assumed valid block 2100 deep
for _ in range(2100):
for _ in range(10000):
block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve()
self.blocks.append(block)
Expand All @@ -139,36 +160,47 @@ def run_test(self):
height += 1

# Start node1 and node2 with assumevalid so they accept a block with a bad signature.
self.start_node(1, extra_args=["-assumevalid=" + hex(block102.sha256)])
self.start_node(2, extra_args=["-assumevalid=" + hex(block102.sha256)])
self.start_node(1, extra_args=["-assumevalid=" + hex(block102.sha256)[2:]])
self.start_node(2, extra_args=["-assumevalid=" + hex(block102.sha256)[2:]])

p2p0 = self.nodes[0].add_p2p_connection(BaseNode())
p2p0.send_header_for_blocks(self.blocks[0:2000])
p2p0.send_header_for_blocks(self.blocks[2000:])
p2p0.send_header_for_blocks(self.blocks[2000:4000])
p2p0.send_header_for_blocks(self.blocks[4000:6000])
p2p0.send_header_for_blocks(self.blocks[6000:8000])
p2p0.send_header_for_blocks(self.blocks[8000:10000])
p2p0.send_header_for_blocks(self.blocks[10000:])

# Send blocks to node0. Block 102 will be rejected.
self.send_blocks_until_disconnected(p2p0)
self.wait_until(lambda: self.nodes[0].getblockcount() >= COINBASE_MATURITY + 1)
assert_equal(self.nodes[0].getblockcount(), COINBASE_MATURITY + 1)
self.assert_blockchain_height(self.nodes[0], COINBASE_MATURITY+1)

p2p1 = self.nodes[1].add_p2p_connection(BaseNode())
p2p1.send_header_for_blocks(self.blocks[0:2000])
p2p1.send_header_for_blocks(self.blocks[2000:])
p2p1.send_header_for_blocks(self.blocks[2000:4000])
p2p1.send_header_for_blocks(self.blocks[4000:6000])
p2p1.send_header_for_blocks(self.blocks[6000:8000])
p2p1.send_header_for_blocks(self.blocks[8000:10000])
p2p1.send_header_for_blocks(self.blocks[10000:])

# Send all blocks to node1. All blocks will be accepted.
for i in range(2202):
# Send only a subset to speed this up
p2p1 = self.nodes[1].add_p2p_connection(BaseNode())
for i in range(1000):
p2p1.send_message(msg_block(self.blocks[i]))
# Syncing 2200 blocks can take a while on slow systems. Give it plenty of time to sync.
p2p1.sync_with_ping(960)
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 2202)
timeout = time.time() + 200
while time.time() < timeout:
if self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'] == 1000:
break
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 1000)

p2p2 = self.nodes[2].add_p2p_connection(BaseNode())
p2p2.send_header_for_blocks(self.blocks[0:200])

# Send blocks to node2. Block 102 will be rejected.
self.send_blocks_until_disconnected(p2p2)
self.wait_until(lambda: self.nodes[2].getblockcount() >= COINBASE_MATURITY + 1)
assert_equal(self.nodes[2].getblockcount(), COINBASE_MATURITY + 1)
self.assert_blockchain_height(self.nodes[2], COINBASE_MATURITY+1)


if __name__ == '__main__':
Expand Down
12 changes: 7 additions & 5 deletions test/functional/feature_bip68_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
"""Test BIP68 implementation."""

import time
import random

from test_framework.blocktools import (
COINBASE_MATURITY,
NORMAL_GBT_REQUEST_PARAMS,
add_witness_commitment,
create_block,
Expand Down Expand Up @@ -72,11 +74,11 @@ def run_test(self):
self.log.info("Running test sequence-lock-unconfirmed-inputs")
self.test_sequence_lock_unconfirmed_inputs()

self.log.info("Running test BIP68 not consensus before activation")
self.test_bip68_not_consensus()
#self.log.info("Running test BIP68 not consensus before activation")
#self.test_bip68_not_consensus()

self.log.info("Activating BIP68 (and 112/113)")
self.activateCSV()
#self.log.info("Activating BIP68 (and 112/113)")
#self.activateCSV()

self.log.info("Verifying nVersion=2 transactions are standard.")
self.log.info("Note that nVersion=2 transactions are always standard (independent of BIP68 activation status).")
Expand Down Expand Up @@ -138,7 +140,7 @@ def test_sequence_lock_confirmed_inputs(self):
import random
num_outputs = random.randint(1, max_outputs)
self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=num_outputs)
self.generate(self.wallet, 1)
self.generate(self.wallet, COINBASE_MATURITY + 1)

utxos = self.wallet.get_utxos(include_immature_coinbase=False)

Expand Down
Loading

0 comments on commit ece590d

Please sign in to comment.