Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIP-325: Signet [consensus] #18267

Merged
merged 10 commits into from
Sep 21, 2020
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,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 @@ -321,6 +322,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 @@ -134,6 +134,7 @@ FUZZ_TARGETS = \
test/fuzz/scriptnum_ops \
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 @@ -1106,6 +1107,12 @@ test_fuzz_signature_checker_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_signature_checker_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
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");
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
Copy link
Contributor

@fjahr fjahr Aug 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in ad33fd5

nit: The help info on the args could be updated to reflect the defaults to the global signet. Right now it's not obvious that blockscript and seednode are optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise all the changes look good to me!

vSeeds.emplace_back("178.128.221.177");
vSeeds.emplace_back("2a01:7c8:d005:390::5");
vSeeds.emplace_back("ntv3mtqw5wt63red.onion:38333");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit weird that this shows up as "Loading addresses from DNS seed", but that's out of scope for this PR.

} 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__));
}
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
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";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we do use "tb" instead of "sb" here?

In c-lightning PR we had "sb" here: https://github.com/ElementsProject/lightning/pull/2816/files#diff-53092192708008b1de0d997128c58d37R54

And BIP-325 and BIP-173 are being silent in this regard: not even a PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People thinks that the test networks should use the same prefixes so it was changed to match testnet.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, probably we have another thing to update in c-lightning then, additionally to new nonce.

Also, noticed that BIP-235 still has outdated nonce info

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed bitcoin/bips#1000 to update the bip for the genesis block. FWIW, #12314 has related discussion about reusing testnet addresses in regtest.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out, @dr-orlovsky -- I thought I had already updated the BIP but I had apparently forgotten to actually make it into a pull request.


fDefaultConsistencyChecks = false;
fRequireStandard = true;
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
m_is_test_chain = true;
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
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);
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
} 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));
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
}

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};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

359badf

nit, just noting signet_blocks is only used in the next commit.

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;
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
}

#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