Skip to content

Commit

Permalink
Merge #18267: BIP-325: Signet [consensus]
Browse files Browse the repository at this point in the history
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
  • Loading branch information
laanwj committed Sep 21, 2020
2 parents c0c409d + 8258c4c commit 8c5f681
Show file tree
Hide file tree
Showing 21 changed files with 532 additions and 44 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ BITCOIN_CORE_H = \
script/signingprovider.h \
script/standard.h \
shutdown.h \
signet.h \
streams.h \
support/allocators/secure.h \
support/allocators/zeroafterfree.h \
Expand Down Expand Up @@ -322,6 +323,7 @@ libbitcoin_server_a_SOURCES = \
rpc/server.cpp \
script/sigcache.cpp \
shutdown.cpp \
signet.cpp \
timedata.cpp \
torcontrol.cpp \
txdb.cpp \
Expand Down
7 changes: 7 additions & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ FUZZ_TARGETS = \
test/fuzz/secp256k1_ecdsa_signature_parse_der_lax \
test/fuzz/service_deserialize \
test/fuzz/signature_checker \
test/fuzz/signet \
test/fuzz/snapshotmetadata_deserialize \
test/fuzz/span \
test/fuzz/spanparsing \
Expand Down Expand Up @@ -1129,6 +1130,12 @@ test_fuzz_signature_checker_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_signature_checker_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
test_fuzz_signature_checker_SOURCES = test/fuzz/signature_checker.cpp

test_fuzz_signet_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_signet_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_signet_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_signet_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_signet_SOURCES = test/fuzz/signet.cpp

test_fuzz_snapshotmetadata_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSNAPSHOTMETADATA_DESERIALIZE=1
test_fuzz_snapshotmetadata_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_snapshotmetadata_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
Expand Down
105 changes: 102 additions & 3 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <chainparamsseeds.h>
#include <consensus/merkle.h>
#include <hash.h> // for signet block challenge hash
#include <tinyformat.h>
#include <util/system.h>
#include <util/strencodings.h>
Expand Down Expand Up @@ -63,6 +64,8 @@ class CMainParams : public CChainParams {
public:
CMainParams() {
strNetworkID = CBaseChainParams::MAIN;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22");
consensus.BIP34Height = 227931;
Expand Down Expand Up @@ -172,6 +175,8 @@ class CTestNetParams : public CChainParams {
public:
CTestNetParams() {
strNetworkID = CBaseChainParams::TESTNET;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105");
consensus.BIP34Height = 21111;
Expand Down Expand Up @@ -250,13 +255,104 @@ class CTestNetParams : public CChainParams {
}
};

/**
* Signet
*/
class SigNetParams : public CChainParams {
public:
explicit SigNetParams(const ArgsManager& args) {
std::vector<uint8_t> bin;
vSeeds.clear();

if (!args.IsArgSet("-signetchallenge")) {
LogPrintf("Using default signet network\n");
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
vSeeds.emplace_back("178.128.221.177");
vSeeds.emplace_back("2a01:7c8:d005:390::5");
vSeeds.emplace_back("ntv3mtqw5wt63red.onion:38333");
} else {
const auto signet_challenge = args.GetArgs("-signetchallenge");
if (signet_challenge.size() != 1) {
throw std::runtime_error(strprintf("%s: -signetchallenge cannot be multiple values.", __func__));
}
bin = ParseHex(signet_challenge[0]);

LogPrintf("Signet with challenge %s\n", signet_challenge[0]);
}

if (args.IsArgSet("-signetseednode")) {
vSeeds = args.GetArgs("-signetseednode");
}

strNetworkID = CBaseChainParams::SIGNET;
consensus.signet_blocks = true;
consensus.signet_challenge.assign(bin.begin(), bin.end());
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP34Height = 1;
consensus.BIP65Height = 1;
consensus.BIP66Height = 1;
consensus.CSVHeight = 1;
consensus.SegwitHeight = 1;
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1916;
consensus.nMinerConfirmationWindow = 2016;
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008

// message start is defined as the first 4 bytes of the sha256d of the block script
CHashWriter h(SER_DISK, 0);
h << consensus.signet_challenge;
uint256 hash = h.GetHash();
memcpy(pchMessageStart, hash.begin(), 4);
LogPrintf("Signet derived magic (message start): %s\n", HexStr({pchMessageStart, pchMessageStart + 4}));

nDefaultPort = 38333;
nPruneAfterHeight = 1000;
m_assumed_blockchain_size = 0;
m_assumed_chain_state_size = 0;

genesis = CreateGenesisBlock(1598918400, 52613770, 0x1e0377ae, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));

vFixedSeeds.clear();

base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};

bech32_hrp = "tb";

fDefaultConsistencyChecks = false;
fRequireStandard = true;
m_is_test_chain = true;
m_is_mockable_chain = false;

chainTxData = ChainTxData{
0,
0,
0
};
}
};

/**
* Regression test
*/
class CRegTestParams : public CChainParams {
public:
explicit CRegTestParams(const ArgsManager& args) {
strNetworkID = CBaseChainParams::REGTEST;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
consensus.nSubsidyHalvingInterval = 150;
consensus.BIP16Exception = uint256();
consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
Expand Down Expand Up @@ -391,12 +487,15 @@ const CChainParams &Params() {

std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
if (chain == CBaseChainParams::MAIN) {
return std::unique_ptr<CChainParams>(new CMainParams());
else if (chain == CBaseChainParams::TESTNET)
} else if (chain == CBaseChainParams::TESTNET) {
return std::unique_ptr<CChainParams>(new CTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
} else if (chain == CBaseChainParams::SIGNET) {
return std::unique_ptr<CChainParams>(new SigNetParams(gArgs));
} else if (chain == CBaseChainParams::REGTEST) {
return std::unique_ptr<CChainParams>(new CRegTestParams(gArgs));
}
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}

Expand Down
16 changes: 11 additions & 5 deletions src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

const std::string CBaseChainParams::MAIN = "main";
const std::string CBaseChainParams::TESTNET = "test";
const std::string CBaseChainParams::SIGNET = "signet";
const std::string CBaseChainParams::REGTEST = "regtest";

void SetupChainParamsBaseOptions(ArgsManager& argsman)
Expand All @@ -23,6 +24,9 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
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);
argsman.AddArg("-signet", "Use the signet chain. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
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);
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);
}

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

std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
if (chain == CBaseChainParams::MAIN) {
return MakeUnique<CBaseChainParams>("", 8332);
else if (chain == CBaseChainParams::TESTNET)
} else if (chain == CBaseChainParams::TESTNET) {
return MakeUnique<CBaseChainParams>("testnet3", 18332);
else if (chain == CBaseChainParams::REGTEST)
} else if (chain == CBaseChainParams::SIGNET) {
return MakeUnique<CBaseChainParams>("signet", 38332);
} else if (chain == CBaseChainParams::REGTEST) {
return MakeUnique<CBaseChainParams>("regtest", 18443);
else
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}

void SelectBaseParams(const std::string& chain)
Expand Down
1 change: 1 addition & 0 deletions src/chainparamsbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class CBaseChainParams
/** Chain name strings */
static const std::string MAIN;
static const std::string TESTNET;
static const std::string SIGNET;
static const std::string REGTEST;
///@}

Expand Down
7 changes: 7 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ struct Params {
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
uint256 nMinimumChainWork;
uint256 defaultAssumeValid;

/**
* If true, witness commitments contain a payload equal to a Bitcoin Script solution
* to the signet challenge. See BIP325.
*/
bool signet_blocks{false};
std::vector<uint8_t> signet_challenge;
};
} // namespace Consensus

Expand Down
27 changes: 27 additions & 0 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
#include <primitives/transaction.h>
#include <primitives/block.h>

/** Index marker for when no witness commitment is present in a coinbase transaction. */
static constexpr int NO_WITNESS_COMMITMENT{-1};

/** Minimum size of a witness commitment structure. Defined in BIP 141. **/
static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38};

/** A "reason" why a transaction was invalid, suitable for determining whether the
* provider of the transaction should be banned/ignored/disconnected/etc.
*/
Expand Down Expand Up @@ -151,4 +157,25 @@ static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
}

/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */
inline int GetWitnessCommitmentIndex(const CBlock& block)
{
int commitpos = NO_WITNESS_COMMITMENT;
if (!block.vtx.empty()) {
for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
const CTxOut& vout = block.vtx[0]->vout[o];
if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT &&
vout.scriptPubKey[0] == OP_RETURN &&
vout.scriptPubKey[1] == 0x24 &&
vout.scriptPubKey[2] == 0xaa &&
vout.scriptPubKey[3] == 0x21 &&
vout.scriptPubKey[4] == 0xa9 &&
vout.scriptPubKey[5] == 0xed) {
commitpos = o;
}
}
}
return commitpos;
}

#endif // BITCOIN_CONSENSUS_VALIDATION_H
1 change: 1 addition & 0 deletions src/qt/guiconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80;
#define QAPP_ORG_DOMAIN "bitcoin.org"
#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt"
#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet"
#define QAPP_APP_NAME_SIGNET "Bitcoin-Qt-signet"
#define QAPP_APP_NAME_REGTEST "Bitcoin-Qt-regtest"

/* One gigabyte (GB) in bytes */
Expand Down
3 changes: 2 additions & 1 deletion src/qt/networkstyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ static const struct {
} network_styles[] = {
{"main", QAPP_APP_NAME_DEFAULT, 0, 0},
{"test", QAPP_APP_NAME_TESTNET, 70, 30},
{"regtest", QAPP_APP_NAME_REGTEST, 160, 30}
{"signet", QAPP_APP_NAME_SIGNET, 35, 15},
{"regtest", QAPP_APP_NAME_REGTEST, 160, 30},
};
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);

Expand Down
Loading

0 comments on commit 8c5f681

Please sign in to comment.