Skip to content

Commit b26d38f

Browse files
authored
Merge pull request #1441 from psgreco/elem-23.3.0rc6
Prepare 23.3.0rc6
2 parents 1b7ea4c + 06880d6 commit b26d38f

12 files changed

+260
-294
lines changed

SECURITY.md

Lines changed: 61 additions & 274 deletions
Large diffs are not rendered by default.

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ AC_PREREQ([2.69])
22
define(_CLIENT_VERSION_MAJOR, 23)
33
define(_CLIENT_VERSION_MINOR, 3)
44
define(_CLIENT_VERSION_BUILD, 0)
5-
define(_CLIENT_VERSION_RC, 5)
5+
define(_CLIENT_VERSION_RC, 6)
66
define(_CLIENT_VERSION_IS_RELEASE, true)
77
define(_COPYRIGHT_YEAR, 2024)
88
define(_COPYRIGHT_HOLDERS,[The %s developers])

src/blindpsbt.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ bool CreateAssetSurjectionProof(std::vector<unsigned char>& output_proof, const
6868

6969
bool VerifyBlindAssetProof(const uint256& asset, const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset)
7070
{
71+
if (conf_asset.vchCommitment.size() != CConfidentialAsset::nCommittedSize || proof.empty()) {
72+
return false;
73+
}
7174
secp256k1_surjectionproof surj_proof;
7275
if (secp256k1_surjectionproof_parse(secp256k1_blind_context, &surj_proof, proof.data(), proof.size()) == 0) {
7376
return false;
7477
}
75-
7678
secp256k1_generator blinded_asset_gen;
7779
if (secp256k1_generator_parse(secp256k1_blind_context, &blinded_asset_gen, conf_asset.vchCommitment.data()) == 0) {
7880
return false;

src/chainparams.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ class CMainParams : public CChainParams {
215215
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 709632; // Approximately November 12th, 2021
216216

217217
// Simplicity
218-
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 24;
218+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 21;
219219
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
220220
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
221221
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].min_activation_height = 0; // No activation delay
@@ -361,7 +361,7 @@ class CTestNetParams : public CChainParams {
361361
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
362362

363363
// Simplicity
364-
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 24;
364+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 21;
365365
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
366366
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
367367
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].min_activation_height = 0; // No activation delay
@@ -527,7 +527,7 @@ class SigNetParams : public CChainParams {
527527
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
528528

529529
// Simplicity
530-
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 24;
530+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 21;
531531
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
532532
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
533533
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].min_activation_height = 0; // No activation delay
@@ -626,7 +626,7 @@ class CRegTestParams : public CChainParams {
626626
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nThreshold = 128;
627627

628628
// Simplicity
629-
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 24;
629+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 21;
630630
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
@@ -1288,7 +1288,7 @@ class CLiquidV1Params : public CChainParams {
12881288
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nThreshold = 10080; // ...of 100% signalling
12891289

12901290
// Simplicity
1291-
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 24;
1291+
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].bit = 21;
12921292
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
12931293
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
12941294
consensus.vDeployments[Consensus::DEPLOYMENT_SIMPLICITY].min_activation_height = 0; // No activation delay

src/confidential_validation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
390390
}
391391
if (!ptxoutwit)
392392
return false;
393+
if (asset.vchCommitment.size() != CConfidentialAsset::nCommittedSize || ptxoutwit->vchSurjectionproof.empty()) {
394+
return false;
395+
}
393396
if (secp256k1_generator_parse(secp256k1_ctx_verify_amounts, &gen, &asset.vchCommitment[0]) != 1)
394397
return false;
395398

src/policy/policy.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static const unsigned int MAX_STANDARD_SCRIPTSIG_SIZE = 1650;
5555
* standard and should be done with care and ideally rarely. It makes sense to
5656
* only increase the dust limit after prior releases were already not creating
5757
* outputs below the new threshold */
58-
static const unsigned int DUST_RELAY_TX_FEE = 3000;
58+
static const unsigned int DUST_RELAY_TX_FEE = 100;
5959
/**
6060
* Standard script verification flags that standard transactions will comply
6161
* with. However scripts violating these flags may still be present in valid
@@ -89,6 +89,9 @@ static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCR
8989
static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE |
9090
LOCKTIME_MEDIAN_TIME_PAST;
9191

92+
// ELEMENTS: keep a copy of the upstream default dust relay fee rate
93+
static const unsigned int DUST_RELAY_TX_FEE_BITCOIN = 3000;
94+
9295
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFee);
9396

9497
bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee);

src/test/transaction_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
795795
CheckIsStandard(t);
796796

797797
// Check dust with default relay fee:
798+
dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE_BITCOIN); // ELEMENTS: use the Bitcoin default dust relay feerate
798799
CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK() / 1000;
799800
BOOST_CHECK_EQUAL(nDustThreshold, 546);
800801
// dust:
@@ -830,7 +831,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
830831
// not dust:
831832
t.vout[0].nValue = 674;
832833
CheckIsStandard(t);
833-
dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
834+
dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE_BITCOIN); // ELEMENTS: use the Bitcoin default dust relay feerate
834835

835836
t.vout[0].scriptPubKey = CScript() << OP_1;
836837
CheckIsNotStandard(t, "scriptpubkey");

test/functional/feature_confidential_transactions.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,44 @@ def test_wallet_recovery(self):
106106
# clean up blind_details
107107
os.remove(file_path)
108108

109+
def test_no_surj(self):
110+
self.generate(self.nodes[0], 1)
111+
112+
tx_hex = self.nodes[0].createrawtransaction([], [{self.nodes[1].getnewaddress(): 1000}])
113+
tx_hex = self.nodes[0].fundrawtransaction(tx_hex)['hex']
114+
tx_hex = self.nodes[0].blindrawtransaction(tx_hex)
115+
# coming from initial free coins: no need to sign
116+
assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]['allowed'], True) # tx is ok
117+
118+
# remove a surjection proof from the tx
119+
tx = CTransaction()
120+
tx.deserialize(io.BytesIO(bytes.fromhex(tx_hex)))
121+
tx.wit.vtxoutwit[0].vchSurjectionproof = b''
122+
tx_hex = tx.serialize().hex()
123+
124+
# Both of these make the node crash
125+
assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]['allowed'], False)
126+
assert_raises_rpc_error(-26, "bad-txns-in-ne-out", self.nodes[0].sendrawtransaction, tx_hex)
127+
128+
def test_no_range(self):
129+
self.generate(self.nodes[0], 1)
130+
131+
tx_hex = self.nodes[0].createrawtransaction([], [{self.nodes[1].getnewaddress(): 1000}])
132+
tx_hex = self.nodes[0].fundrawtransaction(tx_hex)['hex']
133+
tx_hex = self.nodes[0].blindrawtransaction(tx_hex)
134+
# coming from initial free coins: no need to sign
135+
assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]['allowed'], True) # tx is ok
136+
137+
# remove a surjection proof from the tx
138+
tx = CTransaction()
139+
tx.deserialize(io.BytesIO(bytes.fromhex(tx_hex)))
140+
tx.wit.vtxoutwit[0].vchRangeproof = b''
141+
tx_hex = tx.serialize().hex()
142+
143+
# Both of these make the node crash
144+
assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]['allowed'], False)
145+
assert_raises_rpc_error(-26, "bad-txns-in-ne-out", self.nodes[0].sendrawtransaction, tx_hex)
146+
109147
def test_null_rangeproof_enforcement(self):
110148
self.generate(self.nodes[0], 1)
111149

@@ -160,6 +198,12 @@ def test_null_rangeproof_enforcement(self):
160198

161199
def run_test(self):
162200

201+
print("Testing a transaction with a missing surjection proof")
202+
self.test_no_surj()
203+
204+
print("Testing a transaction with a missing range proof")
205+
self.test_no_range()
206+
163207
print("Testing that null issuances must have null rangeproofs")
164208
self.test_null_rangeproof_enforcement()
165209

test/functional/feature_elements_simplicity_activation.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class SimplicityActivationTest(BitcoinTestFramework):
1818
def set_test_params(self):
1919
self.setup_clean_chain = True
2020
self.num_nodes = 1
21+
self.extra_args = [["-evbparams=dynafed:0:::"]]
2122

2223
def skip_test_if_missing_module(self):
2324
self.skip_if_no_wallet()
@@ -36,8 +37,8 @@ def test_activation(self, rpc, activation_height):
3637
if n < 143:
3738
assert_equal (decode["versionHex"], "20000000")
3839
elif n < 431:
39-
# TESTDUMMY deployment: 144 blocks active, 144 blocks locked in
40-
assert_equal (decode["versionHex"], "30000000")
40+
# TESTDUMMY and DYNAFED deployment: 144 blocks active, 144 blocks locked in
41+
assert_equal (decode["versionHex"], "32000000")
4142
else:
4243
assert_equal (decode["versionHex"], "20000000")
4344

@@ -52,38 +53,38 @@ def test_activation(self, rpc, activation_height):
5253
blocks = self.generatetoaddress(rpc, 127, rpc.getnewaddress())
5354
for n, block in enumerate(blocks):
5455
decode = rpc.getblockheader(block)
55-
assert_equal (decode["versionHex"], "21000000")
56+
assert_equal (decode["versionHex"], "20200000")
5657
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
5758

5859
# Fail to signal on the 128th block. Since the threshold for Simplicity is
5960
# 100% this will prevent activation. Note that our period is 128, not
6061
# 144 (the default), as we have overridden the period for Simplicity. On
6162
# the main Liquid chain it is overridden to be one week of signalling.
6263
block = rpc.getnewblockhex()
63-
block = block[:7] + "0" + block[8:] # turn off Simplicity signal
64+
block = block[:4] + "0" + block[5:] # turn off Simplicity signal
6465
rpc.submitblock(block)
6566
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
6667

6768
# Run through another 128 blocks, without failing to signal
6869
blocks = self.generatetoaddress(rpc, 127, rpc.getnewaddress())
6970
for n, block in enumerate(blocks):
7071
decode = rpc.getblockheader(block)
71-
assert_equal (decode["versionHex"], "21000000")
72+
assert_equal (decode["versionHex"], "20200000")
7273
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
7374
# The 128th block then switches from "started" to "locked_in"
7475
blocks = self.generatetoaddress(rpc, 1, rpc.getnewaddress())
7576
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "started")
7677
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status_next"], "locked_in")
77-
assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "21000000")
78+
assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "20200000")
7879

7980
# Run through another 128 blocks, which will go from "locked in" to "active" regardless of signalling
8081
blocks = self.generatetoaddress(rpc, 127, rpc.getnewaddress())
8182
for n, block in enumerate(blocks):
8283
decode = rpc.getblockheader(block)
83-
assert_equal (decode["versionHex"], "21000000")
84+
assert_equal (decode["versionHex"], "20200000")
8485
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "locked_in")
8586
block = rpc.getnewblockhex()
86-
block = block[:7] + "0" + block[8:] # turn off Simplicity signal
87+
block = block[:4] + "0" + block[5:] # turn off Simplicity signal
8788
rpc.submitblock(block)
8889
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status"], "locked_in")
8990
assert_equal(rpc.getdeploymentinfo()["deployments"]["simplicity"]["bip9"]["status_next"], "active")
@@ -103,15 +104,15 @@ def run_test(self):
103104
if n < 143:
104105
assert_equal (decode["versionHex"], "20000000")
105106
elif n < 431:
106-
# TESTDUMMY deployment: 144 blocks active, 144 blocks locked in
107-
assert_equal (decode["versionHex"], "30000000")
107+
# TESTDUMMY and DYNAFED deployment: 144 blocks active, 144 blocks locked in
108+
assert_equal (decode["versionHex"], "32000000")
108109
else:
109110
assert_equal (decode["versionHex"], "20000000")
110111

111112
# Test activation starting from height 1000
112113
# Note that for Simplicity this is an illogical combination (Simplicity without
113114
# Taproot) but for purposes of this test it's fine.
114-
self.restart_node(0, ["-evbparams=simplicity:500:::"])
115+
self.restart_node(0, ["-evbparams=dynafed:0:::", "-evbparams=simplicity:500:::"])
115116
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(1))
116117
self.test_activation(self.nodes[0], 500)
117118

test/functional/mempool_accept.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def set_test_params(self):
4646
'-txindex',
4747
'-txindex','-permitbaremultisig=0',
4848
'-multi_data_permitted=1', # Elements test
49+
'-dustrelayfee=0.00003000', # ELEMENTS: use the Bitcoin default dust relay fee rate
4950
]] * self.num_nodes
5051
self.supports_cli = False
5152

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
'wallet_elements_regression_1172.py --legacy-wallet',
114114
'wallet_elements_regression_1259.py --legacy-wallet',
115115
'wallet_elements_21million.py',
116+
'wallet_elements_dust_relay.py',
116117
'feature_trim_headers.py',
117118
# Longest test should go first, to favor running tests in parallel
118119
'wallet_hd.py --legacy-wallet',

0 commit comments

Comments
 (0)