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

0.17 rebased Signet implementation #5

Open
wants to merge 8 commits into
base: 0.17
from
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C

#
# Issue blocks using a local node at a given interval.
#

if [ $# -lt 3 ]; then
echo "syntax: $0 <min_time> <max_time> <bitcoin-cli path> [<bitcoin-cli args>]" ; exit 1
fi

function log()
{
echo "- $(date +%H:%M:%S): $*"
}

min_time=$1
shift
max_time=$1
shift
bcli=$1
shift

# https://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash
re='^[0-9]+$'
if ! [[ $min_time =~ $re ]] ; then
echo "error: min_time $min_time is not a number" ; exit 1
fi
if ! [[ $max_time =~ $re ]] ; then
echo "error: max_time $max_time is not a number" ; exit 1
fi

let randinterval=max_time-min_time
if [ $randinterval -lt 1 ]; then
echo "error: interval min..max must be positive and greater than 0" ; exit 1
fi

if ! [ -e "$bcli" ]; then
which "$bcli" &> /dev/null
if [ $? -ne 0 ]; then
echo "error: unable to find bitcoin binary: $bcli" ; exit 1
fi
fi

echo "- checking node status"
conns=$($bcli "$@" getconnectioncount)

if [ $? -ne 0 ]; then
echo "node error" ; exit 1
fi

if [ $conns -lt 1 ]; then
echo "warning: node is not connected to any other node"
fi

log "node OK with $conns connection(s)"
log "mining in random intervals between $min_time .. $max_time seconds"
log "hit ^C to stop"

while true; do
let rv=$RANDOM%$randinterval
let rv=rv+min_time
echo -n -e "- $(date +%H:%M:%S): next block in $rv seconds..."
sleep $rv
echo -n -e " [submit]"
blockhash=$($bcli "$@" getnewblockhex true)
if [ $? -ne 0 ]; then
echo "node error; aborting" ; exit 1
fi
echo ""
log "broadcasting block $($bcli "$@" getblockcount) $blockhash to $($bcli "$@" getconnectioncount) peer(s)"
done
@@ -405,6 +405,16 @@ class CDiskBlockIndex : public CBlockIndex
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
if (g_solution_blocks && !(s.GetType() & SER_GETHASH)) {
uint256 hash = GetBlockHash();
READWRITE(g_blockheader_payload_map[hash]);
size_t len = GetSizeOfCompactSize(g_blockheader_payload_map[hash].size()) + g_blockheader_payload_map[hash].size();
while (len < g_solution_block_len) {
uint8_t padding = 0;
READWRITE(padding);
len++;
}
}
}

uint256 GetBlockHash() const
@@ -14,13 +14,15 @@

#include <chainparamsseeds.h>

static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
#include <hash.h>

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)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vin[0].scriptSig = coinbase_sig;
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;

@@ -35,6 +37,12 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
return genesis;
}

static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CScript coinbase_sig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
return CreateGenesisBlock(coinbase_sig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}

/**
* Build the genesis block. Note that the output of its generation
* transaction cannot be spent since it did not originally exist in the
@@ -274,6 +282,88 @@ class CTestNetParams : public CChainParams {
}
};

/**
* SigNet version 2018-07-20
*/
class SigNetParams : public CChainParams {
public:
SigNetParams(const ArgsManager& args) {
if (!args.IsArgSet("-signet_blockscript") || !args.IsArgSet("-signet_siglen")) {
throw std::runtime_error(strprintf("%s: -signet_blockscript and -signet_siglen are both mandatory for signet networks", __func__));
}
if (args.GetArgs("-signet_blockscript").size() != 1) {
throw std::runtime_error(strprintf("%s: -signet_blockscript cannot be multiple values.", __func__));
}
if (args.GetArgs("-signet_siglen").size() != 1) {
throw std::runtime_error(strprintf("%s: -signet_siglen cannot be multiple values.", __func__));
}

LogPrintf("SigNet with block script %s\n", gArgs.GetArgs("-signet_blockscript")[0]);

strNetworkID = "signet";
consensus.signature_pow = true;
consensus.blockscript = ParseHex(args.GetArgs("-signet_blockscript")[0]);
consensus.siglen = g_solution_block_len = atoi64(args.GetArgs("-signet_siglen")[0]);
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP34Height = 1;
consensus.BIP65Height = 1;
consensus.BIP66Height = 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("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1539478800;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;

// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1539478800;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;

// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1539478800;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;

pchMessageStart[0] = 0xf0;
pchMessageStart[1] = 0xc7;
pchMessageStart[2] = 0x70;
pchMessageStart[3] = 0x6a;
nDefaultPort = 38333;
nPruneAfterHeight = 1000;

CHashWriter h(SER_DISK, 0);
h << consensus.blockscript << consensus.siglen;
uint256 hash = h.GetHash();
CScript coinbase_sig = CScript() << std::vector<uint8_t>(hash.begin(), hash.end());
CScript genesis_out = CScript() << OP_RETURN;
genesis = CreateGenesisBlock(coinbase_sig, genesis_out, 1534313275, 0, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();

vFixedSeeds.clear();
vSeeds.clear();
if (args.IsArgSet("-signet_seednode")) {
vSeeds = gArgs.GetArgs("-signet_seednode");
}

base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>{125};
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>{87};
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>{217};
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};

bech32_hrp = "sb";

fDefaultConsistencyChecks = false;
fRequireStandard = false;
fMineBlocksOnDemand = false;
}
};

/**
* Regression test
*/
@@ -361,14 +451,18 @@ const CChainParams &Params() {
return *globalChainParams;
}

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

@@ -107,7 +107,7 @@ class CChainParams
* @returns a CChainParams* of the chosen chain.
* @throws a std::runtime_error if the chain is not supported.
*/
std::unique_ptr<CChainParams> CreateChainParams(const std::string& chain);
std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain);

/**
* Return the currently selected parameters. This won't change after app
@@ -13,13 +13,18 @@

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()
{
gArgs.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
"This is intended for regression testing tools and app development.", true, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-testnet", "Use the test chain", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-signet", "Use the signet chain. Note that the network is defined by the signet_blockscript and signet_siglen parameters", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-signet_blockscript", "Blocks must satisfy the given script to be considered valid (only for -signet networks)", false, OptionsCategory::CHAINPARAMS);
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", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-signet_seednode", "Specify a seed node for the signet network (may be used multiple times to specify multiple seed nodes)", false, OptionsCategory::CHAINPARAMS);
}

static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
@@ -38,8 +43,9 @@ std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain
return MakeUnique<CBaseChainParams>("testnet3", 18332);
else if (chain == CBaseChainParams::REGTEST)
return MakeUnique<CBaseChainParams>("regtest", 18443);
else
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
else if (chain == CBaseChainParams::SIGNET)
return MakeUnique<CBaseChainParams>("signet", 38332);
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}

void SelectBaseParams(const std::string& chain)
@@ -16,9 +16,10 @@
class CBaseChainParams
{
public:
/** BIP70 chain name strings (main, test or regtest) */
/** BIP70 chain name strings (main, test, sigtest or regtest) */
static const std::string MAIN;
static const std::string TESTNET;
static const std::string SIGNET;
static const std::string REGTEST;

const std::string& DataDir() const { return strDataDir; }
@@ -75,7 +75,12 @@ struct Params {
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
uint256 nMinimumChainWork;
uint256 defaultAssumeValid;

bool signature_pow{false};
std::vector<uint8_t> blockscript;
uint32_t siglen;
};

} // namespace Consensus

#endif // BITCOIN_CONSENSUS_PARAMS_H
@@ -55,6 +55,10 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
BlockAssembler::Options::Options() {
blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;

// Make room for the signature in the block header, if this is a signet
// block
if (g_solution_blocks) nBlockMaxWeight -= g_solution_block_len;
}

BlockAssembler::BlockAssembler(const CChainParams& params, const Options& options) : chainparams(params)
@@ -14,6 +14,7 @@
#include <util.h>
#include <utilstrencodings.h>

unsigned int GetStandardScriptVerifyFlags() { return STANDARD_SCRIPT_VERIFY_FLAGS; }

CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
@@ -68,6 +68,8 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VE
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE |
SCRIPT_VERIFY_CONST_SCRIPTCODE;

unsigned int GetStandardScriptVerifyFlags();

/** For convenience, standard but not mandatory verify flags. */
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;

@@ -9,6 +9,9 @@
#include <chain.h>
#include <primitives/block.h>
#include <uint256.h>
#include <script/interpreter.h>

unsigned int GetStandardScriptVerifyFlags();

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

bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
bool CheckProofOfWork(const uint256& hash, unsigned int nBits, const Consensus::Params& params)
{
if (g_solution_blocks) {
if (hash == params.hashGenesisBlock) return true;
SimpleSignatureChecker bsc(hash);
const auto& payload = g_blockheader_payload_map.at(hash);
CScript solution = CScript(payload.begin(), payload.end());
CScript challenge = CScript(params.blockscript.begin(), params.blockscript.end());
return VerifyScript(solution, challenge, nullptr, GetStandardScriptVerifyFlags(), bsc);
}

bool fNegative;
bool fOverflow;
arith_uint256 bnTarget;
@@ -18,6 +18,6 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);

/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
bool CheckProofOfWork(const uint256& hash, unsigned int nBits, const Consensus::Params&);

#endif // BITCOIN_POW_H
@@ -10,9 +10,13 @@
#include <utilstrencodings.h>
#include <crypto/common.h>

bool g_solution_blocks = false;
size_t g_solution_block_len = 0;
std::map<uint256,std::vector<uint8_t>> g_blockheader_payload_map;

uint256 CBlockHeader::GetHash() const
{
return SerializeHash(*this);
return SerializeHash(*this, SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS);
}

std::string CBlock::ToString() const
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.