Skip to content

Conversation

kwvg
Copy link
Collaborator

@kwvg kwvg commented May 12, 2025

Motivation

To enable the switch to extended addresses, the current CService entry was first encapsulated in MnNetInfo and exposed through a public interface (see dash#6627) that restricted access to the underlying type, then the underlying type of the address was abstracted away through NetInfoEntry (see dash#6629), allowing us to store different types of addresses.

This pull request finally abstracts away MnNetInfo as an implementation detail and sets the stage for alternate implementations (i.e. extended addresses) to be selected in based on the version number. This should allow the switchover logic to be insulated from most of the codebase.

Additional Information

  • Depends on feat: define BIP 9 fork DEPLOYMENT_V23 for new version featureset #6669

  • Depends on feat: introduce type-flexible NetInfoEntry to allow non-CService entries, use in MnNetInfo #6629

  • Dependency for feat(rpc): allow reporting multiple addresses with new addresses field, deprecate service field, allow submitting multiple addresses #6674

  • Since dash#6579 got rid of legacy CDeterministicMNState serialization, there is no more logic that can attempt legacy deserialization, making the version check (source) vestigial. We can safely remove the leftover version fields and simplify the serialization logic.

    It is done as part of this PR because the serialization version is manipulated with OverrideStream to ensure proper ADDRv2 serialization (source) and as the extended implementation uses it for that reason, the otherwise-vestigial version-based check could now trigger a crash, so it has been removed.

  • As implementing operators in virtual classes (needed to allow switching implementations) is not possible (unlike regular pointers where a lhs && rhs ? *lhs == *rhs : lhs == rhs would be enough), a separate equality function NetInfoInterface::IsEqual() has been implemented that attempts to downcast lhs and rhs to the same type and returns the implementation-specific equality result.

    A solution that uses typeid to help define comparison operators has been implemented but std::shared_ptr does not deep compare, to aid with that, the deep comparison helpers util::shared_ptr_{,not_}equal have been implemented and can be used with any pair of shared_ptrs so long as their underlying types define the necessary operators.

    Care needs to be taken to ensure that all equality comparisons involving netInfo use those functions.

  • A new ProTx version has been introduced for the upcoming extended addresses implementation. It is only applicable to CProRegTx and CProUpServTx as no other special transaction stores netInfo and is therefore, unaffected by the switchover. No code has been implemented in this PR that uses this new version, that is reserved for the PR that introduces the extended implementation.

    • Additionally, as the transaction version is used to determine the underlying implementation, make sure that nVersion is set before calling MakeNetInfo() (also remember to call MakeNetInfo() as the default constructor will set netInfo to nullptr and a missing call will result in a nullptr dereference when netInfo is eventually accessed). This is only relevant if a transaction is being constructed in-place as deserialization logic handles this for you.

    • An earlier approach involved setting the new version only for CProRegTx and CProUpServTx. In light of multiple ProTx types being able to modify the version of the masternode state (pdmnState), this may prove to be more dangerous than beneficial. In light of that, the version bump now affects all ProTx types but is still only effective in CProRegTx and CProUpServTx. See comment.

Breaking Changes

None expected.

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation (note: N/A)
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@kwvg kwvg added this to the 23 milestone May 12, 2025
@kwvg kwvg changed the title evo: model interface after MnNetInfo and support switching impls, add new ProTx version, introduce DEPLOYMENT_EXTADDR params refactor: model interface after MnNetInfo and support switching impls, add new ProTx version, introduce DEPLOYMENT_EXTADDR params May 12, 2025
PastaPastaPasta added a commit that referenced this pull request May 15, 2025
… featureset

98749a7 feat: define BIP 9 fork `DEPLOYMENT_V23` for new version featureset (Kittywhiskers Van Gogh)

Pull request description:

  ## Motivation

  Should handle the deployment needs for [dash#6662](#6662) and [dash#6665](#6665) as they're expected to be shipped in the same major version.

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 98749a7
  PastaPastaPasta:
    utACK 98749a7

Tree-SHA512: b61302a0bcf236f06661a4a53f1d7b3ab0f65659c1c9ab2fcb782457a25eb1e6bdc942647dca6a4e22686e0c7cc83405e099e1fa790cf007d2bee3eedc456d5f
@kwvg kwvg force-pushed the netinfo_p3 branch 2 times, most recently from af9779d to 227b428 Compare May 16, 2025 12:51
@kwvg kwvg changed the title refactor: model interface after MnNetInfo and support switching impls, add new ProTx version, introduce DEPLOYMENT_EXTADDR params refactor: model interface after MnNetInfo and support switching impls, add new ProTx version May 18, 2025
@kwvg kwvg force-pushed the netinfo_p3 branch 2 times, most recently from f559edc to 5cbddbb Compare May 22, 2025 18:43
PastaPastaPasta added a commit that referenced this pull request May 28, 2025
…n-`CService` entries, use in `MnNetInfo`

3a72f2f evo: fast-fail `MnNetInfo::AddEntry()` if invalid characters found (Kittywhiskers Van Gogh)
e0a1c64 evo: prohibit overwriting entry in `MnNetInfo` (Kittywhiskers Van Gogh)
c69184b evo: utilize `NetInfoEntry::IsTriviallyValid()` in ProTx trivial checks (Kittywhiskers Van Gogh)
06cf4ee evo: return `MnNetInfo::GetEntries()` with `NetInfoEntry` (Kittywhiskers Van Gogh)
6286c9b evo: change internal type of `MnNetInfo` to `NetInfoEntry` (Kittywhiskers Van Gogh)
b0a634e evo: ensure the ADDRV2 serialization is always used in `NetInfoEntry` (Kittywhiskers Van Gogh)
6d97bda evo: introduce type-flexible `NetInfoEntry` to allow non-`CService` data (Kittywhiskers Van Gogh)
069583d evo: expand error codes for `netInfo` validation (Kittywhiskers Van Gogh)

Pull request description:

  ## Motivation

  The upcoming extended addresses specification envisions the ability to store address information _beyond_ the set of addresses that can be represented by BIP-155 (i.e. `CService`). To enable this, we need to devise a backwards-compatible way to allow storing and manipulating address information with differing serialization formats and validation rules.

  Backwards compatibility is a priority as the unique properties set (used to detect attempts at storing already-registered values) only stores a hashed representation of the value and therefore, in-place migration is not a viable option.

  With this in mind, this pull request introduces `NetInfoEntry`, which is wrapper around an `std::variant` that provides dispatching for common endpoints with `std::visit`, serialization and trivial validity enforcement between potential implementations and the ability to access the underlying type if necessary (for code that relies on backwards-compatibility, like hashing). It doesn't implement any network rules itself but requires that it must hold a valid instance of any underlying type that it supports.

  While `MnNetInfo` (the current implementation) has and always will store a `CService`, to ensure a conformity between it and `ExtNetInfo` (the upcoming extended implementation), its public functions will return a `NetInfoEntry` when applicable so that both can be abstracted by a common interface to aid with the transition.

  ## Additional Information

  * Depends on #6627

  * Depends on #6664

  * Dependency for #6665

  * ~~2e9bde0519b242d1d7aaf49344a357b90121689e in [dash#6627](#6627) incorrectly migrated validation conditions such that attempting to set a valid `addr:port` combination on mainnet would result in a `BadPort` error because the non-mainnet rules were applied _regardless_ of network.~~

    ~~This evaded testing as our unit and functional tests do not run on mainnet. To prevent this from occurring again, the whole `evo_netinfo_tests` suite now uses `BasicTestingSetup` (which advertises itself as mainnet), which comes with the added benefit of greater coverage as mainnet rules are _stricter_.~~

    ~~The port validation check for non-mainnet networks are tested _indirectly_ through tests like `evo_simplifiedmns_merkleroots`'s usage of `NetInfoInterface::*` methods ([source](https://github.com/dashpay/dash/blob/0f94e3e3e793925caa24a73ad54d843770b1a8c5/src/test/evo_simplifiedmns_tests.cpp#L25)).~~ Superseded by [dash#6664](#6664).

  * Per replies to review comments ([comment](#6627 (comment)), [comment](#6627 (comment))) from [dash#6627](#6627), reported error codes from `netInfo` interactions have been expanded to be more specific.

  * `CService` by default is serialized using ADDRV1 and utilizing ADDRV2 serialization is either explicitly opted into ([source](https://github.com/dashpay/dash/blob/0f94e3e3e793925caa24a73ad54d843770b1a8c5/src/addrman.cpp#L173-L175)) or determined on-the-fly ([source](https://github.com/dashpay/dash/blob/0f94e3e3e793925caa24a73ad54d843770b1a8c5/src/net_processing.cpp#L3960-L3965)). As we envision the ability to store Tor and I2P addresses, using ADDRV2 is mandatory.

    Though this affects (de)serialization of `NetInfoEntry`, it does not affect `MnNetInfo` as `NetInfoEntry` is only used for the sake of a consistent interface _but_ internally still (de)serializes to an ADDRV1 `CService`.

  * The introduction of fast-failing based on permitted characters is meant to mirror the upcoming extended addresses implementation where permitted characters are used as a quick way to classify the intended underlying type before running more expensive checks.

    As a side effect, this may cause inconsistency where attempting to use `MnNetInfo::AddEntry()` with, for example, an IPv6 address will result in `BadInput` as the delimiter used in IPv6 addresses are not part of the permitted characters filter _but_ validating a `MnNetInfo` with an IPv6 address _already stored_ will return a `BadType`.

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 3a72f2f
  UdjinM6:
    utACK 3a72f2f

Tree-SHA512: abd84db309b6011480431b12cccd649878bab06aa44ca2c81563e9598d4424fd61888b12e2e439b9c2180bc5e0edee3431b1008ae7af4b676b164af1455fda3c
Copy link

This pull request has conflicts, please rebase.

@kwvg kwvg marked this pull request as ready for review May 28, 2025 21:32
Copy link

coderabbitai bot commented May 28, 2025

Walkthrough

This change refactors the handling of masternode network information throughout the codebase by replacing direct value-type usage of the MnNetInfo class with a new polymorphic interface, NetInfoInterface, managed via std::shared_ptr. All relevant classes and methods, including provider transaction payloads, deterministic masternode state, and simplified masternode list entries, now use shared pointers to NetInfoInterface for their network info. Serialization and deserialization logic is updated to accommodate this pointer-based, interface-driven design, employing a new NetInfoSerWrapper for version-aware (de)serialization. The codebase is updated to use pointer dereferencing when accessing network info members. Validation logic for provider transactions is modernized to determine allowable versions based on deployment state and to enforce consistency between transaction version and network info capabilities. Helper utilities for pointer equality and inequality are introduced, and all tests, RPC, and build system logic are updated to use the new interface and versioning mechanisms. Additionally, minor fixes to member access syntax and simplifications in serialization code are applied, and a new unit test verifies network info interface equality behavior.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64f3219 and 3e65628.

📒 Files selected for processing (30)
  • src/Makefile.am (1 hunks)
  • src/coinjoin/client.cpp (6 hunks)
  • src/evo/core_write.cpp (2 hunks)
  • src/evo/deterministicmns.cpp (18 hunks)
  • src/evo/deterministicmns.h (4 hunks)
  • src/evo/dmnstate.cpp (2 hunks)
  • src/evo/dmnstate.h (8 hunks)
  • src/evo/netinfo.cpp (2 hunks)
  • src/evo/netinfo.h (4 hunks)
  • src/evo/providertx.cpp (5 hunks)
  • src/evo/providertx.h (11 hunks)
  • src/evo/simplifiedmns.cpp (2 hunks)
  • src/evo/simplifiedmns.h (4 hunks)
  • src/llmq/utils.cpp (2 hunks)
  • src/masternode/node.cpp (2 hunks)
  • src/masternode/utils.cpp (1 hunks)
  • src/net.cpp (5 hunks)
  • src/qt/masternodelist.cpp (1 hunks)
  • src/rpc/evo.cpp (6 hunks)
  • src/rpc/masternode.cpp (2 hunks)
  • src/rpc/quorums.cpp (1 hunks)
  • src/test/block_reward_reallocation_tests.cpp (1 hunks)
  • src/test/evo_deterministicmns_tests.cpp (9 hunks)
  • src/test/evo_netinfo_tests.cpp (2 hunks)
  • src/test/evo_simplifiedmns_tests.cpp (1 hunks)
  • src/test/evo_trivialvalidation.cpp (4 hunks)
  • src/txmempool.cpp (8 hunks)
  • src/util/pointer.h (1 hunks)
  • test/lint/lint-circular-dependencies.py (1 hunks)
  • test/util/data/non-backported.txt (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/masternode/utils.cpp
  • src/evo/core_write.cpp
🚧 Files skipped from review as they are similar to previous changes (28)
  • test/util/data/non-backported.txt
  • test/lint/lint-circular-dependencies.py
  • src/Makefile.am
  • src/masternode/node.cpp
  • src/qt/masternodelist.cpp
  • src/evo/simplifiedmns.cpp
  • src/evo/netinfo.cpp
  • src/evo/dmnstate.cpp
  • src/llmq/utils.cpp
  • src/test/evo_simplifiedmns_tests.cpp
  • src/txmempool.cpp
  • src/test/evo_netinfo_tests.cpp
  • src/test/block_reward_reallocation_tests.cpp
  • src/rpc/masternode.cpp
  • src/net.cpp
  • src/rpc/quorums.cpp
  • src/coinjoin/client.cpp
  • src/evo/simplifiedmns.h
  • src/test/evo_deterministicmns_tests.cpp
  • src/util/pointer.h
  • src/rpc/evo.cpp
  • src/evo/dmnstate.h
  • src/evo/deterministicmns.cpp
  • src/test/evo_trivialvalidation.cpp
  • src/evo/providertx.cpp
  • src/evo/deterministicmns.h
  • src/evo/providertx.h
  • src/evo/netinfo.h
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: win64-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: linux64_multiprocess-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🔭 Outside diff range comments (4)
src/evo/simplifiedmns.h (1)

52-64: ⚠️ Potential issue

Fix formatting issues in equality operator.

The equality operator logic is correct in using NetInfoInterface::IsEqual for type-safe comparison of polymorphic pointers. However, the pipeline indicates formatting issues that need to be addressed.

Please fix the clang format issues in the equality operator as indicated by the pipeline failure. The logic is correct but the formatting needs to be consistent with project standards.

src/evo/providertx.h (2)

51-82: ⚠️ Potential issue

Fix READWRITE macro formatting to comply with clang-format.

The pipeline indicates formatting inconsistencies in the READWRITE macros.

Apply clang-format to fix the formatting:

 SERIALIZE_METHODS(CProRegTx, obj)
 {
-    READWRITE(
-            obj.nVersion
-    );
+    READWRITE(obj.nVersion);

161-164: ⚠️ Potential issue

Inconsistency between GetMaxVersion and IsTriviallyValid signatures.

The GetMaxVersion method doesn't accept is_extended_addr parameter, but IsTriviallyValid does. This seems inconsistent with the pattern established in CProRegTx and CProUpServTx.

Consider updating GetMaxVersion to match the pattern:

-[[nodiscard]] static constexpr uint16_t GetMaxVersion(const bool is_basic_scheme_active)
+[[nodiscard]] static constexpr uint16_t GetMaxVersion(const bool is_basic_scheme_active, [[maybe_unused]] const bool is_extended_addr)

Also applies to: 203-203

src/evo/providertx.cpp (1)

143-147: ⚠️ Potential issue

Unused parameter is_extended_addr.

The is_extended_addr parameter is not used because GetMaxVersion doesn't accept it. This should be addressed along with the header file fix.

♻️ Duplicate comments (3)
src/evo/providertx.h (2)

117-147: ⚠️ Potential issue

Apply consistent formatting to READWRITE macros.

Similar formatting issues as in CProRegTx.


211-214: ⚠️ Potential issue

Inconsistency between GetMaxVersion and IsTriviallyValid signatures.

Same issue as in CProUpRegTx.

Also applies to: 256-256

src/evo/providertx.cpp (1)

176-180: ⚠️ Potential issue

Unused parameter is_extended_addr.

Same issue as in CProUpRegTx::IsTriviallyValid.

🧹 Nitpick comments (6)
src/net.cpp (3)

3741-3746: Avoid duplicate calls to netInfo->GetPrimary()
You invoke netInfo->GetPrimary() twice in the conditional. Consider caching the result in a local variable for readability and slight performance gain:

- if (dmn && !connectedNodes.count(dmn->pdmnState->netInfo->GetPrimary()) &&
-     !IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo->GetPrimary())) {
+ const auto addr = dmn->pdmnState->netInfo->GetPrimary();
+ if (dmn && !connectedNodes.count(addr) &&
+     !IsMasternodeOrDisconnectRequested(addr)) {
     // ...
 }

3761-3765: Inconsistent use of function name for logging
Earlier logs in this scope use the _func_ variable for the function name; here you use __func__. For consistency, switch to _func_:

- LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- probing masternode %s, service=%s\n",
-          __func_, dmn->proTxHash.ToString(), addr2.ToStringAddrPort());
+ LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- probing masternode %s, service=%s\n",
+          _func_, dmn->proTxHash.ToString(), addr2.ToStringAddrPort());

3788-3792: Consistent function name macro in failure logging
Similarly, replace __func__ with _func_ in the connection failure log to match the surrounding usage:

- LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- connection failed for masternode  %s, service=%s\n",
-          __func__, connectToDmn->proTxHash.ToString(), addr2.ToStringAddrPort());
+ LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- connection failed for masternode  %s, service=%s\n",
+          _func_, connectToDmn->proTxHash.ToString(), addr2.ToStringAddrPort());
src/evo/netinfo.h (2)

75-76: Fix constructor formatting to match style guidelines.

The pipeline failure indicates formatting issues with the multiline constructor template.

Apply this formatting fix:

-    template <typename Stream>
-    NetInfoEntry(deserialize_type, Stream& s) { s >> *this; }
+    template <typename Stream>
+    NetInfoEntry(deserialize_type, Stream& s)
+    {
+        s >> *this;
+    }

159-160: Fix constructor formatting to match style guidelines.

Similar formatting issue as with NetInfoEntry.

Apply this formatting fix:

-    template <typename Stream>
-    MnNetInfo(deserialize_type, Stream& s) { s >> *this; }
+    template <typename Stream>
+    MnNetInfo(deserialize_type, Stream& s)
+    {
+        s >> *this;
+    }
src/evo/deterministicmns.h (1)

66-66: Fix constructor formatting to match style guidelines.

The pipeline failure indicates formatting issues with the constructor template.

Apply this formatting fix:

-    CDeterministicMN(deserialize_type, Stream& s) { s >> *this; }
+    CDeterministicMN(deserialize_type, Stream& s)
+    {
+        s >> *this;
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7325e06 and db8cfc0.

📒 Files selected for processing (28)
  • src/Makefile.am (1 hunks)
  • src/coinjoin/client.cpp (6 hunks)
  • src/evo/common.h (1 hunks)
  • src/evo/core_write.cpp (2 hunks)
  • src/evo/deterministicmns.cpp (15 hunks)
  • src/evo/deterministicmns.h (4 hunks)
  • src/evo/dmnstate.cpp (2 hunks)
  • src/evo/dmnstate.h (7 hunks)
  • src/evo/netinfo.cpp (1 hunks)
  • src/evo/netinfo.h (5 hunks)
  • src/evo/providertx.cpp (5 hunks)
  • src/evo/providertx.h (10 hunks)
  • src/evo/simplifiedmns.cpp (2 hunks)
  • src/evo/simplifiedmns.h (3 hunks)
  • src/llmq/utils.cpp (2 hunks)
  • src/masternode/node.cpp (2 hunks)
  • src/masternode/utils.cpp (1 hunks)
  • src/net.cpp (5 hunks)
  • src/qt/masternodelist.cpp (1 hunks)
  • src/rpc/evo.cpp (3 hunks)
  • src/rpc/masternode.cpp (2 hunks)
  • src/rpc/quorums.cpp (1 hunks)
  • src/test/block_reward_reallocation_tests.cpp (1 hunks)
  • src/test/evo_deterministicmns_tests.cpp (7 hunks)
  • src/test/evo_netinfo_tests.cpp (1 hunks)
  • src/test/evo_simplifiedmns_tests.cpp (1 hunks)
  • src/test/evo_trivialvalidation.cpp (4 hunks)
  • src/txmempool.cpp (8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/evo/netinfo.cpp (3)
src/evo/netinfo.h (9)
  • lhs (133-133)
  • rhs (80-80)
  • rhs (81-81)
  • rhs (82-82)
  • rhs (82-82)
  • rhs (164-164)
  • rhs (164-164)
  • rhs (165-165)
  • rhs (165-165)
src/evo/simplifiedmns.h (5)
  • rhs (52-64)
  • rhs (52-52)
  • rhs (66-69)
  • rhs (66-66)
  • rhs (114-114)
src/evo/simplifiedmns.cpp (2)
  • rhs (136-145)
  • rhs (136-136)
src/txmempool.cpp (2)
src/txmempool.h (14)
  • entry (187-190)
  • entry (187-187)
  • entry (519-519)
  • entry (535-535)
  • entry (536-536)
  • entry (608-608)
  • entry (609-609)
  • entry (611-611)
  • entry (616-616)
  • entry (705-705)
  • entry (883-883)
  • entry (899-899)
  • entry (1031-1035)
  • entry (1031-1031)
src/rpc/misc.cpp (1)
  • entry (1309-1309)
src/test/evo_simplifiedmns_tests.cpp (1)
src/evo/netinfo.h (2)
  • MakeNetInfo (203-207)
  • MakeNetInfo (203-203)
src/evo/simplifiedmns.h (2)
src/evo/netinfo.cpp (6)
  • IsEqual (150-171)
  • IsEqual (150-150)
  • rhs (35-46)
  • rhs (35-35)
  • rhs (48-63)
  • rhs (48-48)
src/evo/netinfo.h (13)
  • rhs (80-80)
  • rhs (81-81)
  • rhs (82-82)
  • rhs (82-82)
  • rhs (164-164)
  • rhs (164-164)
  • rhs (165-165)
  • rhs (165-165)
  • NetInfoSerWrapper (216-216)
  • NetInfoSerWrapper (217-217)
  • NetInfoSerWrapper (218-224)
  • NetInfoSerWrapper (226-226)
  • NetInfoSerWrapper (228-228)
src/test/block_reward_reallocation_tests.cpp (1)
src/evo/netinfo.h (2)
  • MakeNetInfo (203-207)
  • MakeNetInfo (203-203)
src/test/evo_netinfo_tests.cpp (1)
src/evo/netinfo.cpp (2)
  • IsEqual (150-171)
  • IsEqual (150-150)
src/test/evo_deterministicmns_tests.cpp (1)
src/evo/netinfo.h (2)
  • MakeNetInfo (203-207)
  • MakeNetInfo (203-203)
🪛 GitHub Actions: Clang Diff Format Check
src/evo/common.h

[error] 10-18: Clang format differences found: inconsistent spacing around enum values; lines need reformatting.

src/evo/simplifiedmns.h

[error] 51-90: Clang format differences found: inconsistent line breaks and argument formatting in operator== and serialization macros.

src/evo/dmnstate.h

[error] 77-110: Clang format differences found: inconsistent brace placement and argument formatting in serialization macros.

src/evo/providertx.h

[error] 58-130: Clang format differences found: inconsistent argument formatting in READWRITE macros and multiline expressions.

src/evo/deterministicmns.h

[error] 63-75: Clang format differences found: multiline constructor and template formatting inconsistent with style guidelines.

src/evo/netinfo.h

[error] 73-80: Clang format differences found: multiline constructor formatting inconsistent with style guidelines.

🔇 Additional comments (66)
src/Makefile.am (1)

189-189: LGTM! Proper integration of new header.

The addition of evo/common.h to the core headers is correctly placed and integrates the new ProTx version constants into the build system appropriately.

src/evo/core_write.cpp (2)

117-117: Consistent with the polymorphic netInfo refactor.

The pointer access pattern matches the architectural changes and is consistent with the refactor across the codebase.


70-70:

❓ Verification inconclusive

Verify null pointer safety for netInfo access.

The change from object access to pointer dereference is consistent with the polymorphic netInfo refactor. However, ensure that netInfo is always properly initialized before these methods are called to prevent null pointer dereferences.


🏁 Script executed:

#!/bin/bash
# Description: Search for netInfo initialization patterns and null checks in provider transaction code.

# Search for MakeNetInfo calls and netInfo assignments
rg -A 3 -B 3 "netInfo.*=" src/evo/

# Search for any null checks on netInfo
rg -A 2 -B 2 "netInfo.*null|!netInfo" src/evo/

# Search for netInfo pointer usage patterns
rg -A 2 "netInfo->" src/evo/

Length of output: 11950


Verify netInfo is always initialized before dereference in JSON RPC handlers.

The switch from value to pointer access in core_write.cpp aligns with the polymorphic netInfo refactor, but there are no explicit null‐pointer checks on netInfo in any of the RPC‐serialization paths (e.g. in core_write.cpp, providertx.cpp, simplifiedmns.cpp, dmnstate.cpp, etc.). The NetInfoSerWrapper used in the READWRITE blocks of CProRegTx and CProUpServTx should populate the netInfo pointer during deserialization, but please confirm:

  • That NetInfoSerWrapper indeed guarantees netInfo is non‐null for both CProRegTx and CProUpServTx before these JSON helpers are ever called.
  • If there exist any code paths where netInfo could remain nullptr (for example, manual instantiation without going through the deserializer), add an explicit null check or assert(netInfo) around
    ret.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
    in src/evo/core_write.cpp (and similarly in the other JSON routines).
src/rpc/masternode.cpp (2)

568-568: Consistent pointer access pattern for netInfo refactor.

The change from netInfo.GetEntries() to netInfo->GetEntries() is consistent with the polymorphic netInfo architecture. The refactor enables version-dependent network info implementations as described in the PR objectives.


615-615: Uniform application of netInfo pointer access.

The pointer dereference pattern is consistently applied across all netInfo method calls, maintaining uniformity with the architectural changes.

src/masternode/utils.cpp (1)

81-81: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator, reflecting the refactor where netInfo has been changed from a concrete object to a std::shared_ptr<NetInfoInterface>. The logic remains unchanged.

src/llmq/utils.cpp (2)

827-827: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator in the logging statement, reflecting the refactor where netInfo is now a pointer type.


876-876: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator in the logging statement, reflecting the refactor where netInfo is now a pointer type.

src/qt/masternodelist.cpp (2)

224-224: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator when getting the address key, reflecting the refactor where netInfo is now a pointer type.


227-227: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator when getting the address string for display, reflecting the refactor where netInfo is now a pointer type.

src/masternode/node.cpp (2)

149-149: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator when comparing the local service address with the masternode's primary address, reflecting the refactor where netInfo is now a pointer type.


204-204: LGTM: Correct syntax update for pointer-based netInfo.

This change correctly updates the member access from dot to arrow operator when comparing primary addresses between old and new masternode states, reflecting the refactor where netInfo is now a pointer type.

src/evo/simplifiedmns.cpp (2)

71-71: LGTM: Correct pointer dereference for netInfo.

The change from netInfo.ToString() to netInfo->ToString() correctly reflects the refactoring of netInfo from a concrete object to a std::shared_ptr<NetInfoInterface> pointer.


81-81: LGTM: Correct pointer dereference for netInfo.

The change from netInfo.GetPrimary().ToStringAddrPort() to netInfo->GetPrimary().ToStringAddrPort() correctly reflects the refactoring of netInfo from a concrete object to a std::shared_ptr<NetInfoInterface> pointer.

src/rpc/quorums.cpp (1)

206-206: LGTM: Correct pointer dereference for netInfo.

The change from dmn->pdmnState->netInfo.GetPrimary() to dmn->pdmnState->netInfo->GetPrimary() correctly reflects the refactoring of netInfo from a concrete object to a std::shared_ptr<NetInfoInterface> pointer.

src/test/evo_simplifiedmns_tests.cpp (3)

22-22: LGTM: Correct version initialization for new interface.

The version is properly set using CProRegTx::GetMaxVersion with is_extended_addr=false, which is appropriate for this test case that uses the legacy address scheme.


23-23: LGTM: Correct usage of MakeNetInfo factory function.

The MakeNetInfo(smle) call correctly creates a std::shared_ptr<NetInfoInterface> using the entry's version. Since nVersion was set on the previous line, this should satisfy the factory function's assertions.


27-27: LGTM: Correct pointer dereference for netInfo.

The change from netInfo.AddEntry() to netInfo->AddEntry() correctly reflects the refactoring of netInfo from a concrete object to a std::shared_ptr<NetInfoInterface> pointer.

src/net.cpp (1)

3676-3682: Consistent pointer-based access to NetInfo now in place
Accessing netInfo via pointer is correct as part of the interface refactor; this aligns with the polymorphic design for NetInfoInterface.

src/evo/netinfo.cpp (1)

150-171: Well-implemented polymorphic equality comparison.

The IsEqual static method correctly handles all necessary cases for comparing NetInfoInterface shared pointers:

  • Pointer identity and null checks for optimization
  • Type-safe dynamic casting to concrete implementations
  • Deep comparison using the concrete type's operator==
  • Proper fallback for differing derived types

This implementation aligns perfectly with the interface-based refactoring described in the PR objectives.

src/test/block_reward_reallocation_tests.cpp (1)

118-121: Correctly updated to use new netInfo interface pattern.

The changes properly implement the refactored netInfo handling:

  • Version initialization includes the new is_extended_addr parameter
  • MakeNetInfo(proTx) correctly initializes the polymorphic netInfo pointer
  • Access pattern updated from direct member to pointer dereference

The sequence ensures nVersion is set before calling MakeNetInfo(), preventing potential null pointer issues as mentioned in the PR objectives.

src/evo/dmnstate.cpp (3)

35-35: Correctly updated netInfo access pattern.

The change from netInfo.ToString() to netInfo->ToString() properly reflects the refactoring from concrete object to shared pointer.


42-42: Correctly updated netInfo access pattern.

The change from netInfo.GetPrimary() to netInfo->GetPrimary() properly reflects the refactoring from concrete object to shared pointer.


76-76: Correctly updated netInfo access pattern.

The change from netInfo.GetPrimary() to netInfo->GetPrimary() properly reflects the refactoring from concrete object to shared pointer.

src/coinjoin/client.cpp (6)

189-189: Correctly updated netInfo access pattern.

The change to use pointer dereference (netInfo->GetPrimary()) properly reflects the refactoring from concrete object to shared pointer.


1109-1109: Correctly updated netInfo access pattern.

The change to use pointer dereference (netInfo->GetPrimary()) properly reflects the refactoring from concrete object to shared pointer.


1181-1181: Correctly updated netInfo access pattern.

The change to use pointer dereference (netInfo->GetPrimary()) properly reflects the refactoring from concrete object to shared pointer.


1221-1221: Correctly updated netInfo access pattern.

The change to use pointer dereference (netInfo->GetPrimary()) properly reflects the refactoring from concrete object to shared pointer.


1823-1823: Correctly updated netInfo access pattern.

The change to use pointer dereference (netInfo->GetPrimary()) properly reflects the refactoring from concrete object to shared pointer.


1879-1879: Correctly updated netInfo access pattern.

The change to use pointer dereference (netInfo->GetPrimary()) properly reflects the refactoring from concrete object to shared pointer.

src/test/evo_netinfo_tests.cpp (1)

217-236: Excellent test coverage for the new interface equality logic.

This test case thoroughly validates the NetInfoInterface::IsEqual static method across all relevant scenarios:

  • Uninitialized pointers (both null)
  • Unequal initialization status (one null, one initialized)
  • Equal initialization with same content (both empty)
  • Equal initialization with different content

The test correctly uses MnNetInfo as the concrete implementation and verifies that the equality detection properly handles both pointer comparison and deep content comparison.

src/txmempool.cpp (8)

664-664: LGTM: Correct update for polymorphic netInfo access.

The change from proTx.netInfo.GetEntries() to proTx.netInfo->GetEntries() is consistent with the refactor to use std::shared_ptr<NetInfoInterface> instead of a concrete MnNetInfo object.


677-677: LGTM: Consistent pointer dereference for netInfo.

Properly updated to use pointer dereference syntax for the polymorphic netInfo interface.


768-768: LGTM: Correct pointer access in removal logic.

The change maintains the same logic while properly accessing the polymorphic netInfo through pointer dereference.


778-778: LGTM: Consistent with polymorphic netInfo design.

Correct update to use pointer dereference for accessing netInfo entries.


1007-1007: LGTM: Proper polymorphic access in conflict detection.

The change correctly updates the access pattern while maintaining the same conflict detection logic.


1029-1029: LGTM: Consistent pointer dereference pattern.

Properly updated to use the new polymorphic netInfo interface.


1367-1367: LGTM: Correct update in provider transaction conflict check.

The change maintains the same conflict detection logic while using the new pointer-based netInfo access.


1392-1392: LGTM: Final consistent update for polymorphic netInfo.

All netInfo access patterns have been properly updated to use pointer dereference for the polymorphic interface.

src/test/evo_trivialvalidation.cpp (4)

20-22: Good addition of extended address parameter for future support.

The addition of the is_extended_addr parameter to TestTxHelper properly prepares the test infrastructure for extended address validation while maintaining backward compatibility.


32-32: Correct parameter forwarding to validation method.

The is_extended_addr parameter is properly passed to the IsTriviallyValid method, enabling version-specific validation logic.


55-55: Appropriate placeholder for future extended address testing.

The TODO comment and hardcoded false value is a reasonable approach for the current phase, allowing the infrastructure to be in place while extended address test vectors are developed.


72-91: Consistent parameter updates across all provider transaction types.

All test cases for provider transactions (CProRegTx, CProUpServTx, CProUpRegTx, CProUpRevTx) have been properly updated to pass the is_extended_addr parameter.

src/evo/simplifiedmns.h (1)

38-38: Correct transition to polymorphic netInfo interface.

The change from MnNetInfo netInfo to std::shared_ptr<NetInfoInterface> netInfo{nullptr} properly implements the polymorphic design while ensuring safe initialization.

src/rpc/evo.cpp (2)

656-662: LGTM! Correct implementation of the new netInfo interface.

The changes properly implement the new polymorphic NetInfoInterface:

  • Correctly checks for V23 deployment to determine extended address support
  • Properly initializes netInfo using the factory function
  • Consistently uses pointer dereference syntax for member access

Also applies to: 688-688


980-980: LGTM! Consistent implementation with the register wrapper.

The changes correctly apply the same pattern as in protx_register_common_wrapper.

Also applies to: 982-982

src/test/evo_deterministicmns_tests.cpp (1)

107-110: LGTM! Test updates correctly implement the new netInfo interface.

All test functions have been consistently updated to:

  • Use MakeNetInfo factory for initialization
  • Pass is_extended_addr=false to maintain existing test behavior
  • Use pointer dereference syntax (->) for member access

The test coverage appropriately validates the refactored interface.

Also applies to: 130-133, 524-524, 582-582, 641-643, 717-719, 786-788

src/evo/dmnstate.h (2)

218-229: LGTM! Correct handling of polymorphic netInfo comparison.

The use of NetInfoInterface::IsEqual for comparing shared pointers to polymorphic types is the right approach, as virtual operators are not feasible.


255-260: Clarify the TODO comment and verify the is_extended parameter.

The TODO comment on line 258 states "Implement this", but there is already an implementation using NetInfoSerWrapper. This is confusing and needs clarification.

Additionally, the is_extended parameter is hardcoded to false. Please verify if this is intentional for backward compatibility or if it should be determined dynamically based on the version.

src/evo/providertx.h (1)

29-33: LGTM! Version logic is properly implemented.

The GetMaxVersion method correctly returns ProTxVersion::ExtAddr when extended addresses are enabled, with proper fallback to BasicBLS or LegacyBLS versions.

src/evo/providertx.cpp (2)

15-63: Proper implementation of extended address validation.

The function correctly validates the ProTx version against the extended address flag and properly accesses netInfo via pointer dereference.


108-126: Consistent implementation with pointer-based netInfo access.

The function properly handles the extended address parameter and correctly uses pointer dereference for netInfo.

src/evo/deterministicmns.cpp (5)

460-473: Proper handling of netInfo entries in AddMN.

The function correctly iterates through netInfo entries via pointer dereference and maintains proper error handling for invalid addresses.


510-544: Excellent implementation of netInfo update logic.

The use of NetInfoInterface::IsEqual for comparison and the atomic update pattern with rollback capability ensures data consistency. The lambda properly handles the transition from old to new netInfo entries.


888-890: Good: Maintaining version consistency.

Setting nVersion from the ProTx version ensures the state properly reflects the transaction version, which is important for the polymorphic netInfo handling.


929-931: Correct netInfo reset after operator key change.

The call to MakeNetInfo(*newState) properly reconstructs the network info after updating the operator key, ensuring consistency with the new state.


1329-1335: Proper deployment-based extended address flag.

The code correctly determines is_extended_addr based on V23 deployment status and passes it to validation, aligning with the PR's extended address support objectives.

src/evo/netinfo.h (4)

8-8: New dependency added for common types.

The inclusion of evo/common.h is appropriate for accessing the ProTxVersion enum used in the MakeNetInfo template function.


130-147: Well-designed polymorphic interface for network info.

The NetInfoInterface provides a clean abstraction with appropriate virtual methods. The static IsEqual method is a good solution for comparing shared pointers since operator overloading in virtual classes is not feasible.


149-199: MnNetInfo correctly implements the interface.

The refactoring of MnNetInfo to inherit from NetInfoInterface is well-implemented. All virtual methods are properly overridden with the override keyword.


201-207:

✅ Verification successful

Verify version range assertion logic.

The factory function asserts that obj.nVersion is greater than 0 and less than ProTxVersion::ExtAddr. Ensure that this version checking logic aligns with the actual version values defined in evo/common.h.


🏁 Script executed:

#!/bin/bash
# Description: Verify ProTxVersion enum values and version checking logic
# Expected: ProTxVersion::ExtAddr should be defined and have appropriate value

# Find the ProTxVersion enum definition
ast-grep --pattern 'enum $_ ProTxVersion $_'

Length of output: 46


Let’s locate the ProTxVersion enum and confirm the value of ExtAddr:


🏁 Script executed:

#!/bin/bash
# Find where ProTxVersion is defined and its members
rg -n "enum .*ProTxVersion" -C3
# Confirm the numeric value (or surrounding context) of ExtAddr
rg -n "ExtAddr" -C3

Length of output: 4482


Assertion logic confirmed against enum definitions

ProTxVersion in src/evo/common.h is defined as:

  • LegacyBLS = 1
  • BasicBLS = 2
  • ExtAddr = 3

The factory’s

assert(obj.nVersion > 0 && obj.nVersion < ProTxVersion::ExtAddr);

therefore enforces obj.nVersion ∈ {1,2}—exactly LegacyBLS and BasicBLS. No change is needed unless you plan to handle ExtAddr (3) or higher here with a different NetInfoInterface implementation.

src/evo/deterministicmns.h (5)

68-83: SERIALIZE_METHODS refactor looks correct.

The migration to the SERIALIZE_METHODS macro simplifies the serialization code while maintaining backward compatibility with version checks for the nType field.


176-195: Improved serialization with structured bindings.

The use of structured bindings (const auto& [_, dmn]) and uniform initialization improves code readability. The new Clear() method call before deserialization is a good practice.


197-202: Clear() method provides proper state reset.

The Clear() method properly resets all internal maps using default constructors, which is essential for safe deserialization.


393-394: Template static assertions updated for new interface types.

The additions correctly exclude the new NetInfoInterface and std::shared_ptr<NetInfoInterface> types from the GetUniquePropertyHash template method, maintaining type safety.


477-520: Serialization improvements with structured bindings.

The changes improve code clarity with structured bindings and uniform initialization. The comment about CDeterministicMNStateDiff migration logic is helpful context.

src/evo/common.h Outdated
Comment on lines 10 to 16
namespace ProTxVersion {
enum : uint16_t {
LegacyBLS = 1,
BasicBLS = 2,
ExtAddr = 3,
};
} // namespace ProTxVersion
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix formatting to address pipeline failure.

The clang format check failed due to inconsistent spacing around enum values. Apply consistent formatting to resolve the CI failure.

 namespace ProTxVersion {
-enum : uint16_t {
-    LegacyBLS = 1,
-    BasicBLS  = 2,
-    ExtAddr   = 3,
-};
+enum : uint16_t {
+    LegacyBLS = 1,
+    BasicBLS = 2,
+    ExtAddr = 3,
+};
 } // namespace ProTxVersion
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
namespace ProTxVersion {
enum : uint16_t {
LegacyBLS = 1,
BasicBLS = 2,
ExtAddr = 3,
};
} // namespace ProTxVersion
namespace ProTxVersion {
enum : uint16_t {
LegacyBLS = 1,
BasicBLS = 2,
ExtAddr = 3,
};
} // namespace ProTxVersion
🧰 Tools
🪛 GitHub Actions: Clang Diff Format Check

[error] 10-18: Clang format differences found: inconsistent spacing around enum values; lines need reformatting.

🤖 Prompt for AI Agents
In src/evo/common.h around lines 10 to 16, the enum values have inconsistent
spacing which causes the clang format check to fail. Adjust the spacing around
the enum values so that the equals signs and values are aligned consistently,
ensuring uniform indentation and spacing to pass the formatting check.

Comment on lines 209 to 251
class NetInfoSerWrapper
{
private:
std::shared_ptr<NetInfoInterface>& m_data;
const bool m_is_extended{false};

public:
NetInfoSerWrapper() = delete;
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
m_data{data},
m_is_extended{is_extended}
{
// TODO: Remove when extended addresses implementation is added in
assert(!m_is_extended);
}
template <typename Stream>
NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }

~NetInfoSerWrapper() = default;

void Clear() { m_addr.Clear(); }
template <typename Stream>
void Serialize(Stream& s) const
{
if (const auto ptr{std::dynamic_pointer_cast<MnNetInfo>(m_data)}) {
s << *ptr;
} else {
// MakeNetInfo() supplied an unexpected implementation or we didn't call it and
// are left with a nullptr. Neither should happen.
assert(false);
}
}

template <typename Stream>
void Unserialize(Stream& s)
{
m_data = std::make_shared<MnNetInfo>(deserialize, s);
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

NetInfoSerWrapper design needs refinement.

Several concerns with the current implementation:

  1. The constructor takes a mutable reference but the class has const and non-const methods that could cause confusion
  2. The assertion assert(!m_is_extended) suggests incomplete implementation
  3. The deserialization constructor template doesn't make sense in this context

Consider these improvements:

 class NetInfoSerWrapper
 {
 private:
     std::shared_ptr<NetInfoInterface>& m_data;
-    const bool m_is_extended{false};
+    const bool m_is_extended;
 
 public:
     NetInfoSerWrapper() = delete;
     NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
     NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
         m_data{data},
         m_is_extended{is_extended}
     {
-        // TODO: Remove when extended addresses implementation is added in
-        assert(!m_is_extended);
+        if (m_is_extended) {
+            throw std::runtime_error("Extended addresses not yet supported");
+        }
     }
-    template <typename Stream>
-    NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class NetInfoSerWrapper
{
private:
std::shared_ptr<NetInfoInterface>& m_data;
const bool m_is_extended{false};
public:
NetInfoSerWrapper() = delete;
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
m_data{data},
m_is_extended{is_extended}
{
// TODO: Remove when extended addresses implementation is added in
assert(!m_is_extended);
}
template <typename Stream>
NetInfoSerWrapper(deserialize_type, Stream& s) { s >> *this; }
~NetInfoSerWrapper() = default;
void Clear() { m_addr.Clear(); }
template <typename Stream>
void Serialize(Stream& s) const
{
if (const auto ptr{std::dynamic_pointer_cast<MnNetInfo>(m_data)}) {
s << *ptr;
} else {
// MakeNetInfo() supplied an unexpected implementation or we didn't call it and
// are left with a nullptr. Neither should happen.
assert(false);
}
}
template <typename Stream>
void Unserialize(Stream& s)
{
m_data = std::make_shared<MnNetInfo>(deserialize, s);
}
};
class NetInfoSerWrapper
{
private:
std::shared_ptr<NetInfoInterface>& m_data;
const bool m_is_extended;
public:
NetInfoSerWrapper() = delete;
NetInfoSerWrapper(const NetInfoSerWrapper&) = delete;
NetInfoSerWrapper(std::shared_ptr<NetInfoInterface>& data, const bool is_extended) :
m_data{data},
m_is_extended{is_extended}
{
if (m_is_extended) {
throw std::runtime_error("Extended addresses not yet supported");
}
}
~NetInfoSerWrapper() = default;
template <typename Stream>
void Serialize(Stream& s) const
{
if (const auto ptr{std::dynamic_pointer_cast<MnNetInfo>(m_data)}) {
s << *ptr;
} else {
// Unexpected type or null pointer
assert(false);
}
}
template <typename Stream>
void Unserialize(Stream& s)
{
m_data = std::make_shared<MnNetInfo>(deserialize, s);
}
};
🤖 Prompt for AI Agents
In src/evo/netinfo.h around lines 209 to 247, the NetInfoSerWrapper class has
design issues: it takes a mutable reference but has const and non-const methods
causing confusion, the assert(!m_is_extended) indicates incomplete features, and
the deserialization constructor template is unclear. To fix, change the
constructor to take a shared_ptr by value or const reference to avoid mutable
reference confusion, remove or properly implement the extended addresses feature
instead of asserting, and revise or remove the deserialization constructor
template to clearly separate construction and deserialization logic.

@kwvg kwvg requested review from knst, UdjinM6 and PastaPastaPasta May 28, 2025 22:23
@kwvg kwvg requested a review from UdjinM6 June 1, 2025 13:43
Copy link

github-actions bot commented Jul 4, 2025

This pull request has conflicts, please rebase.

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 3e65628

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

@PastaPastaPasta PastaPastaPasta merged commit 831afb2 into dashpay:develop Jul 7, 2025
29 of 34 checks passed
PastaPastaPasta added a commit that referenced this pull request Jul 10, 2025
…roTx version changes with `DEPLOYMENT_V23`

af10784 doc: add release notes for version restrictions (Kittywhiskers Van Gogh)
991f14d evo: prohibit new legacy scheme masternode registrations (Kittywhiskers Van Gogh)
abf96b5 evo: prohibit extended address versioning on unsupported transactions (Kittywhiskers Van Gogh)
de7f928 evo: prohibit upgrading from LegacyBLS to ExtAddr support directly (Kittywhiskers Van Gogh)
e430e6e evo: prohibit any ProTx with legacy BLS version after basic BLS upgrade (Kittywhiskers Van Gogh)
dc687a9 rpc: constrain ProTx version for ProUpRevTx based on legacy status (Kittywhiskers Van Gogh)
23c5152 trivial: use consistent variable name, use brackets (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Depends on #6665

  * Depends on #6723

  * Please refer to comments from [dash#6665](#6665) for prior discussion on the contents of the pull request ([comment](#6665 (comment)), [comment](#6665 (comment)), [comment](#6665 (comment)))

  * Complementing the deprecation in [dash#6723](#6723), after `DEPLOYMENT_V23` is activated
    * Registration of **new** masternodes  (i.e. `ProRegTx`) with the legacy scheme (`LegacyBLS`) will no longer be allowed. Existing masternodes are not affected and can continue to operate and participate.

    * Masternodes that are already using the basic scheme (`BasicBLS`) or higher may no longer **downgrade** to the legacy scheme.

  * Additional guardrails have been introduced to complement [dash#6665](#6665), which reserves a new version for extended addresses (`ExtAddr`), affecting `ProRegTx` and `ProUpServTx`, applicable after `DEPLOYMENT_V23` is activated
    * Masternodes **must** migrate to the basic scheme (`BasicBLS`) _before_ attempting to utilize extended addresses (`ExtAddr`), legacy scheme nodes may not attempt a direct upgrade.

    * Special transactions other than `ProRegTx` or `ProUpServTx` may not bear the version reserved for extended addresses (`ExtAddr`). Note that `IsVersionChangeValid()` does not extend to `ProRegTx` as it _creates_ a new entry and therefore doesn't have a masternode state version to compare against (i.e. there's no version to _change_), so the restriction in `IsVersionChangeValid()` only _de facto_ applies to `ProUpServTx`.

  * Future version updates must be conscious of updates to the masternode state ([source](https://github.com/dashpay/dash/blob/d9f52acecb94d57be91b5e17d478d5c909df3633/src/evo/deterministicmns.cpp#L887-L888)), example code for what changes may be required are available [here](#6665 (comment)).

  ## Breaking Changes

  * `protx revoke` will no longer default to using the highest possible version of `ProUpRevTx` and will now _clamp_ the version to `LegacyBLS` if the masternode uses the legacy scheme.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK af10784
  UdjinM6:
    utACK af10784

Tree-SHA512: fe788c33397f9e351377777946d5c0498569f68f22d308cce03f903fb3e149bd594ce2caafc50fd62611029563e2841bc42151579b21ba42fdf87cbf7762f716
PastaPastaPasta added a commit that referenced this pull request Jul 15, 2025
…addresses` field, deprecate `service` field, allow submitting multiple addresses

7fdd642 docs: add documentation for deprecation, new field and renamed input (Kittywhiskers Van Gogh)
5c564c2 test: check pre-fork conditions for ProRegTx and ProUpServTx preparation (Kittywhiskers Van Gogh)
859ce5c test: validate common conditions for input validation (Kittywhiskers Van Gogh)
a60c39a test: add functional test for `addresses` and deprecated `service` field (Kittywhiskers Van Gogh)
e0d2a81 rpc: deprecate key "service" replaced by "addresses" (Kittywhiskers Van Gogh)
d9247ad rpc: add new key "addresses" to allow reporting multiple entries (Kittywhiskers Van Gogh)
33e5f6a refactor: s/ipAndPort/coreP2PAddrs/g (Kittywhiskers Van Gogh)
4fd4e0e rpc: allow `ipAndPort` to accept multiple entries with arrays (Kittywhiskers Van Gogh)
8c28f30 rpc: spin-off `ipAndPort` and `platform{HTTP,P2P}Port` setters to util (Kittywhiskers Van Gogh)

Pull request description:

  ## Motivation

  To enable including functional tests with the extended addresses (ExtAddr) implementation (i.e. [dash#6666](#6666)), we need the ability to _specify_ and _retrieve_ multiple addresses. The current RPCs do not allow for that and this pull request aims to remedy it.

  This _particular_ pull request does not include:
  * Compatibility logic to allow reporting Platform-specific addresses using legacy fields (will be submitted after ExtAddr impl)
  * Compatibility logic to allow deriving Platform ports from extended address entries to populate deprecated fields (will be submitted after ExtAddr impl)
  * The ability to submit multiple Platform addresses (done in conjunction with ExtAddr impl)

  ## Additional Information

  * Depends on #6665

  * Depends on #6720

  * Dependency for #6666

  * ⚠️ The format for the field replacing `service`, `addresses` is not stable and is changed in [dash#6666](#6666) to allow reporting Platform-specific addresses. This should be acceptable as the whole extended addresses changeset across multiple PRs is expected to be part of a major release but is mentioned here for the sake of posterity.

  * As `IsDeprecatedRPCEnabled()` is defined in `libbitcoin_node` (see `rpc/server.cpp`, [source](https://github.com/dashpay/dash/blob/da8a475dfac9ad80d566eef8cf119c8036d6ebcc/src/rpc/server.cpp#L370-L375)), it is not available to `libbitcoin_common`, where special transaction and network information source files are included. To get around this, a practically identical function, `IsServiceDeprecatedRPCEnabled()` is defined and used in non-RPC code.
    * It is located in `evo/netinfo.cpp` instead of a more natural `rpc/evo_util.cpp` to avoid unnecessary circular dependencies.

  ## Breaking Changes

  * The input field `ipAndPort` has been renamed to `coreP2PAddrs`.
    * `coreP2PAddrs` can now, in addition to accepting a string, accept an array of strings, subject to validation rules.

  * The key `service` has been deprecated for some RPCs (`decoderawtransaction`, `decodepsbt`, `getblock`, `getrawtransaction`,
    `gettransaction`, `masternode status` (only for the `dmnState` key), `protx diff`, `protx listdiff`) and has been replaced
    with the field `addresses`.
    * The deprecated field can be re-enabled using `-deprecatedrpc=service` but is liable to be removed in future versions
      of Dash Core.
    * This change does not affect `masternode status` (except for the `dmnState` key) as `service` does not represent a payload
      value but the external address advertised by the active masternode.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 7fdd642
  UdjinM6:
    utACK 7fdd642

Tree-SHA512: 75331a467e7170542349c94408b71f5d25ebd2bf418cb6bdf77866a342b9079ec795638535f67c6487739b37651bf8265dce66ef3b06e0732748a173441695ef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants