diff --git a/src/dynafed.cpp b/src/dynafed.cpp index de7ada67b99..13fbc8c147f 100644 --- a/src/dynafed.cpp +++ b/src/dynafed.cpp @@ -94,7 +94,7 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre // Return appropriate format based on epoch age if (epoch_age > 0) { // TODO implement "prune" function to remove fields in place and change serialize type - return DynaFedParamEntry(entry.m_signblockscript, entry.m_signblock_witness_limit); + return DynaFedParamEntry(entry.m_signblockscript, entry.m_signblock_witness_limit, entry.CalculateExtraRoot()); } else { return entry; } diff --git a/src/miner.cpp b/src/miner.cpp index 6d311b74c21..1b0c2bb0fea 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -151,8 +151,8 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()); if (IsDynaFedEnabled(pindexPrev, chainparams.GetConsensus())) { - DynaFedParamEntry current_params = ComputeNextBlockCurrentParameters(chainActive.Tip(), chainparams.GetConsensus()); - DynaFedParams block_params(current_params, proposed_entry ? *proposed_entry : DynaFedParamEntry()); + const DynaFedParamEntry current_params = ComputeNextBlockCurrentParameters(chainActive.Tip(), chainparams.GetConsensus()); + const DynaFedParams block_params(current_params, proposed_entry ? *proposed_entry : DynaFedParamEntry()); pblock->m_dynafed_params = block_params; nBlockWeight += ::GetSerializeSize(block_params, PROTOCOL_VERSION)*WITNESS_SCALE_FACTOR; nBlockWeight += current_params.m_signblock_witness_limit; // Note witness discount diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 2b724497401..b17371e50d7 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -43,19 +43,39 @@ std::string CBlock::ToString() const uint256 DynaFedParamEntry::CalculateRoot() const { - if (IsNull()) { + if (m_serialize_type == 0) { return uint256(); } + std::vector compact_leaves; + compact_leaves.push_back(SerializeHash(m_signblockscript, SER_GETHASH, 0)); + compact_leaves.push_back(SerializeHash(m_signblock_witness_limit, SER_GETHASH, 0)); + uint256 compact_root(ComputeFastMerkleRoot(compact_leaves)); + + uint256 extra_root; + if (m_serialize_type ==1 ) { + // It's pruned, take the stored value + extra_root = m_elided_root; + } else if (m_serialize_type == 2) { + // It's unpruned, compute the node value + extra_root = CalculateExtraRoot(); + } + std::vector leaves; - leaves.push_back(SerializeHash(m_signblockscript, SER_GETHASH, 0)); - leaves.push_back(SerializeHash(m_signblock_witness_limit, SER_GETHASH, 0)); - leaves.push_back(SerializeHash(m_fedpeg_program, SER_GETHASH, 0)); - leaves.push_back(SerializeHash(m_fedpegscript, SER_GETHASH, 0)); - leaves.push_back(SerializeHash(m_extension_space, SER_GETHASH, 0)); + leaves.push_back(compact_root); + leaves.push_back(extra_root); return ComputeFastMerkleRoot(leaves); } +uint256 DynaFedParamEntry::CalculateExtraRoot() const +{ + std::vector extra_leaves; + extra_leaves.push_back(SerializeHash(m_fedpeg_program, SER_GETHASH, 0)); + extra_leaves.push_back(SerializeHash(m_fedpegscript, SER_GETHASH, 0)); + extra_leaves.push_back(SerializeHash(m_extension_space, SER_GETHASH, 0)); + return ComputeFastMerkleRoot(extra_leaves); +} + uint256 DynaFedParams::CalculateRoot() const { if (IsNull()) { diff --git a/src/primitives/block.h b/src/primitives/block.h index 6c3b1a99c3f..953811fa9f7 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -64,12 +64,13 @@ class DynaFedParamEntry CScript m_fedpeg_program; // The "scriptPubKey" of the fedpegscript CScript m_fedpegscript; // The witnessScript for witness v0 or undefined otherwise. // No consensus meaning to the particular bytes, currently we interpret as PAK keys, details in pak.h - std::vector> m_extension_space; + std::vector> m_extension_space;\ + uint256 m_elided_root; // non-zero only when m_serialize_type == 1 // Each constructor sets its own serialization type implicitly based on which // arguments are given DynaFedParamEntry() { m_signblock_witness_limit = 0; m_serialize_type = 0; }; - DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in) { m_serialize_type = 1; }; + DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const uint256 elided_root_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_elided_root(elided_root_in) { m_serialize_type = 1; }; DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const CScript& fedpeg_program_in, const CScript& fedpegscript_in, const std::vector> extension_space_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_fedpeg_program(fedpeg_program_in), m_fedpegscript(fedpegscript_in), m_extension_space(extension_space_in) { m_serialize_type = 2; }; ADD_SERIALIZE_METHODS; @@ -84,6 +85,7 @@ class DynaFedParamEntry case 1: READWRITE(m_signblockscript); READWRITE(m_signblock_witness_limit); + READWRITE(m_elided_root); break; case 2: READWRITE(m_signblockscript); @@ -98,6 +100,8 @@ class DynaFedParamEntry } uint256 CalculateRoot() const; + // Calculates root for the non-blocksigning merkle fields + uint256 CalculateExtraRoot() const; bool IsNull() const { diff --git a/src/test/dynafed_tests.cpp b/src/test/dynafed_tests.cpp index 8edfd31d20e..edbdbfbc5f2 100644 --- a/src/test/dynafed_tests.cpp +++ b/src/test/dynafed_tests.cpp @@ -21,7 +21,7 @@ BOOST_AUTO_TEST_CASE(dynafed_params_root) CScript fp_script(opcodetype(4)); std::vector> ext{ {5, 6}, {7} }; - DynaFedParamEntry compact_entry = DynaFedParamEntry(signblockscript, signblock_wl); + DynaFedParamEntry compact_entry = DynaFedParamEntry(signblockscript, signblock_wl, uint256()); BOOST_CHECK_EQUAL( compact_entry.CalculateRoot().GetHex(), "dff5f3793abc06a6d75e80fe3cfd47406f732fa4ec9305960ae2a229222a1ad5"