Skip to content

Commit a0bf080

Browse files
committed
test: swiftsync: Add integration test
1 parent dba6a18 commit a0bf080

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2025-present The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
""" Testing related to SwiftSync initial block download protocol.
6+
"""
7+
from test_framework.util import assert_equal
8+
from test_framework.test_framework import BitcoinTestFramework
9+
from test_framework.wallet import MiniWallet
10+
11+
BASE_BLOCKS = 200
12+
NUM_SWIFTSYNC_BLOCKS = 100
13+
NUM_ADDITIONAL_BLOCKS = 100
14+
GOOD_FILE = "good.hints"
15+
BAD_FILE = "bad.hints"
16+
17+
class SwiftSyncTest(BitcoinTestFramework):
18+
def set_test_params(self):
19+
self.num_nodes = 2
20+
self.setup_clean_chain = True
21+
22+
def setup_network(self):
23+
self.add_nodes(2)
24+
25+
def run_test(self):
26+
full_node = self.nodes[0]
27+
sync_node = self.nodes[1]
28+
self.start_node(0)
29+
mini_wallet = MiniWallet(full_node)
30+
## Coinbase outputs are treated differently by the SwiftSync protocol as their inputs are ignored.
31+
## To ensure the hash aggregate is working correctly, we also create non-coinbase transactions.
32+
self.log.info(f"Generating {BASE_BLOCKS} blocks to a source node")
33+
self.generate(mini_wallet, BASE_BLOCKS, sync_fun=self.no_op)
34+
self.log.info(f"Sending {NUM_SWIFTSYNC_BLOCKS} self transfers")
35+
for i in range(NUM_SWIFTSYNC_BLOCKS):
36+
mini_wallet.send_self_transfer(from_node=full_node)
37+
self.generate(full_node, nblocks=1, sync_fun=self.no_op)
38+
39+
self.log.info("Creating hints file")
40+
result = full_node.generatetxohints(GOOD_FILE)
41+
hints_path = result["path"]
42+
self.log.info(f"Created hints file at {hints_path}")
43+
assert_equal(full_node.getblockcount(), NUM_SWIFTSYNC_BLOCKS + BASE_BLOCKS)
44+
self.log.info(f"Generating {NUM_ADDITIONAL_BLOCKS} blocks with additional self transfers")
45+
for i in range(NUM_ADDITIONAL_BLOCKS):
46+
mini_wallet.send_self_transfer(from_node=full_node)
47+
self.generate(full_node, nblocks=1, sync_fun=self.no_op)
48+
self.log.info("Starting a pruned node with a hints file and performing IBD")
49+
self.start_node(1, extra_args=["-prune=1", f"-utxohints={hints_path}"])
50+
assert_equal(sync_node.getblockcount(), 0)
51+
self.connect_nodes(0, 1)
52+
self.log.info("Asserting sync is successful")
53+
self.sync_blocks([full_node, sync_node])
54+
assert_equal(full_node.getblockcount(), sync_node.getblockcount())
55+
self.log.info("Sync successful")
56+
self.log.info("Creating a hints file from a stale block")
57+
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
58+
mini_wallet.send_self_transfer(from_node=full_node)
59+
self.generate(full_node, nblocks=1, sync_fun=self.no_op)
60+
result = full_node.generatetxohints(BAD_FILE)
61+
bad_hints_path = result["path"]
62+
self.log.info(f"Created defect hints file at {bad_hints_path}")
63+
self.log.info("Creating heavier chain")
64+
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
65+
mini_wallet.send_self_transfer(from_node=full_node)
66+
self.generate(full_node, nblocks=2, sync_fun=self.no_op)
67+
self.log.info("Asserting pruned node can reorganize")
68+
self.connect_nodes(0, 1)
69+
self.sync_blocks([full_node, sync_node])
70+
assert_equal(full_node.getbestblockhash(), sync_node.getbestblockhash())
71+
self.log.info("Reorganize successful")
72+
73+
if __name__ == '__main__':
74+
SwiftSyncTest(__file__).main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
'p2p_segwit.py',
105105
'feature_maxuploadtarget.py',
106106
'feature_assumeutxo.py',
107+
'feature_swiftsync.py',
107108
'mempool_updatefromblock.py',
108109
'mempool_persist.py',
109110
# vv Tests less than 60s vv

0 commit comments

Comments
 (0)