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

HF: Move block.proof.challenge to Consensus::Params::signblockScript #111

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "util.h"
#include "utilstrencodings.h"
#include "amount.h"
#include "crypto/ripemd160.h"

#include <assert.h>

Expand All @@ -18,6 +19,18 @@

#include "chainparamsseeds.h"

// Safer for users if they load incorrect parameters via arguments.
static std::vector<unsigned char> CommitToArguments(const Consensus::Params& params, const std::string& networkID)
{
CRIPEMD160 ripemd;
unsigned char commitment[20];
ripemd.Write((const unsigned char*)networkID.c_str(), networkID.length());
ripemd.Write((const unsigned char*)HexStr(params.fedpegScript).c_str(), HexStr(params.fedpegScript).length());
ripemd.Write((const unsigned char*)HexStr(params.signblockScript).c_str(), HexStr(params.signblockScript).length());
ripemd.Finalize(commitment);
return std::vector<unsigned char>(commitment, commitment + 20);
}

static CScript StrHexToScriptWithDefault(std::string strScript, const CScript defaultScript)
{
CScript returnScript;
Expand All @@ -30,14 +43,15 @@ static CScript StrHexToScriptWithDefault(std::string strScript, const CScript de
return returnScript;
}

static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion, const CAmount& genesisReward, const uint32_t rewardShards)
static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, const CScript& genesisOutputScript, uint32_t nTime, int32_t nVersion, const CAmount& genesisReward, const uint32_t rewardShards)
{
// Shards must be evenly divisible
assert(MAX_MONEY % rewardShards == 0);
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
// Any consensus-related values that are command-line set can be added here for anti-footgun
txNew.vin[0].scriptSig = CScript(CommitToArguments(params, networkID));
txNew.vout.resize(rewardShards);
for (unsigned int i = 0; i < rewardShards; i++) {
txNew.vout[i].nValue = genesisReward/rewardShards;
Expand All @@ -46,7 +60,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi

CBlock genesis;
genesis.nTime = nTime;
genesis.proof = CProof(scriptChallenge, CScript());
genesis.proof = CProof(CScript());
genesis.nVersion = nVersion;
genesis.vtx.push_back(txNew);
genesis.hashPrevBlock.SetNull();
Expand All @@ -71,7 +85,7 @@ class CElementsParams : public CChainParams {
CScript defaultSignblockScript;
// Default blocksign script for elements
defaultSignblockScript = CScript() << OP_2 << ParseHex("03206b45265ae687dfdc602b8faa7dd749d7865b0e51f986e12c532229f0c998be") << ParseHex("02cc276552e180061f64dc16e2a02e7f9ecbcc744dea84eddbe991721824df825c") << ParseHex("0204c6be425356d9200a3303d95f2c39078cc9473ca49619da1e0ec233f27516ca") << OP_3 << OP_CHECKMULTISIG;
CScript genesisChallengeScript = StrHexToScriptWithDefault(GetArg("-signblockscript", "", mapArgs), defaultSignblockScript);
consensus.signblockScript = StrHexToScriptWithDefault(GetArg("-signblockscript", "", mapArgs), defaultSignblockScript);
CScript defaultFedpegScript;
defaultFedpegScript = CScript() << OP_2 << ParseHex("02d51090b27ca8f1cc04984614bd749d8bab6f2a3681318d3fd0dd43b2a39dd774") << ParseHex("03a75bd7ac458b19f98047c76a6ffa442e592148c5d23a1ec82d379d5d558f4fd8") << ParseHex("034c55bede1bce8e486080f8ebb7a0e8f106b49efb295a8314da0e1b1723738c66") << OP_3 << OP_CHECKMULTISIG;
consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", "", mapArgs), defaultFedpegScript);
Expand Down Expand Up @@ -124,7 +138,7 @@ class CElementsParams : public CChainParams {

parentGenesisBlockHash = uint256S("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");
CScript scriptDestination(CScript() << std::vector<unsigned char>(parentGenesisBlockHash.begin(), parentGenesisBlockHash.end()) << OP_WITHDRAWPROOFVERIFY);
genesis = CreateGenesisBlock(strNetworkID.c_str(), scriptDestination, 1231006505, genesisChallengeScript, 1, MAX_MONEY, 100);
genesis = CreateGenesisBlock(consensus, strNetworkID, scriptDestination, 1231006505, 1, MAX_MONEY, 100);
consensus.hashGenesisBlock = genesis.GetHash();

scriptCoinbaseDestination = CScript() << ParseHex("0229536c4c83789f59c30b93eb40d4abbd99b8dcc99ba8bd748f29e33c1d279e3c") << OP_CHECKSIG;
Expand Down Expand Up @@ -192,7 +206,7 @@ class CRegTestParams : public CChainParams {
void Reset(const std::map<std::string, std::string>& mapArgs)
{
const CScript defaultRegtestScript(CScript() << OP_TRUE);
CScript genesisChallengeScript = StrHexToScriptWithDefault(GetArg("-signblockscript", "", mapArgs), defaultRegtestScript);
consensus.signblockScript = StrHexToScriptWithDefault(GetArg("-signblockscript", "", mapArgs), defaultRegtestScript);
consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", "", mapArgs), defaultRegtestScript);

strNetworkID = CHAINPARAMS_REGTEST;
Expand Down Expand Up @@ -227,7 +241,7 @@ class CRegTestParams : public CChainParams {
nDefaultPort = 7042;
nPruneAfterHeight = 1000;

genesis = CreateGenesisBlock(strNetworkID.c_str(), defaultRegtestScript, 1296688602, genesisChallengeScript, 1, MAX_MONEY, 100);
genesis = CreateGenesisBlock(consensus, strNetworkID, defaultRegtestScript, 1296688602, 1, MAX_MONEY, 100);
consensus.hashGenesisBlock = genesis.GetHash();

parentGenesisBlockHash = uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206");
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct Params {
int64_t nPowTargetTimespan;
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
CScript fedpegScript;
CScript signblockScript;
};
} // namespace Consensus

Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// If the loaded chain has a wrong genesis, bail out immediately
// (we're likely using a testnet datadir, or the other way around).
if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0)
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
return InitError(_("Incorrect or no genesis block found. Wrong `-fedpegscript`, `-signblockscript`, or datadir for network?"));

// Initialize the block index (no-op if non-empty database was already loaded)
if (!InitBlockIndex(chainparams)) {
Expand Down
23 changes: 6 additions & 17 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,20 @@
#include "wallet/wallet.h"
#endif

CScript CombineBlockSignatures(const CBlockHeader& header, const CScript& scriptSig1, const CScript& scriptSig2)
CScript CombineBlockSignatures(const Consensus::Params& params, const CBlockHeader& header, const CScript& scriptSig1, const CScript& scriptSig2)
{
SignatureData sig1(scriptSig1);
SignatureData sig2(scriptSig2);
return GenericCombineSignatures(header.proof.challenge, header, sig1, sig2).scriptSig;
return GenericCombineSignatures(params.signblockScript, header, sig1, sig2).scriptSig;
}

bool CheckChallenge(const CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params& params)
{
return block.proof.challenge == indexLast.proof.challenge;
return true;
}

void ResetChallenge(CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params& params)
{
block.proof.challenge = indexLast.proof.challenge;
}

bool CheckBitcoinProof(const CBlockHeader& block)
Expand Down Expand Up @@ -62,14 +61,14 @@ bool CheckProof(const CBlockHeader& block, const Consensus::Params& params)
{
if (block.GetHash() == params.hashGenesisBlock)
return true;
return GenericVerifyScript(block.proof.solution, block.proof.challenge, SCRIPT_VERIFY_P2SH, block);
return GenericVerifyScript(block.proof.solution, params.signblockScript, SCRIPT_VERIFY_P2SH, block);
}

bool MaybeGenerateProof(CBlockHeader *pblock, CWallet *pwallet)
bool MaybeGenerateProof(const Consensus::Params& params, CBlockHeader *pblock, CWallet *pwallet)
{
#ifdef ENABLE_WALLET
SignatureData solution(pblock->proof.solution);
bool res = GenericSignScript(*pwallet, *pblock, pblock->proof.challenge, solution);
bool res = GenericSignScript(*pwallet, *pblock, params.signblockScript, solution);
pblock->proof.solution = solution.scriptSig;
return res;
#endif
Expand All @@ -86,16 +85,6 @@ double GetChallengeDifficulty(const CBlockIndex* blockindex)
return 1;
}

std::string GetChallengeStr(const CBlockIndex& block)
{
return ScriptToAsmStr(block.proof.challenge);
}

std::string GetChallengeStrHex(const CBlockIndex& block)
{
return ScriptToAsmStr(block.proof.challenge);
}

uint32_t GetNonce(const CBlockHeader& block)
{
return 1;
Expand Down
6 changes: 2 additions & 4 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,15 @@ class uint256;
bool CheckBitcoinProof(const CBlockHeader& block);
bool CheckProof(const CBlockHeader& block, const Consensus::Params&);
/** Scans nonces looking for a hash with at least some zero bits */
bool MaybeGenerateProof(CBlockHeader* pblock, CWallet* pwallet);
bool MaybeGenerateProof(const Consensus::Params& params, CBlockHeader* pblock, CWallet* pwallet);
void ResetProof(CBlockHeader& block);
bool CheckChallenge(const CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params&);
void ResetChallenge(CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params&);

CScript CombineBlockSignatures(const CBlockHeader& header, const CScript& scriptSig1, const CScript& scriptSig2);
CScript CombineBlockSignatures(const Consensus::Params& params, const CBlockHeader& header, const CScript& scriptSig1, const CScript& scriptSig2);

/** Avoid using these functions when possible */
double GetChallengeDifficulty(const CBlockIndex* blockindex);
std::string GetChallengeStr(const CBlockIndex& block);
std::string GetChallengeStrHex(const CBlockIndex& block);
uint32_t GetNonce(const CBlockHeader& block);
void SetNonce(CBlockHeader& block, uint32_t nNonce);

Expand Down
4 changes: 2 additions & 2 deletions src/primitives/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ std::string CBitcoinProof::ToString() const

std::string CProof::ToString() const
{
return strprintf("CProof(challenge=%s, solution=%s)",
ScriptToAsmStr(challenge), ScriptToAsmStr(solution));
return strprintf("CProof(solution=%s)",
ScriptToAsmStr(solution));
}

uint256 CBlockHeader::GetHash() const
Expand Down
7 changes: 2 additions & 5 deletions src/primitives/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,34 +51,31 @@ class CBitcoinProof
class CProof
{
public:
CScript challenge;
CScript solution;

CProof()
{
SetNull();
}
CProof(CScript challengeIn, CScript solutionIn) : challenge(challengeIn), solution(solutionIn) {}
CProof(CScript solutionIn) : solution(solutionIn) {}

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
{
READWRITE(*(CScriptBase*)(&challenge));
if (!(nType & SER_GETHASH))
READWRITE(*(CScriptBase*)(&solution));
}

void SetNull()
{
challenge.clear();
solution.clear();
}

bool IsNull() const
{
return challenge.empty();
return solution.empty();
}

std::string ToString() const;
Expand Down
5 changes: 3 additions & 2 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "checkpoints.h"
#include "coins.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "main.h"
#include "policy/policy.h"
#include "primitives/transaction.h"
Expand Down Expand Up @@ -62,7 +63,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
result.push_back(Pair("time", (int64_t)blockindex->nTime));
result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
result.push_back(Pair("nonce", (uint64_t)GetNonce(blockindex->GetBlockHeader())));
result.push_back(Pair("bits", GetChallengeStr(blockindex->GetBlockHeader())));
result.push_back(Pair("bits", ScriptToAsmStr(Params().GetConsensus().signblockScript)));
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));

Expand Down Expand Up @@ -106,7 +107,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
result.push_back(Pair("time", block.GetBlockTime()));
result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
result.push_back(Pair("nonce", (uint64_t)GetNonce(block)));
result.push_back(Pair("bits", GetChallengeStr(block)));
result.push_back(Pair("bits", ScriptToAsmStr(Params().GetConsensus().signblockScript)));
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));

Expand Down
10 changes: 6 additions & 4 deletions src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,15 @@ UniValue combineblocksigs(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");

UniValue result(UniValue::VOBJ);
const Consensus::Params& consensusParams = Params().GetConsensus();
const UniValue& sigs = params[1].get_array();
for (unsigned int i = 0; i < sigs.size(); i++) {
const std::string& sig = sigs[i].get_str();
if (!IsHex(sig))
continue;
std::vector<unsigned char> vchScript = ParseHex(sig);
block.proof.solution = CombineBlockSignatures(block, block.proof.solution, CScript(vchScript.begin(), vchScript.end()));
if (CheckProof(block, Params().GetConsensus())) {
block.proof.solution = CombineBlockSignatures(consensusParams, block, block.proof.solution, CScript(vchScript.begin(), vchScript.end()));
if (CheckProof(block, consensusParams)) {
result.push_back(Pair("hex", EncodeHexBlock(block)));
result.push_back(Pair("complete", true));
return result;
Expand Down Expand Up @@ -662,6 +663,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
aMutable.push_back("transactions");
aMutable.push_back("prevblock");

const std::string signblockStr = ScriptToAsmStr(Params().GetConsensus().signblockScript);
UniValue result(UniValue::VOBJ);
result.push_back(Pair("capabilities", aCaps));

Expand Down Expand Up @@ -725,7 +727,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
result.push_back(Pair("coinbaseaux", aux));
result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue.GetAmount()));
result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
result.push_back(Pair("target", GetChallengeStrHex(*pblock)));
result.push_back(Pair("target", signblockStr));
result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
result.push_back(Pair("mutable", aMutable));
result.push_back(Pair("noncerange", "00000000ffffffff"));
Expand All @@ -738,7 +740,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE));
result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT));
result.push_back(Pair("curtime", pblock->GetBlockTime()));
result.push_back(Pair("bits", GetChallengeStr(*pblock)));
result.push_back(Pair("bits", signblockStr));
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
if (!pblocktemplate->vchCoinbaseCommitment.empty()) {
result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())));
Expand Down
2 changes: 1 addition & 1 deletion src/test/test_bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
newCoinbase.vout[i].scriptPubKey = scriptPubKey;
const_cast<CBlock&>(Params().GenesisBlock()).vtx[0] = newCoinbase;
const_cast<CBlock&>(Params().GenesisBlock()).hashMerkleRoot = BlockMerkleRoot(Params().GenesisBlock());
const_cast<CBlock&>(Params().GenesisBlock()).proof = CProof(CScript()<<OP_TRUE, CScript());
const_cast<CBlock&>(Params().GenesisBlock()).proof = CProof(CScript());
const_cast<Consensus::Params&>(Params().GetConsensus()).hashGenesisBlock = Params().GenesisBlock().GetHash();

ClearDatadirCache();
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2694,7 +2694,7 @@ UniValue signblock(const UniValue& params, bool fHelp)
}

block.proof.solution = CScript();
MaybeGenerateProof(&block, pwalletMain);
MaybeGenerateProof(Params().GetConsensus(), &block, pwalletMain);
return HexStr(block.proof.solution.begin(), block.proof.solution.end());
}

Expand Down