mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-17 13:07:54 +02:00
Merge pull request #55 from apoelstra/scriptdest
Add commandline flag to set genesis block script destination
This commit is contained in:
commit
2f7f3bfb00
9 changed files with 159 additions and 38 deletions
|
|
@ -38,6 +38,7 @@ BITCOIN_TESTS =\
|
|||
test/compress_tests.cpp \
|
||||
test/crypto_tests.cpp \
|
||||
test/DoS_tests.cpp \
|
||||
test/genesis_tests.cpp \
|
||||
test/getarg_tests.cpp \
|
||||
test/hash_tests.cpp \
|
||||
test/key_tests.cpp \
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static const Checkpoints::CCheckpointData dataRegtest = {
|
|||
|
||||
class CMainParams : public CChainParams {
|
||||
public:
|
||||
CMainParams() {
|
||||
CMainParams(CScript scriptDestination) {
|
||||
networkID = CBaseChainParams::MAIN;
|
||||
strNetworkID = "main";
|
||||
/**
|
||||
|
|
@ -127,7 +127,9 @@ public:
|
|||
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
|
||||
genesis.nVersion = 1;
|
||||
genesis.nTime = 1231006505;
|
||||
CScript scriptDestination(CScript() << OP_5 << ParseHex("027d5d62861df77fc9a37dbe901a579d686d1423be5f56d6fc50bb9de3480871d1") << ParseHex("03b41ea6ba73b94c901fdd43e782aaf70016cc124b72a086e77f6e9f4f942ca9bb") << ParseHex("02be643c3350bade7c96f6f28d1750af2ef507bc1f08dd38f82749214ab90d9037") << ParseHex("021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a") << ParseHex("0320ea4fcf77b63e89094e681a5bd50355900bf961c10c9c82876cb3238979c0ed") << ParseHex("021c4c92c8380659eb567b497b936b274424662909e1ffebc603672ed8433f4aa1") << ParseHex("027841250cfadc06c603da8bc58f6cd91e62f369826c8718eb6bd114601dd0c5ac") << OP_7 << OP_CHECKMULTISIG);
|
||||
if (scriptDestination.empty()) {
|
||||
scriptDestination = CScript() << OP_5 << ParseHex("027d5d62861df77fc9a37dbe901a579d686d1423be5f56d6fc50bb9de3480871d1") << ParseHex("03b41ea6ba73b94c901fdd43e782aaf70016cc124b72a086e77f6e9f4f942ca9bb") << ParseHex("02be643c3350bade7c96f6f28d1750af2ef507bc1f08dd38f82749214ab90d9037") << ParseHex("021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a") << ParseHex("0320ea4fcf77b63e89094e681a5bd50355900bf961c10c9c82876cb3238979c0ed") << ParseHex("021c4c92c8380659eb567b497b936b274424662909e1ffebc603672ed8433f4aa1") << ParseHex("027841250cfadc06c603da8bc58f6cd91e62f369826c8718eb6bd114601dd0c5ac") << OP_7 << OP_CHECKMULTISIG;
|
||||
}
|
||||
genesis.proof = CProof(scriptDestination, CScript()); // genesis block gets a PoW pass
|
||||
|
||||
hashGenesisBlock = genesis.GetHash();
|
||||
|
|
@ -163,14 +165,13 @@ public:
|
|||
return data;
|
||||
}
|
||||
};
|
||||
static CMainParams mainParams;
|
||||
|
||||
/**
|
||||
* Testnet (v3)
|
||||
*/
|
||||
class CTestNetParams : public CMainParams {
|
||||
public:
|
||||
CTestNetParams() {
|
||||
CTestNetParams(CScript scriptDestination) : CMainParams(scriptDestination) {
|
||||
networkID = CBaseChainParams::TESTNET;
|
||||
strNetworkID = "test";
|
||||
pchMessageStart[0] = 0xee;
|
||||
|
|
@ -217,14 +218,13 @@ public:
|
|||
return dataTestnet;
|
||||
}
|
||||
};
|
||||
static CTestNetParams testNetParams;
|
||||
|
||||
/**
|
||||
* Regression test
|
||||
*/
|
||||
class CRegTestParams : public CTestNetParams {
|
||||
public:
|
||||
CRegTestParams() {
|
||||
CRegTestParams(CScript scriptDestination) : CTestNetParams(scriptDestination) {
|
||||
networkID = CBaseChainParams::REGTEST;
|
||||
strNetworkID = "regtest";
|
||||
pchMessageStart[0] = 0xfa;
|
||||
|
|
@ -249,7 +249,9 @@ public:
|
|||
txNew.vout[1].scriptPubKey = CScript() << OP_TRUE;
|
||||
genesis.vtx[0] = CTransaction(txNew);
|
||||
|
||||
CScript scriptDestination(CScript() << OP_TRUE);
|
||||
if (scriptDestination.empty()) {
|
||||
scriptDestination = CScript() << OP_TRUE;
|
||||
}
|
||||
genesis.proof = CProof(scriptDestination, CScript()); // genesis block gets a PoW pass
|
||||
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
|
||||
|
||||
|
|
@ -272,14 +274,13 @@ public:
|
|||
return dataRegtest;
|
||||
}
|
||||
};
|
||||
static CRegTestParams regTestParams;
|
||||
|
||||
/**
|
||||
* Unit test
|
||||
*/
|
||||
class CUnitTestParams : public CMainParams, public CModifiableParams {
|
||||
public:
|
||||
CUnitTestParams() {
|
||||
CUnitTestParams(CScript scriptDestination) : CMainParams(scriptDestination) {
|
||||
networkID = CBaseChainParams::UNITTEST;
|
||||
strNetworkID = "unittest";
|
||||
nDefaultPort = 18445;
|
||||
|
|
@ -308,50 +309,47 @@ public:
|
|||
virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
|
||||
virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
|
||||
};
|
||||
static CUnitTestParams unitTestParams;
|
||||
|
||||
|
||||
static CChainParams *pCurrentParams = 0;
|
||||
|
||||
CModifiableParams *ModifiableParams()
|
||||
{
|
||||
assert(pCurrentParams);
|
||||
assert(pCurrentParams==&unitTestParams);
|
||||
return (CModifiableParams*)&unitTestParams;
|
||||
}
|
||||
static CChainParams *pCurrentParams;
|
||||
|
||||
const CChainParams &Params() {
|
||||
assert(pCurrentParams);
|
||||
return *pCurrentParams;
|
||||
}
|
||||
|
||||
CChainParams &Params(CBaseChainParams::Network network) {
|
||||
|
||||
CChainParams* CChainParams::Factory(CBaseChainParams::Network network, CScript scriptDestination) {
|
||||
switch (network) {
|
||||
case CBaseChainParams::MAIN:
|
||||
return mainParams;
|
||||
return new CMainParams(scriptDestination);
|
||||
case CBaseChainParams::TESTNET:
|
||||
return testNetParams;
|
||||
return new CTestNetParams(scriptDestination);
|
||||
case CBaseChainParams::REGTEST:
|
||||
return regTestParams;
|
||||
return new CRegTestParams(scriptDestination);
|
||||
case CBaseChainParams::UNITTEST:
|
||||
return unitTestParams;
|
||||
return new CUnitTestParams(scriptDestination);
|
||||
default:
|
||||
assert(false && "Unimplemented network");
|
||||
return mainParams;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectParams(CBaseChainParams::Network network) {
|
||||
void SelectParams(CBaseChainParams::Network network, CScript scriptDestination) {
|
||||
SelectBaseParams(network);
|
||||
pCurrentParams = &Params(network);
|
||||
pCurrentParams = CChainParams::Factory(network, scriptDestination);
|
||||
}
|
||||
|
||||
void SelectParams(CBaseChainParams::Network network) {
|
||||
SelectParams(network, CScript());
|
||||
}
|
||||
|
||||
bool SelectParamsFromCommandLine()
|
||||
{
|
||||
CBaseChainParams::Network network = NetworkIdFromCommandLine();
|
||||
CScript scriptDestination = ScriptDestinationFromCommandLine();
|
||||
if (network == CBaseChainParams::MAX_NETWORK_TYPES)
|
||||
return false;
|
||||
|
||||
SelectParams(network);
|
||||
SelectParams(network, scriptDestination);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ public:
|
|||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||
const std::vector<CAddress>& FixedSeeds() const { return vFixedSeeds; }
|
||||
virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0;
|
||||
/**
|
||||
* Creates and returns a CChainParams* of the chosen chain. The caller has to delete the object.
|
||||
* @returns a CChainParams* of the chosen chain.
|
||||
* @throws a std::runtime_error if the chain is not supported.
|
||||
*/
|
||||
static CChainParams* Factory(CBaseChainParams::Network network, CScript scriptDestination);
|
||||
protected:
|
||||
CChainParams() {}
|
||||
|
||||
|
|
@ -139,12 +145,14 @@ const CChainParams &Params();
|
|||
/** Return parameters for the given network. */
|
||||
CChainParams &Params(CBaseChainParams::Network network);
|
||||
|
||||
/** Get modifiable network parameters (UNITTEST only) */
|
||||
CModifiableParams *ModifiableParams();
|
||||
|
||||
/** Sets the params returned by Params() to those for the given network. */
|
||||
void SelectParams(CBaseChainParams::Network network);
|
||||
|
||||
/**
|
||||
* Sets the params returned by Params() to those for the given network
|
||||
* with given blocksigning pubkey */
|
||||
void SelectParams(CBaseChainParams::Network network, CScript scriptDestination);
|
||||
|
||||
/**
|
||||
* Looks for -regtest or -testnet and then calls SelectParams as appropriate.
|
||||
* Returns false if an invalid combination is given.
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@
|
|||
|
||||
#include "chainparamsbase.h"
|
||||
|
||||
#include "script/script.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
|
|
@ -114,6 +117,20 @@ CBaseChainParams::Network NetworkIdFromCommandLine()
|
|||
return CBaseChainParams::MAIN;
|
||||
}
|
||||
|
||||
CScript ScriptDestinationFromCommandLine()
|
||||
{
|
||||
std::string sd = GetArg("-genesisscriptdestination", "");
|
||||
if (!sd.empty()) {
|
||||
if (IsHex(sd)) {
|
||||
std::vector<unsigned char> sd_raw(ParseHex(sd));
|
||||
return CScript(sd_raw.begin(), sd_raw.end());
|
||||
} else {
|
||||
fprintf(stderr, "Warning: Genesis script destination was not valid hex, ignoring it.\n");
|
||||
}
|
||||
}
|
||||
return CScript();
|
||||
}
|
||||
|
||||
bool SelectBaseParamsFromCommandLine()
|
||||
{
|
||||
CBaseChainParams::Network network = NetworkIdFromCommandLine();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "script/script.h"
|
||||
|
||||
/**
|
||||
* CBaseChainParams defines the base parameters (shared between bitcoin-cli and bitcoind)
|
||||
* of a given instance of the Bitcoin system.
|
||||
|
|
@ -50,6 +52,12 @@ void SelectBaseParams(CBaseChainParams::Network network);
|
|||
*/
|
||||
CBaseChainParams::Network NetworkIdFromCommandLine();
|
||||
|
||||
/**
|
||||
* Looks for hex-encoded -genesisscriptdistenation and returns a CScript of it.
|
||||
* Returns an empty script if the flag is missing or badly encoded.
|
||||
*/
|
||||
CScript ScriptDestinationFromCommandLine();
|
||||
|
||||
/**
|
||||
* Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate.
|
||||
* Returns false if an invalid combination is given.
|
||||
|
|
|
|||
|
|
@ -346,6 +346,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
|
||||
strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n";
|
||||
#endif
|
||||
strUsage += " -genesisscriptdestination " + _("Set the scriptPubKey used when signing blocks. This is intended for testing, "
|
||||
"as changing it forks the node off of the network") + "\n";
|
||||
strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
|
||||
strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
|
||||
strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n";
|
||||
|
|
|
|||
10
src/main.cpp
10
src/main.cpp
|
|
@ -1288,7 +1288,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
|||
// CBlock and CBlockIndex
|
||||
//
|
||||
|
||||
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
|
||||
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos)
|
||||
{
|
||||
// Open history file to append
|
||||
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
|
||||
|
|
@ -2215,7 +2215,7 @@ static int64_t nTimeProofTxn = 0;
|
|||
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
|
||||
* corresponding to pindexNew, to bypass loading it again from disk.
|
||||
*/
|
||||
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
|
||||
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) {
|
||||
assert(pindexNew->pprev == chainActive.Tip());
|
||||
mempool.check(pcoinsTip);
|
||||
// Read block from disk.
|
||||
|
|
@ -2354,7 +2354,7 @@ static void PruneBlockIndexCandidates() {
|
|||
* Try to make some progress towards making pindexMostWork the active block.
|
||||
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
|
||||
*/
|
||||
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
|
||||
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) {
|
||||
AssertLockHeld(cs_main);
|
||||
bool fInvalidFound = false;
|
||||
const CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||
|
|
@ -2423,7 +2423,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
|
|||
* or an activated best chain. pblock is either NULL or a pointer to a block
|
||||
* that is already loaded (to avoid loading it again from disk).
|
||||
*/
|
||||
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
||||
bool ActivateBestChain(CValidationState &state, const CBlock *pblock) {
|
||||
CBlockIndex *pindexNewTip = NULL;
|
||||
CBlockIndex *pindexMostWork = NULL;
|
||||
do {
|
||||
|
|
@ -3359,7 +3359,7 @@ bool InitBlockIndex() {
|
|||
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
||||
if (!fReindex) {
|
||||
try {
|
||||
CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
|
||||
const CBlock &block = Params().GenesisBlock();
|
||||
// Start new block file
|
||||
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
|
||||
CDiskBlockPos blockPos;
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ std::string GetWarnings(std::string strFor);
|
|||
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
|
||||
/** Find the best known block, and make it the tip of the block chain */
|
||||
bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL);
|
||||
bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL);
|
||||
CAmount GetBlockValue(int nHeight, const CAmount& nFees);
|
||||
|
||||
/** Create a new block index entry for a given block hash */
|
||||
|
|
@ -390,7 +390,7 @@ public:
|
|||
|
||||
|
||||
/** Functions for disk access for blocks */
|
||||
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos);
|
||||
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos);
|
||||
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos);
|
||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
|
||||
|
||||
|
|
|
|||
87
src/test/genesis_tests.cpp
Normal file
87
src/test/genesis_tests.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(genesis_tests)
|
||||
|
||||
// Goal: check that the standard mainnet genesis block is computed correctly
|
||||
BOOST_AUTO_TEST_CASE(genesis_mainnet)
|
||||
{
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
const CChainParams *params = &Params();
|
||||
BOOST_CHECK_EQUAL(params->HashGenesisBlock().GetHex(),
|
||||
params->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params->HashGenesisBlock().GetHex(),
|
||||
"b811a5eeaf27432278c032a0b520f829be2b92fafff9789efe2755fff8ef547b");
|
||||
// Check that unittest genesis hash is same as the mainnet one
|
||||
const CChainParams *params2 = &Params();
|
||||
BOOST_CHECK_EQUAL(params2->HashGenesisBlock().GetHex(),
|
||||
params2->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params2->HashGenesisBlock().GetHex(),
|
||||
"b811a5eeaf27432278c032a0b520f829be2b92fafff9789efe2755fff8ef547b");
|
||||
}
|
||||
|
||||
// Goal: check that the standard testnet genesis block is computed correctly
|
||||
BOOST_AUTO_TEST_CASE(genesis_testnet)
|
||||
{
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
const CChainParams *params = &Params();
|
||||
BOOST_CHECK_EQUAL(params->HashGenesisBlock().GetHex(),
|
||||
params->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params->HashGenesisBlock().GetHex(),
|
||||
"f7f0ca371b1003dc7346bab766b4a131f9e3a5d68820a364d70921cb15b95eaa");
|
||||
// Return params to base case for other tests
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
}
|
||||
|
||||
// Goal: check that the default regtest genesis block is computed correctly
|
||||
BOOST_AUTO_TEST_CASE(genesis_regtest)
|
||||
{
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
const CChainParams *params = &Params();
|
||||
BOOST_CHECK_EQUAL(params->HashGenesisBlock().GetHex(),
|
||||
params->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params->HashGenesisBlock().GetHex(),
|
||||
"b41d03dc310957765223df2bf2f4b3609c79b8b6ac0a0764b20754f972d48b6c");
|
||||
// Return params to base case for other tests
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
}
|
||||
|
||||
// Goal: check that the replacing the signing script pubkey works correctly
|
||||
BOOST_AUTO_TEST_CASE(genesis_customscript)
|
||||
{
|
||||
CScript unsignable = CScript() << OP_FALSE;
|
||||
|
||||
SelectParams(CBaseChainParams::MAIN, unsignable);
|
||||
const CChainParams *params1 = &Params();
|
||||
BOOST_CHECK_EQUAL(params1->HashGenesisBlock().GetHex(),
|
||||
params1->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params1->HashGenesisBlock().GetHex(),
|
||||
"2ec431e3858cef95882cd7d627599fd757afa81938f0b886bee691a48b1e9b58");
|
||||
|
||||
SelectParams(CBaseChainParams::TESTNET, unsignable);
|
||||
const CChainParams *params2 = &Params();
|
||||
BOOST_CHECK_EQUAL(params2->HashGenesisBlock().GetHex(),
|
||||
params2->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params2->HashGenesisBlock().GetHex(),
|
||||
"e28e10e75c6f55edfdb914831b8d48c79fd858b6020963a038ee97dcaae2b355");
|
||||
|
||||
SelectParams(CBaseChainParams::REGTEST, unsignable);
|
||||
const CChainParams *params3 = &Params();
|
||||
BOOST_CHECK_EQUAL(params3->HashGenesisBlock().GetHex(),
|
||||
params3->GenesisBlock().GetHash().GetHex());
|
||||
BOOST_CHECK_EQUAL(params3->HashGenesisBlock().GetHex(),
|
||||
"a99a962c80d71fe1eb0b30217a6f14bc571e3eee97bc16663cf42d9e22eb6cb2");
|
||||
|
||||
// Return params to base case for other tests
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue