From c4eb0e036dc66f419ab92d2a186b38570d24842e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 11 Jan 2017 00:19:01 +0100 Subject: [PATCH] HF: Move block.proof.challenge to Consensus::Params::signblockScript Since the scriptPubKey for signing blocks never changes, there's no point in repeating it with every block header. --- src/chainparams.cpp | 28 ++++++++++++++++------------ src/consensus/params.h | 1 + src/pow.cpp | 23 ++++++----------------- src/pow.h | 6 ++---- src/primitives/block.cpp | 4 ++-- src/primitives/block.h | 7 ++----- src/rpc/blockchain.cpp | 9 ++++++--- src/rpc/mining.cpp | 7 +++---- src/test/test_bitcoin.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 10 files changed, 40 insertions(+), 49 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a0f725d0db..4ac27cd369 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -20,13 +20,13 @@ #include "chainparamsseeds.h" // Safer for users if they load incorrect parameters via arguments. -static std::vector CommitToArguments(const Consensus::Params& params, const std::string& networkID, const CScript& signblockscript) +static std::vector CommitToArguments(const Consensus::Params& params, const std::string& networkID) { CSHA256 sha2; unsigned char commitment[32]; sha2.Write((const unsigned char*)networkID.c_str(), networkID.length()); sha2.Write((const unsigned char*)HexStr(params.fedpegScript).c_str(), HexStr(params.fedpegScript).length()); - sha2.Write((const unsigned char*)HexStr(signblockscript).c_str(), HexStr(signblockscript).length()); + sha2.Write((const unsigned char*)HexStr(params.signblockScript).c_str(), HexStr(params.signblockScript).length()); sha2.Finalize(commitment); return std::vector(commitment, commitment + 32); } @@ -43,7 +43,7 @@ static CScript StrHexToScriptWithDefault(std::string strScript, const CScript de return returnScript; } -static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, const CScript& genesisOutputScript, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion, const CAmount& genesisReward, const uint32_t rewardShards, const CAsset& asset) +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, const CAsset& genesisAsset) { // Shards must be evenly divisible assert(MAX_MONEY % rewardShards == 0); @@ -52,16 +52,16 @@ static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::str txNew.vin.resize(1); txNew.vout.resize(rewardShards); // Any consensus-related values that are command-line set can be added here for anti-footgun - txNew.vin[0].scriptSig = CScript(CommitToArguments(params, networkID, scriptChallenge)); + txNew.vin[0].scriptSig = CScript(CommitToArguments(params, networkID)); for (unsigned int i = 0; i < rewardShards; i++) { txNew.vout[i].nValue = genesisReward/rewardShards; - txNew.vout[i].nAsset = asset; + txNew.vout[i].nAsset = genesisAsset; txNew.vout[i].scriptPubKey = genesisOutputScript; } CBlock genesis; genesis.nTime = nTime; - genesis.proof = CProof(scriptChallenge, CScript()); + genesis.proof = CProof(CScript()); genesis.nVersion = nVersion; genesis.vtx.push_back(MakeTransactionRef(std::move(txNew))); genesis.hashPrevBlock.SetNull(); @@ -85,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", ""), defaultSignblockScript); + consensus.signblockScript = StrHexToScriptWithDefault(GetArg("-signblockscript", ""), defaultSignblockScript); CScript defaultFedpegScript; defaultFedpegScript = CScript() << OP_2 << ParseHex("02d51090b27ca8f1cc04984614bd749d8bab6f2a3681318d3fd0dd43b2a39dd774") << ParseHex("03a75bd7ac458b19f98047c76a6ffa442e592148c5d23a1ec82d379d5d558f4fd8") << ParseHex("034c55bede1bce8e486080f8ebb7a0e8f106b49efb295a8314da0e1b1723738c66") << OP_3 << OP_CHECKMULTISIG; consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", ""), defaultFedpegScript); @@ -145,13 +145,13 @@ class CElementsParams : public CChainParams { parentGenesisBlockHash = uint256S("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); // Generate pegged Bitcoin asset - std::vector commit = CommitToArguments(consensus, strNetworkID, genesisChallengeScript); + std::vector commit = CommitToArguments(consensus, strNetworkID); uint256 entropy; GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash); CalculateAsset(consensus.pegged_asset, entropy); CScript scriptDestination(CScript() << std::vector(parentGenesisBlockHash.begin(), parentGenesisBlockHash.end()) << OP_WITHDRAWPROOFVERIFY); - genesis = CreateGenesisBlock(consensus, strNetworkID, scriptDestination, 1231006505, genesisChallengeScript, 1, MAX_MONEY, 100, consensus.pegged_asset); + genesis = CreateGenesisBlock(consensus, strNetworkID, scriptDestination, 1231006505, 1, MAX_MONEY, 100, consensus.pegged_asset); consensus.hashGenesisBlock = genesis.GetHash(); scriptCoinbaseDestination = CScript() << ParseHex("0229536c4c83789f59c30b93eb40d4abbd99b8dcc99ba8bd748f29e33c1d279e3c") << OP_CHECKSIG; @@ -212,7 +212,7 @@ class CRegTestParams : public CChainParams { public: CRegTestParams() { const CScript defaultRegtestScript(CScript() << OP_TRUE); - CScript genesisChallengeScript = StrHexToScriptWithDefault(GetArg("-signblockscript", ""), defaultRegtestScript); + consensus.signblockScript = StrHexToScriptWithDefault(GetArg("-signblockscript", ""), defaultRegtestScript); consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", ""), defaultRegtestScript); strNetworkID = CHAINPARAMS_REGTEST; @@ -255,12 +255,12 @@ class CRegTestParams : public CChainParams { parentGenesisBlockHash = uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"); // Generate pegged Bitcoin asset - std::vector commit = CommitToArguments(consensus, strNetworkID, genesisChallengeScript); + std::vector commit = CommitToArguments(consensus, strNetworkID); uint256 entropy; GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash); CalculateAsset(consensus.pegged_asset, entropy); - genesis = CreateGenesisBlock(consensus, strNetworkID, defaultRegtestScript, 1296688602, genesisChallengeScript, 1, MAX_MONEY, 100, consensus.pegged_asset); + genesis = CreateGenesisBlock(consensus, strNetworkID, defaultRegtestScript, 1296688602, 1, MAX_MONEY, 100, consensus.pegged_asset); consensus.hashGenesisBlock = genesis.GetHash(); @@ -321,6 +321,10 @@ class CCustomParams : public CChainParams { // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S(GetArg("-con_defaultassumevalid", "0x00")); + const CScript defaultRegtestScript(CScript() << OP_TRUE); + consensus.signblockScript = StrHexToScriptWithDefault(GetArg("-signblockscript", ""), defaultRegtestScript); + consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", ""), defaultRegtestScript); + nDefaultPort = GetArg("-ndefaultport", 18444); nPruneAfterHeight = GetArg("-npruneafterheight", 1000); fDefaultConsistencyChecks = GetBoolArg("-fdefaultconsistencychecks", true); diff --git a/src/consensus/params.h b/src/consensus/params.h index 9fed70b535..e84062357f 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -68,6 +68,7 @@ struct Params { CScript fedpegScript; CAsset pegged_asset; uint256 defaultAssumeValid; + CScript signblockScript; }; } // namespace Consensus diff --git a/src/pow.cpp b/src/pow.cpp index 22dc6b9136..78602683be 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -21,21 +21,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(uint256 hash, unsigned int nBits) @@ -61,14 +60,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 @@ -85,16 +84,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; diff --git a/src/pow.h b/src/pow.h index 6e0f6a36dd..a1c3655dcc 100644 --- a/src/pow.h +++ b/src/pow.h @@ -24,17 +24,15 @@ class uint256; bool CheckBitcoinProof(uint256 hash, unsigned int nBits); 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); diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 8755a0bbea..18262cedc5 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -13,8 +13,8 @@ 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 diff --git a/src/primitives/block.h b/src/primitives/block.h index 9ef00c71a9..875818bcc9 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -14,34 +14,31 @@ 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 inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*(CScriptBase*)(&challenge)); if (!(s.GetType() & SER_GETHASH)) READWRITE(*(CScriptBase*)(&solution)); } void SetNull() { - challenge.clear(); solution.clear(); } bool IsNull() const { - return challenge.empty(); + return solution.empty(); } std::string ToString() const; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9427f68a3b..059b0ee2a5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -10,6 +10,7 @@ #include "coins.h" #include "consensus/validation.h" #include "validation.h" +#include "core_io.h" #include "policy/policy.h" #include "primitives/transaction.h" #include "rpc/server.h" @@ -74,7 +75,6 @@ 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("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); @@ -118,7 +118,6 @@ 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("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); @@ -1046,6 +1045,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) "\nResult:\n" "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"signblockhex\": \"xxxx\", (string) the scriptPubKey for signing blocks as a hex string.\n" + " \"signblockasm\": \"xxxx\", (string) the scriptPubKey for signing blocks in a format more readable for humans (asm).\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" @@ -1079,10 +1080,13 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) + HelpExampleRpc("getblockchaininfo", "") ); + const Consensus::Params& consensusParams = Params().GetConsensus(); LOCK(cs_main); UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); + obj.push_back(Pair("signblockhex", HexStr(consensusParams.signblockScript))); + obj.push_back(Pair("signblockasm", ScriptToAsmStr(consensusParams.signblockScript))); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); @@ -1092,7 +1096,6 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); - const Consensus::Params& consensusParams = Params().GetConsensus(); UniValue bip9_softforks(UniValue::VOBJ); BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV); BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 5ccd03a615..0d3cef5e60 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -215,14 +215,15 @@ UniValue combineblocksigs(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); UniValue result(UniValue::VOBJ); + const Consensus::Params& consensusParams = Params().GetConsensus(); const UniValue& sigs = request.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 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; @@ -738,7 +739,6 @@ UniValue getblocktemplate(const JSONRPCRequest& request) 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("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); @@ -755,7 +755,6 @@ UniValue getblocktemplate(const JSONRPCRequest& request) 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("height", (int64_t)(pindexPrev->nHeight+1))); if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index e4e59e259c..904c90dedf 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -73,7 +73,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha newCoinbase.vout[i].scriptPubKey = scriptPubKey; const_cast(Params().GenesisBlock()).vtx[0] = MakeTransactionRef(newCoinbase); const_cast(Params().GenesisBlock()).hashMerkleRoot = BlockMerkleRoot(Params().GenesisBlock()); - const_cast(Params().GenesisBlock()).proof = CProof(CScript()<(Params().GenesisBlock()).proof = CProof(CScript()); const_cast(Params().GetConsensus()).hashGenesisBlock = Params().GenesisBlock().GetHash(); ClearDatadirCache(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 095871ee98..75355e6d31 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3369,7 +3369,7 @@ UniValue signblock(const JSONRPCRequest& request) } block.proof.solution = CScript(); - MaybeGenerateProof(&block, pwalletMain); + MaybeGenerateProof(Params().GetConsensus(), &block, pwalletMain); return HexStr(block.proof.solution.begin(), block.proof.solution.end()); }