Skip to content

Commit 2d6711c

Browse files
committed
Merge #1534: Prepare 23.3.3rc1
6c45fa0 Update manpages (Pablo Greco) 3df1851 Bump version to 23.3.3-rc1 (Pablo Greco) a18a88b grammar: prefer peg-in to pegin in messages (Byron Hambly) 90b2b3b test: add pegin subsidy functional test (Byron Hambly) 186bb25 validation: check for peg-in subsidy and minimum (Byron Hambly) 51c89c6 subsidy: implementation for claimpegin, createrawpegin, and RPCs (Byron Hambly) 94cde59 subsidy: add chainparams and init (Byron Hambly) f3b63f4 DecomposePeginWitness: fix deserialization flags for MerkleBlock proof (Byron Hambly) Pull request description: Updates master to 7791d31 which ELIP 202 and bumps version/manpages ACKs for top commit: tomt1664: Tested ACK [6c45fa0](6c45fa0) delta1: ACK 6c45fa0; diff looks as expected, built and tested locally Tree-SHA512: 514f29b67a3ede75405391c6b2c34ae636042c6bf4189bcc0d85641f824f2d9ba0664b77ea3ae95f98b29b284823b8916688ff1e00699189de03bea4646f8cd0
2 parents a3752d0 + 6c45fa0 commit 2d6711c

20 files changed

+1457
-49
lines changed

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
AC_PREREQ([2.69])
22
define(_CLIENT_VERSION_MAJOR, 23)
33
define(_CLIENT_VERSION_MINOR, 3)
4-
define(_CLIENT_VERSION_BUILD, 2)
5-
define(_CLIENT_VERSION_RC, 0)
4+
define(_CLIENT_VERSION_BUILD, 3)
5+
define(_CLIENT_VERSION_RC, 1)
66
define(_CLIENT_VERSION_IS_RELEASE, true)
77
define(_COPYRIGHT_YEAR, 2026)
88
define(_COPYRIGHT_HOLDERS,[The %s developers])

doc/man/elements-cli.1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
2-
.TH ELEMENTS-CLI "1" "February 2026" "elements-cli v23.3.2" "User Commands"
2+
.TH ELEMENTS-CLI "1" "February 2026" "elements-cli v23.3.3" "User Commands"
33
.SH NAME
4-
elements-cli \- manual page for elements-cli v23.3.2
4+
elements-cli \- manual page for elements-cli v23.3.3
55
.SH SYNOPSIS
66
.B elements-cli
77
[\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Elements Core\/\fR
@@ -15,7 +15,7 @@ elements-cli \- manual page for elements-cli v23.3.2
1515
.B elements-cli
1616
[\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR
1717
.SH DESCRIPTION
18-
Elements Core RPC client version v23.3.2
18+
Elements Core RPC client version v23.3.3
1919
.SH OPTIONS
2020
.HP
2121
\-?

doc/man/elements-qt.1

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
2-
.TH ELEMENTS-QT "1" "February 2026" "elements-qt v23.3.2" "User Commands"
2+
.TH ELEMENTS-QT "1" "February 2026" "elements-qt v23.3.3" "User Commands"
33
.SH NAME
4-
elements-qt \- manual page for elements-qt v23.3.2
4+
elements-qt \- manual page for elements-qt v23.3.3
55
.SH SYNOPSIS
66
.B elements-qt
77
[\fI\,command-line options\/\fR]
88
.SH DESCRIPTION
9-
Elements Core version v23.3.2
9+
Elements Core version v23.3.3
1010
.SH OPTIONS
1111
.HP
1212
\-?
@@ -755,6 +755,30 @@ address. (default: 111)
755755
The byte prefix, in decimal, of the parent chain's base58 script
756756
address. (default: 196)
757757
.HP
758+
\fB\-peginminamount\fR
759+
.IP
760+
The minimum value for a peg\-in transaction after peginminheight
761+
(default: unset).
762+
.HP
763+
\fB\-peginminheight\fR
764+
.IP
765+
The block height at which a minimum peg\-in value is enforced (default:
766+
not active).
767+
.HP
768+
\fB\-peginsubsidyheight\fR
769+
.IP
770+
The block height at which peg\-in transactions must have a burn subsidy
771+
(default: not active). The subsidy is an OP_RETURN output, with
772+
its value equal to the feerate of the parent transaction
773+
multiplied by the vsize of spending the P2WSH output created by
774+
the peg\-in (feerate * 396 sats for liquidv1).
775+
.HP
776+
\fB\-peginsubsidythreshold\fR
777+
.IP
778+
The output value below which peg\-in transactions must have a burn
779+
subsidy (default: 0). Peg\-ins above this value do not require the
780+
subsidy.
781+
.HP
758782
\fB\-pubkeyprefix\fR
759783
.IP
760784
The byte prefix, in decimal, of the chain's base58 pubkey address.
@@ -1057,7 +1081,7 @@ pre\-dynamic federations. Only used for testing in custom chains.
10571081
.HP
10581082
\fB\-peginconfirmationdepth=\fR<n>
10591083
.IP
1060-
Pegin claims must be this deep to be considered valid. (default: 8)
1084+
Peg\-in claims must be this deep to be considered valid. (default: 8)
10611085
.HP
10621086
\fB\-total_valid_epochs\fR
10631087
.IP

doc/man/elements-tx.1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
2-
.TH ELEMENTS-TX "1" "February 2026" "elements-tx v23.3.2" "User Commands"
2+
.TH ELEMENTS-TX "1" "February 2026" "elements-tx v23.3.3" "User Commands"
33
.SH NAME
4-
elements-tx \- manual page for elements-tx v23.3.2
4+
elements-tx \- manual page for elements-tx v23.3.3
55
.SH SYNOPSIS
66
.B elements-tx
77
[\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded Elements transaction\/\fR
88
.br
99
.B elements-tx
1010
[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded Elements transaction\/\fR
1111
.SH DESCRIPTION
12-
Elements Core elements\-tx utility version v23.3.2
12+
Elements Core elements\-tx utility version v23.3.3
1313
.SH OPTIONS
1414
.HP
1515
\-?

doc/man/elements-util.1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
2-
.TH ELEMENTS-UTIL "1" "February 2026" "elements-util v23.3.2" "User Commands"
2+
.TH ELEMENTS-UTIL "1" "February 2026" "elements-util v23.3.3" "User Commands"
33
.SH NAME
4-
elements-util \- manual page for elements-util v23.3.2
4+
elements-util \- manual page for elements-util v23.3.3
55
.SH SYNOPSIS
66
.B bitcoin-util
77
[\fI\,options\/\fR] [\fI\,commands\/\fR] \fI\,Do stuff\/\fR
88
.SH DESCRIPTION
9-
Elements Core bitcoin\-util utility version v23.3.2
9+
Elements Core bitcoin\-util utility version v23.3.3
1010
.SH OPTIONS
1111
.HP
1212
\-?

doc/man/elements-wallet.1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
2-
.TH ELEMENTS-WALLET "1" "February 2026" "elements-wallet v23.3.2" "User Commands"
2+
.TH ELEMENTS-WALLET "1" "February 2026" "elements-wallet v23.3.3" "User Commands"
33
.SH NAME
4-
elements-wallet \- manual page for elements-wallet v23.3.2
4+
elements-wallet \- manual page for elements-wallet v23.3.3
55
.SH DESCRIPTION
6-
Elements Core elements\-wallet version v23.3.2
6+
Elements Core elements\-wallet version v23.3.3
77
.PP
88
elements\-wallet is an offline tool for creating and interacting with Elements Core wallet files.
99
By default elements\-wallet will act on wallets in the default mainnet wallet directory in the datadir.

doc/man/elementsd.1

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
2-
.TH ELEMENTSD "1" "February 2026" "elementsd v23.3.2" "User Commands"
2+
.TH ELEMENTSD "1" "February 2026" "elementsd v23.3.3" "User Commands"
33
.SH NAME
4-
elementsd \- manual page for elementsd v23.3.2
4+
elementsd \- manual page for elementsd v23.3.3
55
.SH SYNOPSIS
66
.B elementsd
77
[\fI\,options\/\fR] \fI\,Start Elements Core\/\fR
88
.SH DESCRIPTION
9-
Elements Core version v23.3.2
9+
Elements Core version v23.3.3
1010
.SH OPTIONS
1111
.HP
1212
\-?
@@ -755,6 +755,30 @@ address. (default: 111)
755755
The byte prefix, in decimal, of the parent chain's base58 script
756756
address. (default: 196)
757757
.HP
758+
\fB\-peginminamount\fR
759+
.IP
760+
The minimum value for a peg\-in transaction after peginminheight
761+
(default: unset).
762+
.HP
763+
\fB\-peginminheight\fR
764+
.IP
765+
The block height at which a minimum peg\-in value is enforced (default:
766+
not active).
767+
.HP
768+
\fB\-peginsubsidyheight\fR
769+
.IP
770+
The block height at which peg\-in transactions must have a burn subsidy
771+
(default: not active). The subsidy is an OP_RETURN output, with
772+
its value equal to the feerate of the parent transaction
773+
multiplied by the vsize of spending the P2WSH output created by
774+
the peg\-in (feerate * 396 sats for liquidv1).
775+
.HP
776+
\fB\-peginsubsidythreshold\fR
777+
.IP
778+
The output value below which peg\-in transactions must have a burn
779+
subsidy (default: 0). Peg\-ins above this value do not require the
780+
subsidy.
781+
.HP
758782
\fB\-pubkeyprefix\fR
759783
.IP
760784
The byte prefix, in decimal, of the chain's base58 pubkey address.
@@ -1035,7 +1059,7 @@ pre\-dynamic federations. Only used for testing in custom chains.
10351059
.HP
10361060
\fB\-peginconfirmationdepth=\fR<n>
10371061
.IP
1038-
Pegin claims must be this deep to be considered valid. (default: 8)
1062+
Peg\-in claims must be this deep to be considered valid. (default: 8)
10391063
.HP
10401064
\fB\-total_valid_epochs\fR
10411065
.IP

src/chainparams.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77

88
#include <chainparamsseeds.h>
99
#include <consensus/merkle.h>
10+
#include <crypto/sha256.h>
1011
#include <deploymentinfo.h>
1112
#include <hash.h> // for signet block challenge hash
1213
#include <issuance.h>
1314
#include <primitives/transaction.h>
15+
#include <util/moneystr.h>
1416
#include <util/system.h>
15-
#include <crypto/sha256.h>
1617

1718
#include <assert.h>
1819

@@ -232,6 +233,8 @@ class CMainParams : public CChainParams {
232233
multi_data_permitted = false;
233234
accept_discount_ct = false;
234235
create_discount_ct = false;
236+
pegin_subsidy = PeginSubsidy();
237+
pegin_minimum = PeginMinimum();
235238
consensus.has_parent_chain = false;
236239
g_signed_blocks = false;
237240
g_con_elementsmode = false;
@@ -379,6 +382,8 @@ class CTestNetParams : public CChainParams {
379382
multi_data_permitted = false;
380383
accept_discount_ct = false;
381384
create_discount_ct = false;
385+
pegin_subsidy = PeginSubsidy();
386+
pegin_minimum = PeginMinimum();
382387
consensus.has_parent_chain = false;
383388
g_signed_blocks = false;
384389
g_con_elementsmode = false;
@@ -544,6 +549,8 @@ class SigNetParams : public CChainParams {
544549
multi_data_permitted = false;
545550
accept_discount_ct = false;
546551
create_discount_ct = false;
552+
pegin_subsidy = PeginSubsidy();
553+
pegin_minimum = PeginMinimum();
547554
consensus.has_parent_chain = false;
548555
g_signed_blocks = false; // lol
549556
g_con_elementsmode = false;
@@ -648,6 +655,8 @@ class CRegTestParams : public CChainParams {
648655
multi_data_permitted = false;
649656
accept_discount_ct = false;
650657
create_discount_ct = false;
658+
pegin_subsidy = PeginSubsidy();
659+
pegin_minimum = PeginMinimum();
651660
consensus.has_parent_chain = false;
652661
g_signed_blocks = false;
653662
g_con_elementsmode = false;
@@ -792,6 +801,39 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
792801
}
793802
}
794803

804+
// ELEMENTS
805+
PeginSubsidy ParsePeginSubsidy(const ArgsManager& args) {
806+
PeginSubsidy pegin_subsidy;
807+
808+
pegin_subsidy.height = args.GetIntArg("-peginsubsidyheight", std::numeric_limits<int>::max());
809+
if (pegin_subsidy.height < 0) {
810+
throw std::runtime_error(strprintf("Invalid block height (%d) for -peginsubsidyheight. Must be positive.", pegin_subsidy.height));
811+
}
812+
if (std::optional<CAmount> amount = ParseMoney(args.GetArg("-peginsubsidythreshold", "0"))) {
813+
pegin_subsidy.threshold = amount.value();
814+
} else {
815+
throw std::runtime_error("Invalid -peginsubsidythreshold");
816+
}
817+
818+
return pegin_subsidy;
819+
};
820+
821+
PeginMinimum ParsePeginMinimum(const ArgsManager& args) {
822+
PeginMinimum pegin_minimum;
823+
824+
pegin_minimum.height = args.GetIntArg("-peginminheight", std::numeric_limits<int>::max());
825+
if (pegin_minimum.height < 0) {
826+
throw std::runtime_error(strprintf("Invalid block height (%d) for -peginminheight. Must be positive.", pegin_minimum.height));
827+
}
828+
if (std::optional<CAmount> amount = ParseMoney(args.GetArg("-peginminamount", "0"))) {
829+
pegin_minimum.amount = amount.value();
830+
} else {
831+
throw std::runtime_error("Invalid -peginminamount");
832+
}
833+
834+
return pegin_minimum;
835+
};
836+
795837
/**
796838
* Custom params for testing.
797839
*/
@@ -932,6 +974,11 @@ class CCustomParams : public CRegTestParams {
932974
consensus.start_p2wsh_script = args.GetIntArg("-con_start_p2wsh_script", consensus.start_p2wsh_script);
933975
create_discount_ct = args.GetBoolArg("-creatediscountct", create_discount_ct);
934976
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", accept_discount_ct) || create_discount_ct;
977+
pegin_subsidy = ParsePeginSubsidy(args);
978+
pegin_minimum = ParsePeginMinimum(args);
979+
if (pegin_subsidy.threshold < pegin_minimum.amount) {
980+
throw std::runtime_error(strprintf("Peg-in subsidy threshold (%s) must be greater than or equal to peg-in minimum amount (%s)", FormatMoney(pegin_subsidy.threshold), FormatMoney(pegin_minimum.amount)));
981+
}
935982

936983
// Calculate pegged Bitcoin asset
937984
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
@@ -1178,6 +1225,11 @@ class CLiquidV1Params : public CChainParams {
11781225
multi_data_permitted = true;
11791226
create_discount_ct = args.GetBoolArg("-creatediscountct", false);
11801227
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", true) || create_discount_ct;
1228+
pegin_subsidy = ParsePeginSubsidy(args);
1229+
pegin_minimum = ParsePeginMinimum(args);
1230+
if (pegin_subsidy.threshold < pegin_minimum.amount) {
1231+
throw std::runtime_error(strprintf("Peg-in subsidy threshold (%s) must be greater than or equal to peg-in minimum amount (%s)", FormatMoney(pegin_subsidy.threshold), FormatMoney(pegin_minimum.amount)));
1232+
}
11811233

11821234
parentGenesisBlockHash = uint256S("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
11831235
const bool parent_genesis_is_null = parentGenesisBlockHash == uint256();
@@ -1538,6 +1590,11 @@ class CLiquidV1TestParams : public CLiquidV1Params {
15381590
multi_data_permitted = args.GetBoolArg("-multi_data_permitted", multi_data_permitted);
15391591
create_discount_ct = args.GetBoolArg("-creatediscountct", create_discount_ct);
15401592
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", accept_discount_ct) || create_discount_ct;
1593+
pegin_subsidy = ParsePeginSubsidy(args);
1594+
pegin_minimum = ParsePeginMinimum(args);
1595+
if (pegin_subsidy.threshold < pegin_minimum.amount) {
1596+
throw std::runtime_error(strprintf("Peg-in subsidy threshold (%s) must be greater than or equal to peg-in minimum amount (%s)", FormatMoney(pegin_subsidy.threshold), FormatMoney(pegin_minimum.amount)));
1597+
}
15411598

15421599
if (args.IsArgSet("-parentgenesisblockhash")) {
15431600
parentGenesisBlockHash = uint256S(args.GetArg("-parentgenesisblockhash", ""));

src/chainparams.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ struct CCheckpointData {
2828
}
2929
};
3030

31+
// ELEMENTS
32+
struct PeginSubsidy {
33+
int height{std::numeric_limits<int>::max()};
34+
CAmount threshold{0};
35+
36+
PeginSubsidy() {};
37+
bool IsDefined() {
38+
return threshold > 0 || height < std::numeric_limits<int>::max();
39+
};
40+
};
41+
42+
struct PeginMinimum {
43+
int height{std::numeric_limits<int>::max()};
44+
CAmount amount{0};
45+
46+
PeginMinimum() {};
47+
bool IsDefined() {
48+
return amount > 0 || height < std::numeric_limits<int>::max();
49+
};
50+
};
51+
3152
struct AssumeutxoHash : public BaseHash<uint256> {
3253
explicit AssumeutxoHash(const uint256& hash) : BaseHash(hash) {}
3354
};
@@ -138,6 +159,8 @@ class CChainParams
138159
bool GetMultiDataPermitted() const { return multi_data_permitted; }
139160
bool GetAcceptDiscountCT() const { return accept_discount_ct; }
140161
bool GetCreateDiscountCT() const { return create_discount_ct; }
162+
PeginSubsidy GetPeginSubsidy() const { return pegin_subsidy; }
163+
PeginMinimum GetPeginMinimum() const { return pegin_minimum; }
141164

142165
protected:
143166
CChainParams() {}
@@ -173,6 +196,8 @@ class CChainParams
173196
bool multi_data_permitted;
174197
bool accept_discount_ct;
175198
bool create_discount_ct;
199+
PeginSubsidy pegin_subsidy;
200+
PeginMinimum pegin_minimum;
176201
};
177202

178203
/**

src/dynafed.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,34 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre
123123
}
124124
}
125125

126+
bool ParseFedPegQuorum(const CScript& fedpegscript, int& t, int& n) {
127+
CScript::const_iterator it = fedpegscript.begin();
128+
std::vector<unsigned char> vch;
129+
opcodetype opcode;
130+
131+
// parse the required threshold number
132+
if (!fedpegscript.GetOp(it, opcode, vch)) return false;
133+
t = CScript::DecodeOP_N(opcode);
134+
if (t < 1 || t > MAX_PUBKEYS_PER_MULTISIG) return false;
135+
136+
// support a fedpegscript like OP_TRUE if we're at the end of the script
137+
if (it == fedpegscript.end()) return true;
138+
139+
// count the pubkeys
140+
int pubkeys = 0;
141+
while (fedpegscript.GetOp(it, opcode, vch)) {
142+
if (opcode != 0x21) break;
143+
if (vch.size() != 33) return false;
144+
pubkeys++;
145+
}
146+
147+
// parse the total number of pubkeys
148+
n = CScript::DecodeOP_N(opcode);
149+
if (n < 1 || n > MAX_PUBKEYS_PER_MULTISIG || n < t) return false;
150+
if (pubkeys != n) return false;
151+
152+
// the next opcode must be OP_CHECKMULTISIG
153+
if (!fedpegscript.GetOp(it, opcode, vch)) return false;
154+
155+
return opcode == OP_CHECKMULTISIG;
156+
}

0 commit comments

Comments
 (0)