Skip to content

Commit aa2420c

Browse files
authored
Merge pull request #1368 from apoelstra/2024-10--simplicity-activation
simplicity: define liquid testnet activation parameters
2 parents 2534141 + 626e3ae commit aa2420c

File tree

6 files changed

+135
-1
lines changed

6 files changed

+135
-1
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,7 @@ bitcoin_chainstate_LDADD = \
939939
$(LIBBITCOIN_CRYPTO) \
940940
$(LIBUNIVALUE) \
941941
$(LIBSECP256K1) \
942+
$(LIBELEMENTSSIMPLICITY) \
942943
$(LIBLEVELDB) \
943944
$(LIBLEVELDB_SSE42) \
944945
$(LIBMEMENV)

src/chainparams.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,11 @@ class CRegTestParams : public CChainParams {
627627

628628
// Simplicity
629629
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 24;
630-
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
630+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
631631
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
632632
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].min_activation_height = 0; // No activation delay
633+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nPeriod = 128; // test ability to change from default
634+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nThreshold = 128;
633635

634636
consensus.nMinimumChainWork = uint256{};
635637
consensus.defaultAssumeValid = uint256{};
@@ -1034,6 +1036,10 @@ class CLiquidTestNetParams : public CCustomParams {
10341036
base58Prefixes[BLINDED_ADDRESS] = std::vector<unsigned char>(1, 23);
10351037
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, base58Prefixes[SECRET_KEY][0]);
10361038

1039+
// turn on Simplicity unconditionally on Liquid Testnet
1040+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
1041+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
1042+
10371043
// disable automatic dynafed
10381044
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = 0;
10391045

@@ -1286,6 +1292,8 @@ class CLiquidV1Params : public CChainParams {
12861292
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
12871293
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
12881294
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].min_activation_height = 0; // No activation delay
1295+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nPeriod = 10080; // one week...
1296+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nThreshold = 10080; // ...of 100% signalling
12891297

12901298
// Activated from block 1,000,000.
12911299
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25;

src/rpc/blockchain.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,6 +1837,7 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const Consensus::Params&
18371837
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_DYNA_FED);
18381838
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
18391839
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TAPROOT);
1840+
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_SIMPLICITY);
18401841
return softforks;
18411842
}
18421843
} // anon namespace
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/feature_taproot.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,10 @@ def set_test_params(self):
13021302
self.wallet_names = [None, self.default_wallet_name]
13031303
else:
13041304
self.extra_args[0].append("-vbparams=taproot:1:1")
1305+
# ELEMENTS: both nodes have Simplicity active. We activate one with evbparams
1306+
# and the other with vbparams to check that both work.
1307+
self.extra_args[0].append("-vbparams=simplicity:-1:1")
1308+
self.extra_args[1].append("-evbparams=simplicity:-1:::")
13051309

13061310
def setup_nodes(self):
13071311
self.add_nodes(self.num_nodes, self.extra_args, versions=[

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)