Skip to content

Commit

Permalink
HF: Move block.proof.challenge to Consensus::Params::signblockScript
Browse files Browse the repository at this point in the history
Since the scriptPubKey for signing blocks never changes, there's no
point in repeating it with every block header.
  • Loading branch information
jtimon committed Sep 21, 2017
1 parent 37ae000 commit c4eb0e0
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 49 deletions.
28 changes: 16 additions & 12 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
#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, const CScript& signblockscript)
static std::vector<unsigned char> 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<unsigned char>(commitment, commitment + 32);
}
Expand All @@ -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);
Expand All @@ -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();
Expand All @@ -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);
Expand Down Expand Up @@ -145,13 +145,13 @@ class CElementsParams : public CChainParams {
parentGenesisBlockHash = uint256S("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");

// Generate pegged Bitcoin asset
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID, genesisChallengeScript);
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
uint256 entropy;
GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash);
CalculateAsset(consensus.pegged_asset, entropy);

CScript scriptDestination(CScript() << std::vector<unsigned char>(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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -255,12 +255,12 @@ class CRegTestParams : public CChainParams {
parentGenesisBlockHash = uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206");

// Generate pegged Bitcoin asset
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID, genesisChallengeScript);
std::vector<unsigned char> 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();


Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct Params {
CScript fedpegScript;
CAsset pegged_asset;
uint256 defaultAssumeValid;
CScript signblockScript;
};
} // namespace Consensus

Expand Down
23 changes: 6 additions & 17 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions src/primitives/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 2 additions & 5 deletions src/primitives/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename Stream, typename Operation>
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;
Expand Down
9 changes: 6 additions & 3 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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()));

Expand Down Expand Up @@ -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()));

Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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()));
Expand All @@ -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);
Expand Down
7 changes: 3 additions & 4 deletions src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<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 @@ -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"));
Expand All @@ -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) {
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 @@ -73,7 +73,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
newCoinbase.vout[i].scriptPubKey = scriptPubKey;
const_cast<CBlock&>(Params().GenesisBlock()).vtx[0] = MakeTransactionRef(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 @@ -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());
}

Expand Down

0 comments on commit c4eb0e0

Please sign in to comment.