Skip to content

Commit 626e3ae

Browse files
committed
test: add functional simplicity activation test
1 parent 57ab101 commit 626e3ae

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2015-2020 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+
"""Test Simplicity soft fork activation for Elements
6+
7+
This is essentially the same as the Taproot activation test.
8+
9+
Like that one, it doesn't try to test the actual activation (which is
10+
tested by feature_taproot.py) but instead makes sure that the parameters
11+
do what we expect.
12+
"""
13+
14+
from test_framework.test_framework import BitcoinTestFramework
15+
from test_framework.util import assert_equal
16+
17+
class SimplicityActivationTest(BitcoinTestFramework):
18+
def set_test_params(self):
19+
self.setup_clean_chain = True
20+
self.num_nodes = 1
21+
22+
def skip_test_if_missing_module(self):
23+
self.skip_if_no_wallet()
24+
25+
def test_activation(self, rpc, activation_height):
26+
self.log.info("Testing activation at height %d" % activation_height)
27+
activation_height = 128 * ((activation_height + 127) // 128)
28+
29+
assert_equal(rpc.getblockcount(), 0)
30+
31+
blocks = self.generatetoaddress(rpc, activation_height - 2, rpc.getnewaddress())
32+
assert_equal(rpc.getblockcount(), activation_height - 2)
33+
34+
for n, block in enumerate(blocks):
35+
decode = rpc.getblockheader(block)
36+
if n < 143:
37+
assert_equal (decode["versionHex"], "20000000")
38+
elif n < 431:
39+
# TESTDUMMY deployment: 144 blocks active, 144 blocks locked in
40+
assert_equal (decode["versionHex"], "30000000")
41+
else:
42+
assert_equal (decode["versionHex"], "20000000")
43+
44+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "defined")
45+
# The 1023rd block does not signal, but changes status-next to "started" from "defined"
46+
# bitcoin PR #23508 changed bip9 status to the current block instead of the next block
47+
blocks = self.generatetoaddress(rpc, 1, rpc.getnewaddress())
48+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "defined")
49+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status-next"], "started")
50+
assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "20000000")
51+
52+
blocks = self.generatetoaddress(rpc, 127, rpc.getnewaddress())
53+
for n, block in enumerate(blocks):
54+
decode = rpc.getblockheader(block)
55+
assert_equal (decode["versionHex"], "21000000")
56+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
57+
58+
# Fail to signal on the 128th block. Since the threshold for Simplicity is
59+
# 100% this will prevent activation. Note that our period is 128, not
60+
# 144 (the default), as we have overridden the period for Simplicity. On
61+
# the main Liquid chain it is overridden to be one week of signalling.
62+
block = rpc.getnewblockhex()
63+
block = block[:7] + "0" + block[8:] # turn off Simplicity signal
64+
rpc.submitblock(block)
65+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
66+
67+
# Run through another 128 blocks, without failing to signal
68+
blocks = self.generatetoaddress(rpc, 127, rpc.getnewaddress())
69+
for n, block in enumerate(blocks):
70+
decode = rpc.getblockheader(block)
71+
assert_equal (decode["versionHex"], "21000000")
72+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
73+
# The 128th block then switches from "started" to "locked_in"
74+
blocks = self.generatetoaddress(rpc, 1, rpc.getnewaddress())
75+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
76+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status-next"], "locked_in")
77+
assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "21000000")
78+
79+
# Run through another 128 blocks, which will go from "locked in" to "active" regardless of signalling
80+
blocks = self.generatetoaddress(rpc, 127, rpc.getnewaddress())
81+
for n, block in enumerate(blocks):
82+
decode = rpc.getblockheader(block)
83+
assert_equal (decode["versionHex"], "21000000")
84+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "locked_in")
85+
block = rpc.getnewblockhex()
86+
block = block[:7] + "0" + block[8:] # turn off Simplicity signal
87+
rpc.submitblock(block)
88+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "locked_in")
89+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status-next"], "active")
90+
91+
# After the state is "active", signallng stops by default.
92+
blocks = self.generatetoaddress(rpc, 1, self.nodes[0].getnewaddress())
93+
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "active")
94+
assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "20000000")
95+
96+
def run_test(self):
97+
# Test that regtest nodes never signal Simplicity or Simplicity by default
98+
self.log.info("Testing node not configured to activate Simplicity")
99+
blocks = self.generatetoaddress(self.nodes[0], 2500, self.nodes[0].getnewaddress())
100+
assert_equal(self.nodes[0].getblockcount(), 2500)
101+
for n, block in enumerate(blocks):
102+
decode = self.nodes[0].getblockheader(block)
103+
if n < 143:
104+
assert_equal (decode["versionHex"], "20000000")
105+
elif n < 431:
106+
# TESTDUMMY deployment: 144 blocks active, 144 blocks locked in
107+
assert_equal (decode["versionHex"], "30000000")
108+
else:
109+
assert_equal (decode["versionHex"], "20000000")
110+
111+
# Test activation starting from height 1000
112+
# Note that for Simplicity this is an illogical combination (Simplicity without
113+
# Taproot) but for purposes of this test it's fine.
114+
self.restart_node(0, ["-evbparams=simplicity:500:::"])
115+
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(1))
116+
self.test_activation(self.nodes[0], 500)
117+
118+
if __name__ == '__main__':
119+
SimplicityActivationTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@
241241
'p2p_invalid_locator.py',
242242
'p2p_invalid_block.py',
243243
'feature_elements_taproot_activation.py',
244+
'feature_elements_simplicity_activation.py',
244245
# ELEMENTS: needs to be fixed
245246
#'p2p_invalid_messages.py',
246247
'p2p_invalid_tx.py',

0 commit comments

Comments
 (0)