Skip to content

Commit 03bbf01

Browse files
kallewoofjtimon
authored andcommitted
Signet implementation
test/functional/data/rpc_getblockstats.json needs to be touched because: Signet implementation changes the genesis block for custom chains
1 parent a1e0c56 commit 03bbf01

File tree

24 files changed

+556
-133
lines changed

24 files changed

+556
-133
lines changed

contrib/example.conf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
[signet]
3+
signet_blockscript=512103e464a9f3070da4d3e0b34ce971ff36f3e07c47a8f4beadf32e8ea7e2afa8a82451ae
4+
signet_siglen=77
5+
# DG seed node
6+
seednode=178.128.221.177
7+
bech32_hrp=sb
8+
pchmessagestart=F0C7706A
9+
pubkeyprefix=125
10+
scriptprefix=87
11+
secretprefix=217
12+
extpubkeyprefix=043587CF
13+
extprvkeyprefix=04358394

contrib/signet/issuer/issuer.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) 2018 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
export LC_ALL=C
7+
8+
#
9+
# Issue blocks using a local node at a given interval.
10+
#
11+
12+
if [ $# -lt 3 ]; then
13+
echo "syntax: $0 <min_time> <max_time> <bitcoin-cli path> [<bitcoin-cli args>]" ; exit 1
14+
fi
15+
16+
function log()
17+
{
18+
echo "- $(date +%H:%M:%S): $*"
19+
}
20+
21+
min_time=$1
22+
shift
23+
max_time=$1
24+
shift
25+
bcli=$1
26+
shift
27+
28+
# https://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash
29+
re='^[0-9]+$'
30+
if ! [[ $min_time =~ $re ]] ; then
31+
echo "error: min_time $min_time is not a number" ; exit 1
32+
fi
33+
if ! [[ $max_time =~ $re ]] ; then
34+
echo "error: max_time $max_time is not a number" ; exit 1
35+
fi
36+
37+
let randinterval=max_time-min_time
38+
if [ $randinterval -lt 1 ]; then
39+
echo "error: interval min..max must be positive and greater than 0" ; exit 1
40+
fi
41+
42+
if ! [ -e "$bcli" ]; then
43+
which "$bcli" &> /dev/null
44+
if [ $? -ne 0 ]; then
45+
echo "error: unable to find bitcoin binary: $bcli" ; exit 1
46+
fi
47+
fi
48+
49+
echo "- checking node status"
50+
conns=$($bcli "$@" getconnectioncount)
51+
52+
if [ $? -ne 0 ]; then
53+
echo "node error" ; exit 1
54+
fi
55+
56+
if [ $conns -lt 1 ]; then
57+
echo "warning: node is not connected to any other node"
58+
fi
59+
60+
log "node OK with $conns connection(s)"
61+
log "mining in random intervals between $min_time .. $max_time seconds"
62+
log "hit ^C to stop"
63+
64+
while true; do
65+
let rv=$RANDOM%$randinterval
66+
echo -n -e "- $(date +%H:%M:%S): next block in $rv seconds..."
67+
sleep $rv
68+
echo -n -e " [submit]"
69+
blockhash=$($bcli "$@" getnewblockhex true)
70+
if [ $? -ne 0 ]; then
71+
echo "node error; aborting" ; exit 1
72+
fi
73+
echo ""
74+
log "broadcasting block $($bcli "$@" getblockcount) $blockhash to $($bcli "$@" getconnectioncount) peer(s)"
75+
done

src/chain.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,16 @@ class CDiskBlockIndex : public CBlockIndex
405405
READWRITE(nTime);
406406
READWRITE(nBits);
407407
READWRITE(nNonce);
408+
if (g_solution_blocks && !(s.GetType() & SER_GETHASH)) {
409+
uint256 hash = GetBlockHash();
410+
READWRITE(g_blockheader_payload_map[hash]);
411+
size_t len = GetSizeOfCompactSize(g_blockheader_payload_map[hash].size()) + g_blockheader_payload_map[hash].size();
412+
while (len < g_solution_block_len) {
413+
uint8_t padding = 0;
414+
READWRITE(padding);
415+
len++;
416+
}
417+
}
408418
}
409419

410420
uint256 GetBlockHash() const

src/chainparams.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
#include <boost/algorithm/string/classification.hpp>
1818
#include <boost/algorithm/string/split.hpp>
1919

20-
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
20+
#include <hash.h>
21+
22+
static CBlock CreateGenesisBlock(const CScript& coinbase_sig, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
2123
{
2224
CMutableTransaction txNew;
2325
txNew.nVersion = 1;
2426
txNew.vin.resize(1);
2527
txNew.vout.resize(1);
26-
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
28+
txNew.vin[0].scriptSig = coinbase_sig;
2729
txNew.vout[0].nValue = genesisReward;
2830
txNew.vout[0].scriptPubKey = genesisOutputScript;
2931

@@ -38,6 +40,12 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
3840
return genesis;
3941
}
4042

43+
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
44+
{
45+
CScript coinbase_sig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
46+
return CreateGenesisBlock(coinbase_sig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
47+
}
48+
4149
/**
4250
* Build the genesis block. Note that the output of its generation
4351
* transaction cannot be spent since it did not originally exist in the
@@ -420,6 +428,10 @@ class CCustomParams : public CRegTestParams {
420428
consensus.nMinimumChainWork = uint256S(args.GetArg("-con_nminimumchainwork", "0x0"));
421429
consensus.defaultAssumeValid = uint256S(args.GetArg("-con_defaultassumevalid", "0x00"));
422430

431+
consensus.blockscript = ParseHex(args.GetArg("-signet_blockscript", ""));
432+
g_solution_blocks = !consensus.blockscript.empty();
433+
g_solution_block_len = consensus.siglen = args.GetArg("-signet_siglen", 77);
434+
423435
nPruneAfterHeight = (uint64_t)args.GetArg("-npruneafterheight", nPruneAfterHeight);
424436
fDefaultConsistencyChecks = args.GetBoolArg("-fdefaultconsistencychecks", fDefaultConsistencyChecks);
425437
fMineBlocksOnDemand = args.GetBoolArg("-fmineblocksondemand", fMineBlocksOnDemand);
@@ -457,7 +469,15 @@ class CCustomParams : public CRegTestParams {
457469
{
458470
strNetworkID = chain;
459471
UpdateFromArgs(args);
460-
genesis = CreateGenesisBlock(strNetworkID.c_str(), CScript(OP_TRUE), 1296688602, 2, 0x207fffff, 1, 50 * COIN);
472+
CHashWriter h(SER_DISK, 0);
473+
h << strNetworkID;
474+
if (g_solution_blocks) {
475+
h << consensus.blockscript << consensus.siglen;
476+
}
477+
const uint256 hash = h.GetHash();
478+
const CScript coinbase_sig = CScript() << std::vector<uint8_t>(hash.begin(), hash.end());
479+
const CScript genesis_out = CScript() << OP_RETURN;
480+
genesis = CreateGenesisBlock(coinbase_sig, genesis_out, 1296688602, 0, 0x207fffff, 1, 50 * COIN);
461481
consensus.hashGenesisBlock = genesis.GetHash();
462482
}
463483
};

src/chainparamsbase.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ void SetupChainParamsBaseOptions()
2323
gArgs.AddArg("-testnet", "Use the test chain", false, OptionsCategory::CHAINPARAMS);
2424
gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest or custom only)", true, OptionsCategory::CHAINPARAMS);
2525
gArgs.AddArg("-seednode=<ip>", "Use specified node as seed node. This option can be specified multiple times to connect to multiple nodes. (custom only)", true, OptionsCategory::CHAINPARAMS);
26+
gArgs.AddArg("-signet_blockscript", "Blocks must satisfy the given script to be considered valid instead of using pow. If empty, and by default, it is ignored. (custom only)", true, OptionsCategory::CHAINPARAMS);
27+
gArgs.AddArg("-signet_siglen", "The length of the signature must be exactly this long (padded to this length, if shorter). All block headers in this network are of length 80 + this value (custom only)", true, OptionsCategory::CHAINPARAMS);
2628
}
2729

2830
static std::unique_ptr<CBaseChainParams> globalChainBaseParams;

src/consensus/params.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ struct Params {
7575
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
7676
uint256 nMinimumChainWork;
7777
uint256 defaultAssumeValid;
78+
79+
std::vector<uint8_t> blockscript;
80+
uint32_t siglen;
7881
};
82+
7983
} // namespace Consensus
8084

8185
#endif // BITCOIN_CONSENSUS_PARAMS_H

src/miner.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
5555
BlockAssembler::Options::Options() {
5656
blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
5757
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
58+
59+
// Make room for the signature in the block header, if this is a signet block
60+
if (g_solution_blocks) nBlockMaxWeight -= g_solution_block_len;
5861
}
5962

6063
BlockAssembler::BlockAssembler(const CChainParams& params, const Options& options) : chainparams(params)

src/policy/policy.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <util.h>
1515
#include <utilstrencodings.h>
1616

17+
unsigned int GetStandardScriptVerifyFlags() { return STANDARD_SCRIPT_VERIFY_FLAGS; }
1718

1819
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
1920
{

src/policy/policy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VE
6868
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE |
6969
SCRIPT_VERIFY_CONST_SCRIPTCODE;
7070

71+
unsigned int GetStandardScriptVerifyFlags();
72+
7173
/** For convenience, standard but not mandatory verify flags. */
7274
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
7375

src/pow.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include <chain.h>
1010
#include <primitives/block.h>
1111
#include <uint256.h>
12+
#include <script/interpreter.h>
13+
14+
unsigned int GetStandardScriptVerifyFlags();
1215

1316
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
1417
{
@@ -71,8 +74,17 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
7174
return bnNew.GetCompact();
7275
}
7376

74-
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
77+
bool CheckProofOfWork(const uint256& hash, unsigned int nBits, const Consensus::Params& params)
7578
{
79+
if (g_solution_blocks) {
80+
if (hash == params.hashGenesisBlock) return true;
81+
SimpleSignatureChecker bsc(hash);
82+
const auto& payload = g_blockheader_payload_map.at(hash);
83+
CScript solution = CScript(payload.begin(), payload.end());
84+
CScript challenge = CScript(params.blockscript.begin(), params.blockscript.end());
85+
return VerifyScript(solution, challenge, nullptr, GetStandardScriptVerifyFlags(), bsc);
86+
}
87+
7688
bool fNegative;
7789
bool fOverflow;
7890
arith_uint256 bnTarget;

0 commit comments

Comments
 (0)