Skip to content

refactor: expose masternode Platform endpoints, quorum keys and islocks via node interface - #7591

Open
PastaPastaPasta wants to merge 1 commit into
dashpay:developfrom
PastaPastaPasta:platform-node-seams
Open

refactor: expose masternode Platform endpoints, quorum keys and islocks via node interface#7591
PastaPastaPasta wants to merge 1 commit into
dashpay:developfrom
PastaPastaPasta:platform-node-seams

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

Part of the Dash Platform GUI train (#7512). dash-qt's Platform integration needs three pieces of node state that today have no interfaces::Node surface: evonode Platform HTTPS endpoints (to select DAPI gateways from the locally synced masternode list), locally retained Platform-quorum public keys (to verify Platform quorum signatures against local LLMQ data instead of trusting a remote key service), and InstantSend locks by txid (to build asset-lock proofs).

What was done?

Three read-only additions, compiled unconditionally (no Platform types, no feature gate):

  • MnEntry::getPlatformHTTPSAddrs() — the PLATFORM_HTTPS entries from the extended address list; empty for non-evo masternodes.
  • LLMQ::getPlatformQuorums(uint8_t llmq_type) — quorum hash, serialized basic-scheme BLS public key, and height for locally retained quorums, scanning max(signingActiveQuorumCount, keepOldKeys) so verification keeps working for proofs signed by recently rotated-out quorums.
  • LLMQ::getInstantSendLock(const uint256& txid) — serialized islock or empty.

These are exports of already-public node state (netInfo->GetEntries, qman->ScanQuorums, isman->GetInstantSendLockByTxid); no consensus surface, no key material, no behavior change for existing code.

Reference implementation using these seams: PastaPastaPasta#67.

How Has This Been Tested?

Compiles cleanly (node/libbitcoin_node_a-interfaces.o on macOS arm64 against depends). No other implementers of these interface classes exist in-tree (verified across src/test, src/qt/test, src/interfaces, src/ipc), so the pure-virtual additions require no stubs.

Breaking Changes

None.

@thepastaclaw

thepastaclaw commented Aug 13, 2026

Copy link
Copy Markdown

⛔ Blockers found — Opus deferred (commit 027764f)
Canonical validated blockers: 1

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b6d6307e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/interfaces.cpp
Comment on lines +141 to +142
if (const auto service_opt{entry.GetAddrPort()}) {
ret.push_back(*service_opt);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve domain-based Platform HTTPS endpoints

When an EvoNode registers a valid domain endpoint such as example.com:443, GetAddrPort() returns empty because the entry contains a DomainPort, so this loop silently omits it. Platform HTTPS explicitly supports internet domains (as exercised in test/functional/rpc_netinfo.py), meaning the GUI can receive an incomplete or empty DAPI gateway list; expose both service and domain endpoint forms instead of restricting the interface to CService.

AGENTS.md reference: AGENTS.md:L172-L180

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fe515160-a7e1-43d6-b737-3aaf10f989ce

📥 Commits

Reviewing files that changed from the base of the PR and between d370d90 and 027764f.

📒 Files selected for processing (2)
  • src/interfaces/node.h
  • src/node/interfaces.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/interfaces/node.h
  • src/node/interfaces.cpp

Walkthrough

The node interfaces now expose platform HTTPS addresses for Evo masternodes. LLMQ exposes retained platform quorum hashes, serialized public keys, heights, and serialized InstantSend locks. Implementations resolve supported addresses, retrieve rotation-aware quorum commitments, filter invalid keys, and return matching serialized locks.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to 02776

The PR adds read-only access to existing masternode, quorum, and InstantSend state without changing existing behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant MnEntryImpl
  participant LLMQImpl
  participant LLMQBlockProcessor
  participant InstantSendState
  Caller->>MnEntryImpl: request platform HTTPS addresses
  MnEntryImpl-->>Caller: return valid addresses
  Caller->>LLMQImpl: request platform quorum data
  LLMQImpl->>LLMQBlockProcessor: retrieve retained commitments
  LLMQBlockProcessor-->>LLMQImpl: return quorum commitments
  LLMQImpl-->>Caller: return valid quorum data
  Caller->>LLMQImpl: request InstantSend lock by transaction ID
  LLMQImpl->>InstantSendState: find matching lock
  InstantSendState-->>LLMQImpl: return serialized lock
  LLMQImpl-->>Caller: return lock data
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the three main node-interface additions for Platform endpoints, quorum keys, and InstantSend locks.
Description check ✅ Passed The description directly explains the implemented interface additions, their purpose, testing, and impact.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/node/interfaces.cpp`:
- Around line 137-146: Add targeted C++ unit tests covering the new interface
exports, including getPlatformHTTPSAddrs() handling invalid platform entries and
non-Evo entries, invalid LLMQ types and retained quorum selection, basic-scheme
public-key bytes, and serialized InstantSend locks. Use existing test fixtures
and assert the changed invariants so valid Platform proofs remain accepted and
asset-lock proofs serialize correctly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e5330ff3-c927-4def-bf78-2c489eceafe3

📥 Commits

Reviewing files that changed from the base of the PR and between 76c38fa and 8b6d630.

📒 Files selected for processing (2)
  • src/interfaces/node.h
  • src/node/interfaces.cpp

Comment thread src/node/interfaces.cpp
Comment on lines +137 to +146
std::vector<CService> getPlatformHTTPSAddrs() const override
{
std::vector<CService> ret;
for (const auto& entry : m_dmn->pdmnState->netInfo->GetEntries(NetInfoPurpose::PLATFORM_HTTPS)) {
if (const auto service_opt{entry.GetAddrPort()}) {
ret.push_back(*service_opt);
}
}
return ret;
}

@coderabbitai coderabbitai Bot Aug 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Add targeted coverage for the new interface exports.

No test changes cover the new endpoint, quorum, or InstantSend-lock behavior. Add tests for invalid platform entries, non-Evo entries, invalid LLMQ types, retained quorum selection, basic-scheme public-key bytes, and serialized locks. A regression here can cause the GUI to reject valid Platform proofs or build invalid asset-lock proofs.

As per coding guidelines, “Choose and add targeted C++ unit tests for changed behavior,” and quorum changes require small tests that prove the changed invariant.

Also applies to: 552-594

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/node/interfaces.cpp` around lines 137 - 146, Add targeted C++ unit tests
covering the new interface exports, including getPlatformHTTPSAddrs() handling
invalid platform entries and non-Evo entries, invalid LLMQ types and retained
quorum selection, basic-scheme public-key bytes, and serialized InstantSend
locks. Use existing test fixtures and assert the changed invariants so valid
Platform proofs remain accepted and asset-lock proofs serialize correctly.

Source: Coding guidelines

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The coverage request is valid, but endpoint tests must also include a valid DomainPort such as example.com:443. PLATFORM_HTTPS explicitly accepts DomainPort entries, while the current CService-only export silently drops them. The quorum test should also verify that exporting the retained window does not require materializing every full CQuorum object.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Network entry definitions and conversions =='
rg -n -A12 -B8 'GetAddrPort\s*\(|DomainPort|PLATFORM_HTTPS' src --glob '*.{h,cpp}'

printf '%s\n' '== Quorum scan declarations and implementations =='
rg -n -A18 -B10 'ScanQuorums\s*\(' src --glob '*.{h,cpp}'

printf '%s\n' '== Existing interface and quorum-related tests =='
fd -t f . src test 2>/dev/null | rg '(interfaces|quorum|llmq|deterministicmn|netinfo).*(_tests)?\.(cpp|h)$' | head -100
rg -n -A8 -B5 '(GetEntries|PLATFORM_HTTPS|DomainPort|ScanQuorums)' src test --glob '*_tests.cpp' --glob '*.cpp' 2>/dev/null | head -240

Length of output: 152096


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== ScanQuorums implementation =='
sed -n '177,285p' src/llmq/quorumsman.cpp

printf '%s\n' '== Quorum construction and lightweight commitment retrieval =='
sed -n '168,235p' src/llmq/quorumsman.h
rg -n -A16 -B8 '(BuildQuorumFromCommitment|GetMinedCommitment|GetFinalCommitment|Read.*Commitment|CFinalCommitment)' src/llmq src/evo --glob '*.{h,cpp}' | head -300

printf '%s\n' '== Public interface contract =='
rg -n -A25 -B8 'getPlatformHTTPSAddrs|PlatformQuorum|getPlatformQuorums' src/interfaces/node.h

Length of output: 34197


@thepastaclaw, confirmed.

PLATFORM_HTTPS accepts DomainPort. Existing tests validate example.com:443. getPlatformHTTPSAddrs() cannot return this value because its public type is std::vector<CService> and its implementation only uses GetAddrPort(). The fix must change the interface contract and implementation to preserve both CService and DomainPort endpoints. The tests must assert that both endpoint types are exported.

getPlatformQuorums() also currently calls CQuorumManager::ScanQuorums(). That method calls GetQuorum() for every retained result. It therefore materializes full CQuorum objects and their member lists. The fix needs a lightweight retained-commitment query that returns the quorum hash, basic-scheme public key bytes, and base height without constructing CQuorum.

I will keep this finding open with the expanded scope.

🧐🐇


✏️ Learnings added
Learnt from: thepastaclaw
Repo: dashpay/dash PR: 7591
File: src/node/interfaces.cpp:137-146
Timestamp: 2026-08-13T03:37:37.236Z
Learning: For Dash Platform endpoint exports, `NetInfoPurpose::PLATFORM_HTTPS` can contain either `CService` or `DomainPort` entries. In particular, `example.com:443` is valid. An `interfaces::MnEntry` accessor for Platform HTTPS endpoints must preserve both types; a `std::vector<CService>` return type silently drops valid `DomainPort` entries.

Learnt from: thepastaclaw
Repo: dashpay/dash PR: 7591
File: src/node/interfaces.cpp:137-146
Timestamp: 2026-08-13T03:37:37.236Z
Learning: In `src/llmq/quorumsman.cpp`, `CQuorumManager::ScanQuorums()` materializes each result through `GetQuorum()`, including full `CQuorum` member data. An interface that exports only retained quorum hash, basic-scheme public key bytes, and height should use a lightweight retained-commitment enumeration path instead of `ScanQuorums()`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The InstantSend-lock export and basic-scheme quorum-key serialization are consistent with existing node behavior. The Platform endpoint contract omits valid DNS gateways, while quorum enumeration synchronously materializes up to 1,440 full quorum objects; targeted tests for these new interface contracts are also absent.
Source: reviewer backend model gpt-5.6-sol; final verifier backend model gpt-5.6-sol; openclaw-agent/cliproxy/gpt-5.6-sol is orchestration-only and not reviewer evidence.

Validated blockers were found in the Codex precheck. Opus is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking | 🟡 2 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/node/interfaces.cpp`:
- [BLOCKING] src/node/interfaces.cpp:140-143: Preserve domain-based Platform HTTPS endpoints
  `PLATFORM_HTTPS` entries may contain either a `CService` or a `DomainPort`. `ExtNetInfo::ProcessCandidate()` explicitly permits domains for this purpose, and the netinfo tests accept entries such as `example.com:443`. `GetAddrPort()` returns `std::nullopt` for every `DomainPort`, so this implementation silently drops valid DAPI gateways. Because the interface returns only `std::vector<CService>`, callers cannot recover the omitted hostname, leaving the GUI with an incomplete or empty gateway set for evonodes that advertise DNS endpoints. Expose a representation that preserves both endpoint variants, such as a validated host-and-port string or a dedicated endpoint variant.
- [SUGGESTION] src/node/interfaces.cpp:570-572: Avoid constructing full quorums just to export public keys
  Platform quorum parameters retain 24 × 30 × 2 = 1,440 quorum keys. `ScanQuorums()` materializes a `CQuorum` for every uncached commitment: `BuildQuorumFromCommitment()` computes the full member list, reads or rebuilds contribution and verification-vector data, and unconditionally inserts the resulting object into `mapQuorumsCache`, whose per-type capacity is initialized from `keepOldKeys`. The new API only needs the quorum hash, public key, and base height, but its initial GUI-thread invocation can therefore build and retain two months of full quorum objects, and the reference consumer refreshes this context every minute. Add a lightweight quorum-manager export that scans mined commitments and returns these three fields without constructing `CQuorum` instances.
- [SUGGESTION] src/node/interfaces.cpp:137-146: Add targeted coverage for the new interface exports
  The PR introduces three externally consumed interface contracts but adds no tests beyond a compile check. Add focused tests for non-evo and missing-context results, valid `CService` and `DomainPort` HTTPS entries, unsupported LLMQ types, the retained-quorum window, basic-scheme public-key bytes, and exact InstantSend-lock serialization with the missing-lock case. In particular, a valid domain-endpoint test would expose the current loss of DNS gateways, while serialization assertions would prevent subtle incompatibilities in Platform proof and asset-lock construction.

Comment thread src/node/interfaces.cpp
Comment on lines +140 to +143
for (const auto& entry : m_dmn->pdmnState->netInfo->GetEntries(NetInfoPurpose::PLATFORM_HTTPS)) {
if (const auto service_opt{entry.GetAddrPort()}) {
ret.push_back(*service_opt);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Blocking: Preserve domain-based Platform HTTPS endpoints

PLATFORM_HTTPS entries may contain either a CService or a DomainPort. ExtNetInfo::ProcessCandidate() explicitly permits domains for this purpose, and the netinfo tests accept entries such as example.com:443. GetAddrPort() returns std::nullopt for every DomainPort, so this implementation silently drops valid DAPI gateways. Because the interface returns only std::vector<CService>, callers cannot recover the omitted hostname, leaving the GUI with an incomplete or empty gateway set for evonodes that advertise DNS endpoints. Expose a representation that preserves both endpoint variants, such as a validated host-and-port string or a dedicated endpoint variant.

source: ['codex']

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

GUI may have incomplete gateway sets but it won't be empty since the first entry must be CService

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks — that matches what the consumer needs, so I've left the behaviour as-is and documented the constraint instead of widening the API.

For the record on the bot's finding: GetAddrPort() does drop DomainPort entries, so a masternode advertising extra domain-based gateways contributes only its CService ones here. Since the first entry is guaranteed to be a CService, the set is never empty and the GUI always has at least one reachable gateway per evonode — it rotates across many nodes, so an incomplete set per node isn't a functional problem. Resolving domains inside a node-interface getter would also mean DNS in a path that is supposed to be a cheap read of already-synced state.


🤖 Posted autonomously by Claude on behalf of pasta.

Comment thread src/node/interfaces.cpp Outdated
Comment on lines +570 to +572
const auto quorum_count{static_cast<size_t>(std::max(llmq_params->signingActiveQuorumCount,
llmq_params->keepOldKeys))};
for (const auto& q : context().llmq_ctx->qman->ScanQuorums(type, pindex, quorum_count)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Suggestion: Avoid constructing full quorums just to export public keys

Platform quorum parameters retain 24 × 30 × 2 = 1,440 quorum keys. ScanQuorums() materializes a CQuorum for every uncached commitment: BuildQuorumFromCommitment() computes the full member list, reads or rebuilds contribution and verification-vector data, and unconditionally inserts the resulting object into mapQuorumsCache, whose per-type capacity is initialized from keepOldKeys. The new API only needs the quorum hash, public key, and base height, but its initial GUI-thread invocation can therefore build and retain two months of full quorum objects, and the reference consumer refreshes this context every minute. Add a lightweight quorum-manager export that scans mined commitments and returns these three fields without constructing CQuorum instances.

source: ['codex']

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch — reworked in d370d90. getPlatformQuorums no longer calls qman->ScanQuorums, so it no longer materializes full CQuorum objects (member lists, contribution/vvec reads) or inserts into mapQuorumsCache. It now reads the mined final commitments directly via quorum_block_processor: GetMinedCommitmentsUntilBlock (or GetMinedCommitmentsIndexedUntilBlock for rotated LLMQ types, matching ScanQuorums' selection) over the same window of max(signingActiveQuorumCount, keepOldKeys) quorums walking back from the tip, then GetMinedCommitment per quorum base block — a single evoDb read each — extracting quorumHash, quorumPublicKey (ToByteVector(specificLegacyScheme=false), unchanged) and the quorum base block height. Invalid public keys are still filtered, null-guard and return semantics are unchanged, and ordering remains newest-first as before.


🤖 Posted autonomously by Claude on behalf of pasta.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Resolved in this update — Avoid constructing full quorums just to export public keys no longer present.

Auto-resolved by the review system based on the latest commit diff. If you believe this was closed in error, reopen the thread.

Comment thread src/node/interfaces.cpp
Comment on lines +137 to +146
std::vector<CService> getPlatformHTTPSAddrs() const override
{
std::vector<CService> ret;
for (const auto& entry : m_dmn->pdmnState->netInfo->GetEntries(NetInfoPurpose::PLATFORM_HTTPS)) {
if (const auto service_opt{entry.GetAddrPort()}) {
ret.push_back(*service_opt);
}
}
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Suggestion: Add targeted coverage for the new interface exports

The PR introduces three externally consumed interface contracts but adds no tests beyond a compile check. Add focused tests for non-evo and missing-context results, valid CService and DomainPort HTTPS entries, unsupported LLMQ types, the retained-quorum window, basic-scheme public-key bytes, and exact InstantSend-lock serialization with the missing-lock case. In particular, a valid domain-endpoint test would expose the current loss of DNS gateways, while serialization assertions would prevent subtle incompatibilities in Platform proof and asset-lock construction.

source: ['coderabbit']

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d370d901bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/interfaces.cpp
if (!context().llmq_ctx || !context().llmq_ctx->isman) {
return {};
}
const auto islock{context().llmq_ctx->isman->GetInstantSendLockByTxid(txid)};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Read retained islocks even when InstantSend is disabled

When SPORK_2 is disabled, or the node is reindexing/importing, this call returns empty for every txid because CInstantSendManager::GetInstantSendLockByTxid() exits before querying its database (src/instantsend/instantsend.cpp:357-363, with the gate defined at lines 479-482). Consequently, a previously stored islock becomes unavailable to the Platform GUI precisely as it tries to build an asset-lock proof, despite this interface promising emptiness only when the transaction has no islock; use a retained-lock lookup that is independent of whether new InstantSend processing is enabled.

AGENTS.md reference: AGENTS.md:L169-L172

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is fine; no action needed imo

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

Potential PR merge conflicts

This is advisory only. It does not block CI, but it marks PRs that will likely need a rebase depending on merge order.

If this PR merges first

These open PRs will likely need a rebase:

If these PRs merge first

This PR will likely need a rebase:

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The lightweight mined-commitment scan resolves the prior quorum materialization issue without constructing or caching full CQuorum objects. The endpoint export still drops valid DomainPort HTTPS gateways, and the three proof-facing interface contracts remain without targeted tests.
Source: reviewer backend model gpt-5.6-sol; final verifier backend model gpt-5.6-sol; openclaw-agent/cliproxy/gpt-5.6-sol is orchestration-only and not reviewer evidence.

Validated blockers were found in the Codex precheck. Opus is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking

2 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/node/interfaces.cpp`:
- [BLOCKING] src/node/interfaces.cpp:138-145: Preserve domain-based Platform HTTPS endpoints
  (existing thread: https://github.com/dashpay/dash/pull/7591#discussion_r3772204476)
  PLATFORM_HTTPS explicitly accepts both CService and DomainPort entries. ExtNetInfo::ProcessCandidate() allows DomainPort for this purpose, and the unit and functional tests accept internet domains such as example.com:443. GetAddrPort() returns std::nullopt for DomainPort, so this loop silently omits those valid DAPI gateways. Because the public interface returns only std::vector<CService>, the caller cannot recover the omitted hostnames, leaving its gateway set incomplete. Change the interface representation to preserve both endpoint variants, such as validated host-and-port strings or a dedicated endpoint type.
- [SUGGESTION] src/node/interfaces.cpp:138-145: Add targeted coverage for the new interface exports
  (existing thread: https://github.com/dashpay/dash/pull/7591#discussion_r3772204486)
  The PR introduces three externally consumed interface contracts but adds no tests beyond compilation. Add focused coverage for non-evo and missing-context results, both CService and DomainPort HTTPS endpoints, unsupported LLMQ types, rotated and non-rotated retained-quorum selection, basic-scheme public-key bytes, and exact InstantSend-lock serialization including the missing-lock behavior. These outputs feed Platform proof verification and asset-lock proof construction, so contract-level regressions can reject valid proofs or produce unusable requests.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 08f0b7ecee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/interfaces.cpp
std::vector<CService> getPlatformHTTPSAddrs() const override
{
std::vector<CService> ret;
for (const auto& entry : m_dmn->pdmnState->netInfo->GetEntries(NetInfoPurpose::PLATFORM_HTTPS)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include legacy EvoNode HTTPS endpoints

For EvoNodes whose state version predates ProTxVersion::ExtAddr, the Platform endpoint is stored as platformHTTPPort alongside the primary Core address rather than as a PLATFORM_HTTPS netInfo entry (src/evo/dmnstate.h:112-115, with the conversion spelled out in src/evo/specialtxman.cpp:471-473). This loop therefore returns an empty vector for valid legacy EvoNodes that have not submitted an extended-address update, removing those DAPI gateways from the GUI; synthesize the service from the primary address and legacy HTTP port when netInfo cannot store Platform entries.

AGENTS.md reference: AGENTS.md:L15-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid — fixed at the new head.

Confirmed against the code: CDeterministicMNState only serializes platformP2PPort/platformHTTPPort when nVersion < ProTxVersion::ExtAddr (src/evo/dmnstate.h:112-115), and specialtxman.cpp:471-478 zeroes those scalars from ExtAddr onward precisely because netInfo owns them then. So the netInfo-only loop returned an empty vector for every legacy EvoNode — which today is most of them, meaning the GUI would have seen gateways only from nodes that had already submitted an extended-address update.

getPlatformHTTPSAddrs() now branches on the state version: below ExtAddr it synthesizes the gateway from the primary address and the legacy platformHTTPPort (guarded on MnType::Evo and a non-zero port, using the same CService(addr, port) idiom as dmnstate.cpp:138 and rpc/evo_util.h:41); at ExtAddr and above it reads the PLATFORM_HTTPS netInfo entries as before.


🤖 Posted autonomously by Claude on behalf of pasta.

…ks via node interface

Add three read-only exports of already-public node state to the node interface, needed by the Dash Platform GUI train (dashpay#7512): getPlatformHTTPSAddrs() returns the extended netinfo PLATFORM_HTTPS entries for a masternode-list entry, getPlatformQuorums() exports ScanQuorums results over the retained-key window with basic-scheme serialized quorum public keys, and getInstantSendLock() returns the serialized islock for a txid via GetInstantSendLockByTxid.

Reference implementation consuming these seams: #67. No consensus surface is touched, no key material is exposed, and everything is compiled unconditionally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The current head restores legacy EvoNode HTTPS endpoints and avoids constructing full quorum objects, but the endpoint API still drops valid domain-based Platform HTTPS entries and can return an incomplete or empty gateway set. The three new externally consumed interface contracts also remain without targeted tests.
Source: reviewer backend model gpt-5.6-sol; final verifier backend model gpt-5.6-sol. openclaw-agent/cliproxy/gpt-5.6-sol is orchestration-only and not reviewer evidence.

Validated blockers were found in the Codex precheck. Opus is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking

2 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/node/interfaces.cpp`:
- [BLOCKING] src/node/interfaces.cpp:152-155: Preserve domain-based Platform HTTPS endpoints
  (existing thread: https://github.com/dashpay/dash/pull/7591#discussion_r3772204476)
  `PLATFORM_HTTPS` accepts both `CService` and `DomainPort`, but this loop exports only entries for which `GetAddrPort()` succeeds. `ExtNetInfo::ProcessCandidate()` and `ExtNetInfo::Validate()` explicitly permit `DomainPort` for this purpose, while provider-transaction validation requires only that the HTTPS list be nonempty; it does not require its first entry, or any entry, to be a `CService`. A valid EvoNode can therefore advertise only a domain such as `example.com:443`, causing this method to return an empty vector, and mixed lists silently lose their domain gateways. The new header comment's first-entry invariant is not enforced. Change the public representation so it can preserve both endpoint forms, such as validated host-and-port strings or a dedicated endpoint variant.
- [SUGGESTION] src/node/interfaces.cpp:138-158: Add targeted coverage for the new interface exports
  (existing thread: https://github.com/dashpay/dash/pull/7591#discussion_r3772204486)
  The PR adds three externally consumed interface contracts but no tests exercise them. Add focused coverage for legacy and ExtAddr EvoNodes, non-EvoNodes, missing contexts, both `CService` and `DomainPort` HTTPS endpoints, unsupported LLMQ types, rotated and non-rotated retained-quorum windows, basic-scheme public-key bytes, and exact InstantSend-lock serialization including the missing-lock case. A domain-only HTTPS test would expose the current endpoint loss, while quorum and serialization assertions would protect the Platform proof and asset-lock formats consumed outside this implementation.

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.

3 participants