From 4c3d4f278a648b22d4790dbf3e40039877b94306 Mon Sep 17 00:00:00 2001 From: Hector Chu Date: Sat, 17 Feb 2024 15:00:30 +0000 Subject: [PATCH] enable peerblockfilters by default & add NODE_MWEB_LIGHT_CLIENT service flag & blockheight to netutxos + more --- src/init.cpp | 12 ++++++++++-- src/libmw/include/mw/models/tx/UTXO.h | 3 ++- src/libmw/src/mmr/Segment.cpp | 19 ++++++++++--------- src/libmw/test/tests/mmr/Test_Segment.cpp | 23 +++++++++++------------ src/net_processing.cpp | 4 ++-- src/net_processing.h | 2 +- src/protocol.cpp | 15 ++++++++------- src/protocol.h | 4 +++- src/validation.h | 2 +- 9 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index c60d8afb80..117e7411c3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1002,7 +1002,11 @@ bool AppInitParameterInteraction(const ArgsManager& args) } // parse and validate enabled filter types + bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false); std::string blockfilterindex_value = args.GetArg("-blockfilterindex", DEFAULT_BLOCKFILTERINDEX); + if (fReindexChainState && !args.IsArgSet("-blockfilterindex")) { + blockfilterindex_value = "0"; + } if (blockfilterindex_value == "" || blockfilterindex_value == "1") { g_enabled_filter_types = AllBlockFilterTypes(); } else if (blockfilterindex_value != "0") { @@ -1017,7 +1021,11 @@ bool AppInitParameterInteraction(const ArgsManager& args) } // Signal NODE_COMPACT_FILTERS if peerblockfilters and basic filters index are both enabled. - if (args.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) { + bool peerblockfilters = args.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS); + if (fReindexChainState && !args.IsArgSet("-peerblockfilters")) { + peerblockfilters = false; + } + if (peerblockfilters) { if (g_enabled_filter_types.count(BlockFilterType::BASIC) != 1) { return InitError(_("Cannot set -peerblockfilters without -blockfilterindex.")); } @@ -1852,7 +1860,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS); // NODE_MWEB requires NODE_WITNESS, so we shouldn't signal for NODE_MWEB without NODE_WITNESS - nLocalServices = ServiceFlags(nLocalServices | NODE_MWEB); + nLocalServices = ServiceFlags(nLocalServices | NODE_MWEB | NODE_MWEB_LIGHT_CLIENT); } // ********************************************************* Step 11: import blocks diff --git a/src/libmw/include/mw/models/tx/UTXO.h b/src/libmw/include/mw/models/tx/UTXO.h index d64d8bad14..3aa6728520 100644 --- a/src/libmw/include/mw/models/tx/UTXO.h +++ b/src/libmw/include/mw/models/tx/UTXO.h @@ -56,7 +56,8 @@ public: template inline void Serialize(Stream& s) const { - s << VARINT(m_utxo->GetLeafIndex().Get()); + s << m_utxo->GetBlockHeight(); + s << COMPACTSIZE(m_utxo->GetLeafIndex().Get()); if (m_format == FULL_UTXO) { s << m_utxo->GetOutput(); diff --git a/src/libmw/src/mmr/Segment.cpp b/src/libmw/src/mmr/Segment.cpp index 7087f2869e..998a0fba16 100644 --- a/src/libmw/src/mmr/Segment.cpp +++ b/src/libmw/src/mmr/Segment.cpp @@ -19,7 +19,7 @@ Segment SegmentFactory::Assemble(const IMMR& mmr, const ILeafSet& leafset, const while (segment.leaves.size() < num_leaves && leaf_idx < leafset.GetNextLeafIdx()) { if (leafset.Contains(leaf_idx)) { last_leaf_idx = leaf_idx; - segment.leaves.push_back(mmr.GetHash(leaf_idx.GetNodeIndex())); + segment.leaves.push_back(mmr.GetLeaf(leaf_idx).vec()); } ++leaf_idx; @@ -36,13 +36,14 @@ Segment SegmentFactory::Assemble(const IMMR& mmr, const ILeafSet& leafset, const } // Determine the lowest peak that can be calculated using the hashes we've already provided - auto peak = std::find_if( + auto peak_iter = std::find_if( peak_indices.begin(), peak_indices.end(), - [&last_leaf_idx](const Index& peak_idx) { return peak_idx > last_leaf_idx.GetNodeIndex(); }); + [&last_leaf_idx](const Index& peak_idx) { return peak_idx >= last_leaf_idx.GetNodeIndex(); }); + assert(peak_iter != peak_indices.end()); // Bag the next lower peak (if there is one), so the root can still be calculated - if (peak != peak_indices.end() && peak++ != peak_indices.end()) { - segment.lower_peak = MMRUtil::CalcBaggedPeak(mmr, *peak); + if (++peak_iter != peak_indices.end()) { + segment.lower_peak = MMRUtil::CalcBaggedPeak(mmr, *peak_iter); } return segment; @@ -69,9 +70,9 @@ std::set SegmentFactory::CalcHashIndices( } // 2. Add indices needed to reach left edge of mountain - auto on_mountain_left_edge = [prev_peak](const Index& idx) -> bool { - const uint64_t adjustment = !!prev_peak ? prev_peak->GetPosition() + 1 : 0; - return ((idx.GetPosition() + 2) - adjustment) == (uint64_t(2) << idx.GetHeight()); + uint64_t adjustment = prev_peak ? prev_peak->GetPosition() + 1 : 0; + auto on_mountain_left_edge = [adjustment](const Index& idx) -> bool { + return (idx.GetPosition() + 2 - adjustment) == (uint64_t(2) << idx.GetHeight()); }; Index idx = first_leaf_idx.GetNodeIndex(); @@ -96,7 +97,7 @@ std::set SegmentFactory::CalcHashIndices( // 4. Add indices needed to reach right edge of mountain containing the last leaf auto peak_iter = std::find_if( peak_indices.begin(), peak_indices.end(), - [&last_leaf_idx](const Index& peak_idx) { return peak_idx > last_leaf_idx.GetNodeIndex(); }); + [&last_leaf_idx](const Index& peak_idx) { return peak_idx >= last_leaf_idx.GetNodeIndex(); }); assert(peak_iter != peak_indices.end()); Index peak = *peak_iter; diff --git a/src/libmw/test/tests/mmr/Test_Segment.cpp b/src/libmw/test/tests/mmr/Test_Segment.cpp index 465ae461c3..5eb91afc55 100644 --- a/src/libmw/test/tests/mmr/Test_Segment.cpp +++ b/src/libmw/test/tests/mmr/Test_Segment.cpp @@ -27,12 +27,7 @@ struct MMRWithLeafset { static mmr::Leaf DeterministicLeaf(const uint64_t i) { - std::vector serialized{ - uint8_t(i >> 24), - uint8_t(i >> 16), - uint8_t(i >> 8), - uint8_t(i)}; - return mmr::Leaf::Create(mmr::LeafIndex::At(i), serialized); + return mmr::Leaf::Create(mmr::LeafIndex::At(i), Hasher().Append(i).hash().vec()); } static MMRWithLeafset BuildDetermininisticMMR(const uint64_t num_leaves) @@ -62,10 +57,10 @@ BOOST_AUTO_TEST_CASE(AssembleSegment) ); std::vector expected_leaves{ - DeterministicLeaf(0).GetHash(), - DeterministicLeaf(1).GetHash(), - DeterministicLeaf(2).GetHash(), - DeterministicLeaf(3).GetHash() + Hasher().Append(0).hash(), + Hasher().Append(1).hash(), + Hasher().Append(2).hash(), + Hasher().Append(3).hash(), }; BOOST_REQUIRE_EQUAL_COLLECTIONS(segment.leaves.begin(), segment.leaves.end(), expected_leaves.begin(), expected_leaves.end()); @@ -78,8 +73,12 @@ BOOST_AUTO_TEST_CASE(AssembleSegment) BOOST_REQUIRE_EQUAL(expected_lower_peak, segment.lower_peak); // Verify PMMR root can be fully recomputed - mw::Hash n2 = MMRUtil::CalcParentHash(mmr::Index::At(2), segment.leaves[0], segment.leaves[1]); - mw::Hash n5 = MMRUtil::CalcParentHash(mmr::Index::At(5), segment.leaves[2], segment.leaves[3]); + mw::Hash n0 = mmr::Leaf::CalcHash(mmr::LeafIndex::At(0), segment.leaves[0].vec()); + mw::Hash n1 = mmr::Leaf::CalcHash(mmr::LeafIndex::At(1), segment.leaves[1].vec()); + mw::Hash n2 = MMRUtil::CalcParentHash(mmr::Index::At(2), n0, n1); + mw::Hash n3 = mmr::Leaf::CalcHash(mmr::LeafIndex::At(2), segment.leaves[2].vec()); + mw::Hash n4 = mmr::Leaf::CalcHash(mmr::LeafIndex::At(3), segment.leaves[3].vec()); + mw::Hash n5 = MMRUtil::CalcParentHash(mmr::Index::At(5), n3, n4); mw::Hash n6 = MMRUtil::CalcParentHash(mmr::Index::At(6), n2, n5); mw::Hash n14 = MMRUtil::CalcParentHash(mmr::Index::At(14), n6, segment.hashes[0]); mw::Hash root = MMRUtil::CalcParentHash(Index::At(26), n14, *segment.lower_peak); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 41b5bc4fb3..546ad726f3 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1792,7 +1792,7 @@ struct GetMWEBUTXOsMsg SERIALIZE_METHODS(GetMWEBUTXOsMsg, obj) { - READWRITE(obj.block_hash, VARINT(obj.start_index), obj.num_requested, obj.output_format); + READWRITE(obj.block_hash, COMPACTSIZE(obj.start_index), obj.num_requested, obj.output_format); } uint256 block_hash; @@ -1807,7 +1807,7 @@ struct MWEBUTXOsMsg SERIALIZE_METHODS(MWEBUTXOsMsg, obj) { - READWRITE(obj.block_hash, VARINT(obj.start_index), obj.output_format, obj.utxos, obj.proof_hashes); + READWRITE(obj.block_hash, COMPACTSIZE(obj.start_index), obj.output_format, obj.utxos, obj.proof_hashes); } uint256 block_hash; diff --git a/src/net_processing.h b/src/net_processing.h index 4a9c76a3fa..ca6511221a 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -28,7 +28,7 @@ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default number of orphan+recently-replaced txn to keep around for block reconstruction */ static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100; static const bool DEFAULT_PEERBLOOMFILTERS = false; -static const bool DEFAULT_PEERBLOCKFILTERS = false; +static const bool DEFAULT_PEERBLOCKFILTERS = true; /** Threshold for marking a node to be discouraged, e.g. disconnected and added to the discouragement filter. */ static const int DISCOURAGEMENT_THRESHOLD{100}; diff --git a/src/protocol.cpp b/src/protocol.cpp index 4e8263acdf..c2fdd4fdb4 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -215,13 +215,14 @@ static std::string serviceFlagToStr(size_t bit) const uint64_t service_flag = 1ULL << bit; switch ((ServiceFlags)service_flag) { case NODE_NONE: abort(); // impossible - case NODE_NETWORK: return "NETWORK"; - case NODE_GETUTXO: return "GETUTXO"; - case NODE_BLOOM: return "BLOOM"; - case NODE_WITNESS: return "WITNESS"; - case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS"; - case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED"; - case NODE_MWEB: return "MWEB"; + case NODE_NETWORK: return "NETWORK"; + case NODE_GETUTXO: return "GETUTXO"; + case NODE_BLOOM: return "BLOOM"; + case NODE_WITNESS: return "WITNESS"; + case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS"; + case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED"; + case NODE_MWEB: return "MWEB"; + case NODE_MWEB_LIGHT_CLIENT: return "MWEB_LIGHT_CLIENT"; // Not using default, so we get warned when a case is missing } diff --git a/src/protocol.h b/src/protocol.h index 5323338b52..a401f6eaf1 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -319,7 +319,9 @@ enum ServiceFlags : uint64_t { NODE_NETWORK_LIMITED = (1 << 10), // NODE_MWEB indicates that a node can be asked for blocks and transactions including // MWEB data. - NODE_MWEB = (1 << 24) + NODE_MWEB = (1 << 24), + // NODE_MWEB_LIGHT_CLIENT indicates that a node can be asked for MWEB light client data. + NODE_MWEB_LIGHT_CLIENT = (1 << 25) // Bits 25-31 are reserved for temporary experiments. Just pick a bit that // isn't getting used, or one not being used much, and notify the diff --git a/src/validation.h b/src/validation.h index 56c0d09e05..ac83f4b922 100644 --- a/src/validation.h +++ b/src/validation.h @@ -73,7 +73,7 @@ static const int DEFAULT_SCRIPTCHECK_THREADS = 0; static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60; static const bool DEFAULT_CHECKPOINTS_ENABLED = true; static const bool DEFAULT_TXINDEX = false; -static const char* const DEFAULT_BLOCKFILTERINDEX = "0"; +static const char* const DEFAULT_BLOCKFILTERINDEX = "1"; /** Default for -persistmempool */ static const bool DEFAULT_PERSIST_MEMPOOL = true; /** Default for -mempoolreplacement */