diff --git a/src/block_proof.cpp b/src/block_proof.cpp index 1478e2246e..0c1a279d68 100644 --- a/src/block_proof.cpp +++ b/src/block_proof.cpp @@ -13,7 +13,7 @@ bool CheckChallenge(const CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params& params) { if (g_signed_blocks) { - return block.proof.challenge == indexLast.proof.challenge; + return block.proof.challenge == indexLast.get_proof().challenge; } else { return block.nBits == GetNextWorkRequired(&indexLast, &block, params); } diff --git a/src/chain.h b/src/chain.h index 80d56325f7..8617d9733a 100644 --- a/src/chain.h +++ b/src/chain.h @@ -192,10 +192,51 @@ public: uint32_t nTime{0}; uint32_t nBits{0}; uint32_t nNonce{0}; - CProof proof{}; + +protected: + std::optional proof{}; // Dynamic federation fields - DynaFedParams dynafed_params{}; - CScriptWitness m_signblock_witness{}; + std::optional m_dynafed_params{}; + std::optional m_signblock_witness{}; + + bool m_trimmed{false}; + + friend class CBlockTreeDB; + +public: + + // Irrevocably remove blocksigning and dynafed-related stuff from this + // in-memory copy of the block header. + void trim() { + assert_untrimmed(); + m_trimmed = true; + proof = std::nullopt; + m_dynafed_params = std::nullopt; + m_signblock_witness = std::nullopt; + } + + bool trimmed() const { + return m_trimmed; + } + + void assert_untrimmed() const { + assert(!m_trimmed); + } + + const CProof& get_proof() const { + assert_untrimmed(); + return proof.value(); + } + + const DynaFedParams& dynafed_params() const { + assert_untrimmed(); + return m_dynafed_params.value(); + } + + const CScriptWitness& signblock_witness() const { + assert_untrimmed(); + return m_signblock_witness.value(); + } //! (memory only) Sequential id assigned to distinguish order in which blocks are received. int32_t nSequenceId{0}; @@ -214,7 +255,7 @@ public: nBits{block.nBits}, nNonce{block.nNonce}, proof{block.proof}, - dynafed_params{block.m_dynafed_params}, + m_dynafed_params{block.m_dynafed_params}, m_signblock_witness{block.m_signblock_witness} { } @@ -239,6 +280,7 @@ public: CBlockHeader GetBlockHeader() const { + assert_untrimmed(); CBlockHeader block; block.nVersion = nVersion; if (pprev) @@ -250,9 +292,9 @@ public: } block.nBits = nBits; block.nNonce = nNonce; - block.proof = proof; - block.m_dynafed_params = dynafed_params; - block.m_signblock_witness = m_signblock_witness; + block.proof = proof.value(); + block.m_dynafed_params = m_dynafed_params.value(); + block.m_signblock_witness = m_signblock_witness.value(); return block; } @@ -366,12 +408,12 @@ public: nVersion = ~CBlockHeader::DYNAFED_HF_MASK & nVersion; return is_dyna; } else { - return !dynafed_params.IsNull(); + return !dynafed_params().IsNull(); } } bool RemoveDynaFedMaskOnSerialize(bool for_read) const { assert(!for_read); - return !dynafed_params.IsNull(); + return !dynafed_params().IsNull(); } SERIALIZE_METHODS(CDiskBlockIndex, obj) @@ -394,7 +436,7 @@ public: READWRITE(obj.nVersion); } else { int32_t nVersion = obj.nVersion; - if (!obj.dynafed_params.IsNull()) { + if (!obj.dynafed_params().IsNull()) { nVersion |= CBlockHeader::DYNAFED_HF_MASK; } READWRITE(nVersion); @@ -406,11 +448,14 @@ public: READWRITE(obj.nTime); // For compatibility with elements 0.14 based chains if (g_signed_blocks) { + SER_READ(obj, obj.m_dynafed_params = DynaFedParams()); + SER_READ(obj, obj.m_signblock_witness = CScriptWitness()); + SER_READ(obj, obj.proof = CProof()); if (is_dyna) { - READWRITE(obj.dynafed_params); - READWRITE(obj.m_signblock_witness.stack); + READWRITE(obj.m_dynafed_params.value()); + READWRITE(obj.m_signblock_witness.value().stack); } else { - READWRITE(obj.proof); + READWRITE(obj.proof.value()); } } else { READWRITE(obj.nBits); @@ -420,6 +465,7 @@ public: uint256 GetBlockHash() const { + assert_untrimmed(); CBlockHeader block; block.nVersion = nVersion; block.hashPrevBlock = hashPrev; @@ -430,8 +476,8 @@ public: } block.nBits = nBits; block.nNonce = nNonce; - block.proof = proof; - block.m_dynafed_params = dynafed_params; + block.proof = proof.value(); + block.m_dynafed_params = m_dynafed_params.value(); return block.GetHash(); } diff --git a/src/dynafed.cpp b/src/dynafed.cpp index be123c5d43..5ef34edcbd 100644 --- a/src/dynafed.cpp +++ b/src/dynafed.cpp @@ -15,7 +15,7 @@ bool NextBlockIsParameterTransition(const CBlockIndex* pindexPrev, const Consens for (int32_t height = next_height - 1; height >= (int32_t)(next_height - consensus.dynamic_epoch_length); --height) { const CBlockIndex* p_epoch_walk = pindexPrev->GetAncestor(height); assert(p_epoch_walk); - const DynaFedParamEntry& proposal = p_epoch_walk->dynafed_params.m_proposed; + const DynaFedParamEntry& proposal = p_epoch_walk->dynafed_params().m_proposed; const uint256 proposal_root = proposal.CalculateRoot(); vote_tally[proposal_root]++; // Short-circuit once 4/5 threshold is reached @@ -56,13 +56,13 @@ DynaFedParamEntry ComputeNextBlockFullCurrentParameters(const CBlockIndex* pinde // may be pre-dynafed params const CBlockIndex* p_epoch_start = pindexPrev->GetAncestor(epoch_start_height); assert(p_epoch_start); - if (p_epoch_start->dynafed_params.IsNull()) { + if (p_epoch_start->dynafed_params().IsNull()) { // We need to construct the "full" current parameters of pre-dynafed // consensus // Convert signblockscript to P2WSH uint256 signblock_witness_program; - CSHA256().Write(p_epoch_start->proof.challenge.data(), p_epoch_start->proof.challenge.size()).Finalize(signblock_witness_program.begin()); + CSHA256().Write(p_epoch_start->get_proof().challenge.data(), p_epoch_start->get_proof().challenge.size()).Finalize(signblock_witness_program.begin()); CScript p2wsh_signblock_script = CScript() << OP_0 << ToByteVector(signblock_witness_program); // Make P2SH-P2WSH-ness of non-dynafed fedpegscript explicit @@ -75,7 +75,7 @@ DynaFedParamEntry ComputeNextBlockFullCurrentParameters(const CBlockIndex* pinde // Put them in winning proposal winning_proposal = DynaFedParamEntry(p2wsh_signblock_script, consensus.max_block_signature_size, sh_wsh_fedpeg_program, consensus.fedpegScript, consensus.first_extension_space); } else { - winning_proposal = p_epoch_start->dynafed_params.m_current; + winning_proposal = p_epoch_start->dynafed_params().m_current; } return winning_proposal; } @@ -93,7 +93,7 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre // Return appropriate format based on epoch age or if we *just* activated // dynafed via BIP9 - if (epoch_age == 0 || pindexPrev->dynafed_params.IsNull()) { + if (epoch_age == 0 || pindexPrev->dynafed_params().IsNull()) { return entry; } else { return DynaFedParamEntry(entry.m_signblockscript, entry.m_signblock_witness_limit, entry.CalculateExtraRoot()); diff --git a/src/miner.cpp b/src/miner.cpp index 75a6bbd9be..9bee5755de 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -29,7 +29,7 @@ void ResetChallenge(CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params& params) { - block.proof.challenge = indexLast.proof.challenge; + block.proof.challenge = indexLast.get_proof().challenge; } void ResetProof(CBlockHeader& block) diff --git a/src/pegins.cpp b/src/pegins.cpp index e9a7b6c74e..dc133d1fbc 100644 --- a/src/pegins.cpp +++ b/src/pegins.cpp @@ -487,8 +487,8 @@ std::vector> GetValidFedpegScripts(const CBlockIndex break; } - if (!p_epoch_start->dynafed_params.IsNull()) { - fedpegscripts.push_back(std::make_pair(p_epoch_start->dynafed_params.m_current.m_fedpeg_program, p_epoch_start->dynafed_params.m_current.m_fedpegscript)); + if (!p_epoch_start->dynafed_params().IsNull()) { + fedpegscripts.push_back(std::make_pair(p_epoch_start->dynafed_params().m_current.m_fedpeg_program, p_epoch_start->dynafed_params().m_current.m_fedpegscript)); } else { fedpegscripts.push_back(std::make_pair(GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(params.fedpegScript)))), params.fedpegScript)); } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b5c85aa77b..6db3520170 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -248,13 +248,13 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex result.pushKV("difficulty", GetDifficulty(blockindex)); result.pushKV("chainwork", blockindex->nChainWork.GetHex()); } else { - if (blockindex->dynafed_params.IsNull()) { - result.pushKV("signblock_witness_asm", ScriptToAsmStr(blockindex->proof.solution)); - result.pushKV("signblock_witness_hex", HexStr(blockindex->proof.solution)); - result.pushKV("signblock_challenge", HexStr(blockindex->proof.challenge)); + if (blockindex->dynafed_params().IsNull()) { + result.pushKV("signblock_witness_asm", ScriptToAsmStr(blockindex->get_proof().solution)); + result.pushKV("signblock_witness_hex", HexStr(blockindex->get_proof().solution)); + result.pushKV("signblock_challenge", HexStr(blockindex->get_proof().challenge)); } else { - result.pushKV("signblock_witness_hex", EncodeHexScriptWitness(blockindex->m_signblock_witness)); - result.pushKV("dynamic_parameters", dynaParamsToJSON(blockindex->dynafed_params)); + result.pushKV("signblock_witness_hex", EncodeHexScriptWitness(blockindex->signblock_witness())); + result.pushKV("dynamic_parameters", dynaParamsToJSON(blockindex->dynafed_params())); } } result.pushKV("nTx", (uint64_t)blockindex->nTx); diff --git a/src/txdb.cpp b/src/txdb.cpp index f616ab3288..a283742462 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -335,7 +335,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, pindexNew->proof = diskindex.proof; pindexNew->nStatus = diskindex.nStatus; pindexNew->nTx = diskindex.nTx; - pindexNew->dynafed_params = diskindex.dynafed_params; + pindexNew->m_dynafed_params = diskindex.m_dynafed_params; pindexNew->m_signblock_witness = diskindex.m_signblock_witness; const uint256 block_hash = pindexNew->GetBlockHash(); diff --git a/src/validation.cpp b/src/validation.cpp index c96515f3d7..7f97c08980 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2464,13 +2464,13 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew) !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages.original) : ""); // Do some logging if dynafed parameters changed. - if (pindexNew->pprev && !pindexNew->dynafed_params.IsNull()) { + if (pindexNew->pprev && !pindexNew->dynafed_params().IsNull()) { int height = pindexNew->nHeight; uint256 hash = pindexNew->GetBlockHash(); - uint256 root = pindexNew->dynafed_params.m_current.CalculateRoot(); - if (pindexNew->pprev->dynafed_params.IsNull()) { + uint256 root = pindexNew->dynafed_params().m_current.CalculateRoot(); + if (pindexNew->pprev->dynafed_params().IsNull()) { LogPrintf("Dynafed activated in block %d:%s: %s\n", height, hash.GetHex(), root.GetHex()); - } else if (root != pindexNew->pprev->dynafed_params.m_current.CalculateRoot()) { + } else if (root != pindexNew->pprev->dynafed_params().m_current.CalculateRoot()) { LogPrintf("New dynafed parameters activated in block %d:%s: %s\n", height, hash.GetHex(), root.GetHex()); } } diff --git a/src/validation.h b/src/validation.h index 7f04f1a740..f4ebc713d9 100644 --- a/src/validation.h +++ b/src/validation.h @@ -649,6 +649,7 @@ public: //! @returns A reference to the in-memory cache of the UTXO set. CCoinsViewCache& CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main) { + assert(m_coins_views); assert(m_coins_views->m_cacheview); return *m_coins_views->m_cacheview.get(); }