Skip to content

Commit 8c5f681

Browse files
committed
Merge #18267: BIP-325: Signet [consensus]
8258c4c test: some sanity checks for consensus logic (Anthony Towns) e47ad37 test: basic signet tests (Karl-Johan Alm) 4c189ab test: add small signet fuzzer (practicalswift) ec9b25d test: signet network selection tests (Karl-Johan Alm) 3efe298 signet: hard-coded parameters for Signet Global Network VI (2020-09-07) (Karl-Johan Alm) c7898bc qt: update QT to support signet network (Karl-Johan Alm) a8de47a consensus: add signet validation (Karl-Johan Alm) e8990f1 add signet chain and accompanying parameters (Karl-Johan Alm) 404682b add signet basic support (signet.cpp) (Karl-Johan Alm) a2147d7 validation: move GetWitnessCommitmentIndex to consensus/validation (Karl-Johan Alm) Pull request description: This PR is a part of BIP-325 (https://github.com/bitcoin/bips/blob/master/bip-0325.mediawiki), and is a sub-PR of #16411. * Signet consensus (this) * Signet RPC tools (pending) * Signet utility scripts (contrib/signet) (pending) ACKs for top commit: jonatack: re-ACK 8258c4c per `git diff dbeea65 8258c4c`, only change since last review is updated `-signet*` config option naming. fjahr: re-ACK 8258c4c laanwj: ACK 8258c4c MarcoFalke: Approach ACK 8258c4c 🌵 Tree-SHA512: 5d158add96755910837feafa8214e13695b769a6aec3a2da753cf672618bef377fac43b0f4b772a87b25dd9f0c1c9b29f2789785d7a7d47a155cdcf48f7c975d
2 parents c0c409d + 8258c4c commit 8c5f681

21 files changed

+532
-44
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ BITCOIN_CORE_H = \
202202
script/signingprovider.h \
203203
script/standard.h \
204204
shutdown.h \
205+
signet.h \
205206
streams.h \
206207
support/allocators/secure.h \
207208
support/allocators/zeroafterfree.h \
@@ -322,6 +323,7 @@ libbitcoin_server_a_SOURCES = \
322323
rpc/server.cpp \
323324
script/sigcache.cpp \
324325
shutdown.cpp \
326+
signet.cpp \
325327
timedata.cpp \
326328
torcontrol.cpp \
327329
txdb.cpp \

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ FUZZ_TARGETS = \
137137
test/fuzz/secp256k1_ecdsa_signature_parse_der_lax \
138138
test/fuzz/service_deserialize \
139139
test/fuzz/signature_checker \
140+
test/fuzz/signet \
140141
test/fuzz/snapshotmetadata_deserialize \
141142
test/fuzz/span \
142143
test/fuzz/spanparsing \
@@ -1129,6 +1130,12 @@ test_fuzz_signature_checker_LDADD = $(FUZZ_SUITE_LD_COMMON)
11291130
test_fuzz_signature_checker_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
11301131
test_fuzz_signature_checker_SOURCES = test/fuzz/signature_checker.cpp
11311132

1133+
test_fuzz_signet_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
1134+
test_fuzz_signet_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
1135+
test_fuzz_signet_LDADD = $(FUZZ_SUITE_LD_COMMON)
1136+
test_fuzz_signet_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
1137+
test_fuzz_signet_SOURCES = test/fuzz/signet.cpp
1138+
11321139
test_fuzz_snapshotmetadata_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSNAPSHOTMETADATA_DESERIALIZE=1
11331140
test_fuzz_snapshotmetadata_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
11341141
test_fuzz_snapshotmetadata_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/chainparams.cpp

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <chainparamsseeds.h>
99
#include <consensus/merkle.h>
10+
#include <hash.h> // for signet block challenge hash
1011
#include <tinyformat.h>
1112
#include <util/system.h>
1213
#include <util/strencodings.h>
@@ -63,6 +64,8 @@ class CMainParams : public CChainParams {
6364
public:
6465
CMainParams() {
6566
strNetworkID = CBaseChainParams::MAIN;
67+
consensus.signet_blocks = false;
68+
consensus.signet_challenge.clear();
6669
consensus.nSubsidyHalvingInterval = 210000;
6770
consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22");
6871
consensus.BIP34Height = 227931;
@@ -172,6 +175,8 @@ class CTestNetParams : public CChainParams {
172175
public:
173176
CTestNetParams() {
174177
strNetworkID = CBaseChainParams::TESTNET;
178+
consensus.signet_blocks = false;
179+
consensus.signet_challenge.clear();
175180
consensus.nSubsidyHalvingInterval = 210000;
176181
consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105");
177182
consensus.BIP34Height = 21111;
@@ -250,13 +255,104 @@ class CTestNetParams : public CChainParams {
250255
}
251256
};
252257

258+
/**
259+
* Signet
260+
*/
261+
class SigNetParams : public CChainParams {
262+
public:
263+
explicit SigNetParams(const ArgsManager& args) {
264+
std::vector<uint8_t> bin;
265+
vSeeds.clear();
266+
267+
if (!args.IsArgSet("-signetchallenge")) {
268+
LogPrintf("Using default signet network\n");
269+
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
270+
vSeeds.emplace_back("178.128.221.177");
271+
vSeeds.emplace_back("2a01:7c8:d005:390::5");
272+
vSeeds.emplace_back("ntv3mtqw5wt63red.onion:38333");
273+
} else {
274+
const auto signet_challenge = args.GetArgs("-signetchallenge");
275+
if (signet_challenge.size() != 1) {
276+
throw std::runtime_error(strprintf("%s: -signetchallenge cannot be multiple values.", __func__));
277+
}
278+
bin = ParseHex(signet_challenge[0]);
279+
280+
LogPrintf("Signet with challenge %s\n", signet_challenge[0]);
281+
}
282+
283+
if (args.IsArgSet("-signetseednode")) {
284+
vSeeds = args.GetArgs("-signetseednode");
285+
}
286+
287+
strNetworkID = CBaseChainParams::SIGNET;
288+
consensus.signet_blocks = true;
289+
consensus.signet_challenge.assign(bin.begin(), bin.end());
290+
consensus.nSubsidyHalvingInterval = 210000;
291+
consensus.BIP34Height = 1;
292+
consensus.BIP65Height = 1;
293+
consensus.BIP66Height = 1;
294+
consensus.CSVHeight = 1;
295+
consensus.SegwitHeight = 1;
296+
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
297+
consensus.nPowTargetSpacing = 10 * 60;
298+
consensus.fPowAllowMinDifficultyBlocks = false;
299+
consensus.fPowNoRetargeting = false;
300+
consensus.nRuleChangeActivationThreshold = 1916;
301+
consensus.nMinerConfirmationWindow = 2016;
302+
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
303+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
304+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
305+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
306+
307+
// message start is defined as the first 4 bytes of the sha256d of the block script
308+
CHashWriter h(SER_DISK, 0);
309+
h << consensus.signet_challenge;
310+
uint256 hash = h.GetHash();
311+
memcpy(pchMessageStart, hash.begin(), 4);
312+
LogPrintf("Signet derived magic (message start): %s\n", HexStr({pchMessageStart, pchMessageStart + 4}));
313+
314+
nDefaultPort = 38333;
315+
nPruneAfterHeight = 1000;
316+
m_assumed_blockchain_size = 0;
317+
m_assumed_chain_state_size = 0;
318+
319+
genesis = CreateGenesisBlock(1598918400, 52613770, 0x1e0377ae, 1, 50 * COIN);
320+
consensus.hashGenesisBlock = genesis.GetHash();
321+
assert(consensus.hashGenesisBlock == uint256S("0x00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6"));
322+
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
323+
324+
vFixedSeeds.clear();
325+
326+
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
327+
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
328+
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
329+
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
330+
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
331+
332+
bech32_hrp = "tb";
333+
334+
fDefaultConsistencyChecks = false;
335+
fRequireStandard = true;
336+
m_is_test_chain = true;
337+
m_is_mockable_chain = false;
338+
339+
chainTxData = ChainTxData{
340+
0,
341+
0,
342+
0
343+
};
344+
}
345+
};
346+
253347
/**
254348
* Regression test
255349
*/
256350
class CRegTestParams : public CChainParams {
257351
public:
258352
explicit CRegTestParams(const ArgsManager& args) {
259353
strNetworkID = CBaseChainParams::REGTEST;
354+
consensus.signet_blocks = false;
355+
consensus.signet_challenge.clear();
260356
consensus.nSubsidyHalvingInterval = 150;
261357
consensus.BIP16Exception = uint256();
262358
consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
@@ -391,12 +487,15 @@ const CChainParams &Params() {
391487

392488
std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
393489
{
394-
if (chain == CBaseChainParams::MAIN)
490+
if (chain == CBaseChainParams::MAIN) {
395491
return std::unique_ptr<CChainParams>(new CMainParams());
396-
else if (chain == CBaseChainParams::TESTNET)
492+
} else if (chain == CBaseChainParams::TESTNET) {
397493
return std::unique_ptr<CChainParams>(new CTestNetParams());
398-
else if (chain == CBaseChainParams::REGTEST)
494+
} else if (chain == CBaseChainParams::SIGNET) {
495+
return std::unique_ptr<CChainParams>(new SigNetParams(gArgs));
496+
} else if (chain == CBaseChainParams::REGTEST) {
399497
return std::unique_ptr<CChainParams>(new CRegTestParams(gArgs));
498+
}
400499
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
401500
}
402501

src/chainparamsbase.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
const std::string CBaseChainParams::MAIN = "main";
1515
const std::string CBaseChainParams::TESTNET = "test";
16+
const std::string CBaseChainParams::SIGNET = "signet";
1617
const std::string CBaseChainParams::REGTEST = "regtest";
1718

1819
void SetupChainParamsBaseOptions(ArgsManager& argsman)
@@ -23,6 +24,9 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
2324
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
2425
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
2526
argsman.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
27+
argsman.AddArg("-signet", "Use the signet chain. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
28+
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
29+
argsman.AddArg("-signetseednode", "Specify a seed node for the signet network, in the hostname[:port] format, e.g. sig.net:1234 (may be used multiple times to specify multiple seed nodes; defaults to the global default signet test network seed node(s))", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
2630
}
2731

2832
static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
@@ -35,14 +39,16 @@ const CBaseChainParams& BaseParams()
3539

3640
std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
3741
{
38-
if (chain == CBaseChainParams::MAIN)
42+
if (chain == CBaseChainParams::MAIN) {
3943
return MakeUnique<CBaseChainParams>("", 8332);
40-
else if (chain == CBaseChainParams::TESTNET)
44+
} else if (chain == CBaseChainParams::TESTNET) {
4145
return MakeUnique<CBaseChainParams>("testnet3", 18332);
42-
else if (chain == CBaseChainParams::REGTEST)
46+
} else if (chain == CBaseChainParams::SIGNET) {
47+
return MakeUnique<CBaseChainParams>("signet", 38332);
48+
} else if (chain == CBaseChainParams::REGTEST) {
4349
return MakeUnique<CBaseChainParams>("regtest", 18443);
44-
else
45-
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
50+
}
51+
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
4652
}
4753

4854
void SelectBaseParams(const std::string& chain)

src/chainparamsbase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class CBaseChainParams
2121
/** Chain name strings */
2222
static const std::string MAIN;
2323
static const std::string TESTNET;
24+
static const std::string SIGNET;
2425
static const std::string REGTEST;
2526
///@}
2627

src/consensus/params.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ struct Params {
8080
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
8181
uint256 nMinimumChainWork;
8282
uint256 defaultAssumeValid;
83+
84+
/**
85+
* If true, witness commitments contain a payload equal to a Bitcoin Script solution
86+
* to the signet challenge. See BIP325.
87+
*/
88+
bool signet_blocks{false};
89+
std::vector<uint8_t> signet_challenge;
8390
};
8491
} // namespace Consensus
8592

src/consensus/validation.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
#include <primitives/transaction.h>
1313
#include <primitives/block.h>
1414

15+
/** Index marker for when no witness commitment is present in a coinbase transaction. */
16+
static constexpr int NO_WITNESS_COMMITMENT{-1};
17+
18+
/** Minimum size of a witness commitment structure. Defined in BIP 141. **/
19+
static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38};
20+
1521
/** A "reason" why a transaction was invalid, suitable for determining whether the
1622
* provider of the transaction should be banned/ignored/disconnected/etc.
1723
*/
@@ -151,4 +157,25 @@ static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
151157
return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
152158
}
153159

160+
/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */
161+
inline int GetWitnessCommitmentIndex(const CBlock& block)
162+
{
163+
int commitpos = NO_WITNESS_COMMITMENT;
164+
if (!block.vtx.empty()) {
165+
for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
166+
const CTxOut& vout = block.vtx[0]->vout[o];
167+
if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT &&
168+
vout.scriptPubKey[0] == OP_RETURN &&
169+
vout.scriptPubKey[1] == 0x24 &&
170+
vout.scriptPubKey[2] == 0xaa &&
171+
vout.scriptPubKey[3] == 0x21 &&
172+
vout.scriptPubKey[4] == 0xa9 &&
173+
vout.scriptPubKey[5] == 0xed) {
174+
commitpos = o;
175+
}
176+
}
177+
}
178+
return commitpos;
179+
}
180+
154181
#endif // BITCOIN_CONSENSUS_VALIDATION_H

src/qt/guiconstants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80;
4646
#define QAPP_ORG_DOMAIN "bitcoin.org"
4747
#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt"
4848
#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet"
49+
#define QAPP_APP_NAME_SIGNET "Bitcoin-Qt-signet"
4950
#define QAPP_APP_NAME_REGTEST "Bitcoin-Qt-regtest"
5051

5152
/* One gigabyte (GB) in bytes */

src/qt/networkstyle.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ static const struct {
1919
} network_styles[] = {
2020
{"main", QAPP_APP_NAME_DEFAULT, 0, 0},
2121
{"test", QAPP_APP_NAME_TESTNET, 70, 30},
22-
{"regtest", QAPP_APP_NAME_REGTEST, 160, 30}
22+
{"signet", QAPP_APP_NAME_SIGNET, 35, 15},
23+
{"regtest", QAPP_APP_NAME_REGTEST, 160, 30},
2324
};
2425
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
2526

0 commit comments

Comments
 (0)