Skip to content

feat(rpc): expose upcoming DKG participation#7428

Open
knst wants to merge 3 commits into
dashpay:developfrom
knst:rpc-dkg-scheduled-participation-2
Open

feat(rpc): expose upcoming DKG participation#7428
knst wants to merge 3 commits into
dashpay:developfrom
knst:rpc-dkg-scheduled-participation-2

Conversation

@knst

@knst knst commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Issue being fixed or feature implemented

Dashmate currently uses quorum dkginfo/quorum dkgstatus to avoid unsafe restart/reindex operations around DKG windows, but Core only exposes global DKG timing. That forces Dashmate to treat "a DKG is soon" as "this node might be needed", which blocks harmless recovery operations for masternodes that are not actually selected for the upcoming DKG.

What was done?

This PR extends quorum dkginfo so tooling can ask whether a specific proTxHash is selected for an upcoming, already-determinable DKG. What was done?

Added an optional quorum dkginfo proTxHash parameter, defaulting to the local active masternode when available.
Added an upcoming_dkgs result array with quorum type, planned quorum height, blocks until start, known/unknown status, and per-proTxHash membership fields when prediction is possible. The RPC reports only upcoming sessions whose work block is already mined.
Added utility helpers that compute future v20 quorum members from already-known DKG work blocks for both non-rotated and rotated quorum types. For rotated quorums, prediction uses the cycle base work block and historical quarter-rotation snapshots, without storing a snapshot for the future cycle base block.
Shared the post-v20 work-block hash modifier helper with normal quorum selection, so prediction does not duplicate modifier logic. Snapshot the chain tip/work-block lookup consistently for the prediction path. Return structured unknown reasons instead of guessing for cases that cannot be predicted safely, including unavailable work blocks, unavailable rotated snapshots, and pre-v20 quorum selection.

How Has This Been Tested?

See updates for functional tests

Breaking Changes

N/A

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
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@thepastaclaw

thepastaclaw commented Jul 8, 2026

Copy link
Copy Markdown

✅ Review complete (commit 2629a3b)

@github-actions

github-actions Bot commented Jul 8, 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:

@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: 5a9b3d4605

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/llmq/utils.cpp
Comment on lines +622 to +627
auto quorumMembers = ComputeQuorumMembersByQuarterRotation(llmq_params, util_params, pWorkBlockIndex,
cycleBaseHeight, modifier, /*storeSnapshot=*/false);
if (quorumMembers.empty()) {
return std::nullopt;
}
return quorumMembers[quorumIndex];

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 Reject incomplete rotated predictions

When a rotated quorum is predicted and any of the three prior cycle snapshots is unavailable (GetSnapshotForBlock breaks out above), ComputeQuorumMembersByQuarterRotation still returns a non-empty outer vector containing only the quarters it could reconstruct plus the new quarter. This wrapper treats that as known and returns quorumMembers[quorumIndex], so quorum dkginfo can report a reduced memberCount and isMember=false for masternodes that are actually in one of the missing previous quarters (for example while the snapshot DB is incomplete or the required warm-up snapshots are not available). Please return std::nullopt unless the rotated prediction contains a full llmq_params.size members for the requested index.

Useful? React with 👍 / 👎.

@PastaPastaPasta PastaPastaPasta left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

~~I found one correctness issue in the replacement branch. The simplified rotated prediction path can return known=true using incomplete previous-quarter data when the required rotated quorum snapshots are unavailable, which is unsafe for the Dashmate use case this RPC is meant to support.

I did not run the full functional tests locally; I did run git diff --check and Python compile checks for the touched functional-test files, both clean. CI is still partially pending on GitHub.
~~
Codex posted for me :(

Comment thread src/llmq/utils.cpp
@coderabbitai

coderabbitai Bot commented Jul 8, 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

Run ID: aa38e4fa-bd26-466e-8b9e-2102fa2caf4f

📥 Commits

Reviewing files that changed from the base of the PR and between e0e1e8f and 2629a3b.

📒 Files selected for processing (5)
  • src/llmq/utils.cpp
  • src/llmq/utils.h
  • src/rpc/quorums.cpp
  • test/functional/feature_llmq_rotation.py
  • test/functional/test_framework/test_framework.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • test/functional/feature_llmq_rotation.py
  • src/llmq/utils.h
  • test/functional/test_framework/test_framework.py
  • src/rpc/quorums.cpp
  • src/llmq/utils.cpp

Walkthrough

This PR refactors LLMQ quarter-rotation member selection to use explicit work-block, modifier, and cycle-base-height inputs, adds ComputeQuorumMembersFromWorkBlock for future quorum prediction, extends quorum dkginfo with an optional proTxHash and upcoming_dkgs output, and updates functional tests to validate the new prediction and fallback behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant quorum_dkginfo_RPC
  participant ComputeQuorumMembersFromWorkBlock
  participant ComputeQuorumMembersByQuarterRotation
  participant BuildNewQuorumQuarterMembers

  Client->>quorum_dkginfo_RPC: quorum dkginfo(proTxHash)
  quorum_dkginfo_RPC->>quorum_dkginfo_RPC: compute cycle base height and work block
  quorum_dkginfo_RPC->>ComputeQuorumMembersFromWorkBlock: predict members for quorumHeight
  ComputeQuorumMembersFromWorkBlock->>ComputeQuorumMembersByQuarterRotation: quarter-rotation path
  ComputeQuorumMembersByQuarterRotation->>BuildNewQuorumQuarterMembers: build with modifier and cycleBaseHeight
  BuildNewQuorumQuarterMembers-->>ComputeQuorumMembersByQuarterRotation: quarter members
  ComputeQuorumMembersByQuarterRotation-->>ComputeQuorumMembersFromWorkBlock: quorum list
  ComputeQuorumMembersFromWorkBlock-->>quorum_dkginfo_RPC: optional member list
  quorum_dkginfo_RPC-->>Client: upcoming_dkgs results
Loading

Possibly related PRs

  • dashpay/dash#7411: Both PRs modify quorum-related functional test helpers in test/functional/test_framework/test_framework.py.

Suggested reviewers: thepastaclaw, PastaPastaPasta

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main RPC feature added in this changeset.
Description check ✅ Passed The description clearly matches the implemented RPC, helper, and test changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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

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

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

🧹 Nitpick comments (1)
src/llmq/utils.cpp (1)

457-462: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Guard the implicit m_base_index == cycleBaseHeight coupling.

The function was refactored to take cycleBaseHeight explicitly, but the snapshot path still relies on util_params.m_base_index for both BuildQuorumSnapshot and StoreSnapshotForBlock. This silently assumes m_base_index->nHeight == cycleBaseHeight whenever storeSnapshot is true. It holds today because GetAllQuorumMembers calls replace_index(pCycleQuorumBaseBlockIndex), but a future caller passing a divergent cycleBaseHeight with storeSnapshot=true would persist a snapshot keyed to the wrong block. Consider asserting the invariant.

🛡️ Suggested guard
     if (storeSnapshot) {
+        ASSERT_IF_DEBUG(util_params.m_base_index->nHeight == cycleBaseHeight);
         llmq::CQuorumSnapshot quorumSnapshot{};
         BuildQuorumSnapshot(llmqParams, util_params.m_chainman.GetConsensus(), allMns, MnsUsedAtH, sortedCombinedMnsList,
                             quorumSnapshot, skipList, util_params.m_base_index);
         util_params.m_qsnapman.StoreSnapshotForBlock(llmqParams.type, util_params.m_base_index, quorumSnapshot);
     }
🤖 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/llmq/utils.cpp` around lines 457 - 462, The snapshot branch in the quorum
member flow still assumes util_params.m_base_index matches cycleBaseHeight when
storeSnapshot is true. In the BuildQuorumSnapshot and StoreSnapshotForBlock
path, add an explicit guard/assert around that invariant in GetAllQuorumMembers
so future callers cannot persist a snapshot under the wrong block index; keep
the check close to the existing use of util_params.m_base_index and
cycleBaseHeight.
🤖 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 `@test/functional/test_framework/test_framework.py`:
- Around line 2146-2159: The quorum prediction validation in test_framework.py
only asserts that memberIndex is present or not -1, so an incorrect positive
index could still pass. Update the checks in the prediction loop around
quorum_info["members"] and predictions to compare entry["memberIndex"] against
the actual position of proTxHash within quorum_info["members"], while still
keeping the existing isMember and memberCount assertions.

---

Nitpick comments:
In `@src/llmq/utils.cpp`:
- Around line 457-462: The snapshot branch in the quorum member flow still
assumes util_params.m_base_index matches cycleBaseHeight when storeSnapshot is
true. In the BuildQuorumSnapshot and StoreSnapshotForBlock path, add an explicit
guard/assert around that invariant in GetAllQuorumMembers so future callers
cannot persist a snapshot under the wrong block index; keep the check close to
the existing use of util_params.m_base_index and cycleBaseHeight.
🪄 Autofix (Beta)

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

Run ID: 0b14d51e-6d0b-49a4-9f20-9de5347ba22c

📥 Commits

Reviewing files that changed from the base of the PR and between 84b6bf6 and 5a9b3d4.

📒 Files selected for processing (5)
  • src/llmq/utils.cpp
  • src/llmq/utils.h
  • src/rpc/quorums.cpp
  • test/functional/feature_llmq_rotation.py
  • test/functional/test_framework/test_framework.py

Comment thread test/functional/test_framework/test_framework.py Outdated
@knst knst requested a review from PastaPastaPasta July 8, 2026 17:37

@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.

Code Review

Source: reviewers: codex/gpt-5.5 general, codex/gpt-5.5 dash-core-commit-history; failed lanes: claude/opus general, claude/opus dash-core-commit-history, claude/opus verifier (quota); verifier: codex/gpt-5.5.

The main correctness issue is confirmed: rotated quorum prediction can return known=true after silently dropping unavailable prior-quarter data, which contradicts the RPC's safety semantics for Dashmate. The added prediction tests also leave the new memberIndex field under-verified by checking only membership, not the returned position in the quorum member order.

1 blocking, 1 suggestion

Blocking

  • src/llmq/utils.cpp:490-500 - Missing rotated snapshots still produce known predictions
    In prediction mode, this loop stops as soon as a previous cycle ancestor or snapshot is unavailable, but it still proceeds with the remaining PreviousQuorumQuarters entries left empty. BuildNewQuorumQuarterMembers then computes a new quarter from that incomplete history, ComputeQuorumMembersFromWorkBlock returns a value, and quorum dkginfo reports known=true. For the Dashmate restart-safety use case, that can falsely report a masternode as not selected when it would have appeared in one of the missing historical quarters; unavailable rotated snapshot data must make the prediction unknown instead of partial.

Suggestion

  • test/functional/test_framework/test_framework.py:2146-2159 - Prediction tests do not verify the returned member index
    The new RPC exposes memberIndex, but the test only checks whether it is -1 consistently with isMember. A regression that returns the wrong positive index for a real member would still pass, even though quorum info exposes members in the same order used for quorum member indexes and consumers may rely on that position.
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/llmq/utils.cpp`:
- [BLOCKING] src/llmq/utils.cpp:490-500: Missing rotated snapshots still produce known predictions
  In prediction mode, this loop stops as soon as a previous cycle ancestor or snapshot is unavailable, but it still proceeds with the remaining `PreviousQuorumQuarters` entries left empty. `BuildNewQuorumQuarterMembers` then computes a new quarter from that incomplete history, `ComputeQuorumMembersFromWorkBlock` returns a value, and `quorum dkginfo` reports `known=true`. For the Dashmate restart-safety use case, that can falsely report a masternode as not selected when it would have appeared in one of the missing historical quarters; unavailable rotated snapshot data must make the prediction unknown instead of partial.

In `test/functional/test_framework/test_framework.py`:
- [SUGGESTION] test/functional/test_framework/test_framework.py:2146-2159: Prediction tests do not verify the returned member index
  The new RPC exposes `memberIndex`, but the test only checks whether it is `-1` consistently with `isMember`. A regression that returns the wrong positive index for a real member would still pass, even though `quorum info` exposes members in the same order used for quorum member indexes and consumers may rely on that position.

Comment on lines +2146 to +2159
members = set(m["proTxHash"] for m in quorum_info["members"])
work_height = quorum_info["height"] - quorum_info["quorumIndex"] - 8
for proTxHash, entries in predictions.items():
[entry] = [d for d in entries if d["quorumHeight"] == quorum_info["height"]]
assert_equal(entry["proTxHash"], proTxHash)
if not entry["known"]:
# no prediction was possible (e.g. pre-v20); the RPC must tell why
assert "reason" in entry
continue
assert_equal(entry["workBlockHeight"], work_height)
assert_equal(entry["workBlockHash"], self.nodes[0].getblockhash(work_height))
assert_equal(entry["memberCount"], len(members))
assert_equal(entry["isMember"], entry["memberIndex"] != -1)
assert_equal(entry["isMember"], proTxHash in members)

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: Prediction tests do not verify the returned member index

The new RPC exposes memberIndex, but the test only checks whether it is -1 consistently with isMember. A regression that returns the wrong positive index for a real member would still pass, even though quorum info exposes members in the same order used for quorum member indexes and consumers may rely on that position.

Suggested change
members = set(m["proTxHash"] for m in quorum_info["members"])
work_height = quorum_info["height"] - quorum_info["quorumIndex"] - 8
for proTxHash, entries in predictions.items():
[entry] = [d for d in entries if d["quorumHeight"] == quorum_info["height"]]
assert_equal(entry["proTxHash"], proTxHash)
if not entry["known"]:
# no prediction was possible (e.g. pre-v20); the RPC must tell why
assert "reason" in entry
continue
assert_equal(entry["workBlockHeight"], work_height)
assert_equal(entry["workBlockHash"], self.nodes[0].getblockhash(work_height))
assert_equal(entry["memberCount"], len(members))
assert_equal(entry["isMember"], entry["memberIndex"] != -1)
assert_equal(entry["isMember"], proTxHash in members)
member_list = [m["proTxHash"] for m in quorum_info["members"]]
members = set(member_list)
work_height = quorum_info["height"] - quorum_info["quorumIndex"] - 8
for proTxHash, entries in predictions.items():
[entry] = [d for d in entries if d["quorumHeight"] == quorum_info["height"]]
assert_equal(entry["proTxHash"], proTxHash)
if not entry["known"]:
# no prediction was possible (e.g. pre-v20); the RPC must tell why
assert "reason" in entry
continue
assert_equal(entry["workBlockHeight"], work_height)
assert_equal(entry["workBlockHash"], self.nodes[0].getblockhash(work_height))
assert_equal(entry["memberCount"], len(members))
expected_member_index = member_list.index(proTxHash) if proTxHash in members else -1
assert_equal(entry["memberIndex"], expected_member_index)
assert_equal(entry["isMember"], proTxHash in members)

source: ['codex']

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 e0e1e8fPrediction tests do not verify the returned member index 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.

@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.

Code Review

Source: reviewers: codex/gpt-5.5 general, codex/gpt-5.5 dash-core-commit-history; failed lanes: claude/opus general, claude/opus dash-core-commit-history; verifier: codex/gpt-5.5

prior-1 is STILL VALID: the current rotated prediction path can still return a known result after missing historical quarter data. prior-2 is FIXED by e0e1e8f, which now checks the exact ordered member index from quorum info. The latest push also introduced a small review-fix commit that should be folded into the feature commit before merge.

🔴 1 blocking | 🟡 1 suggestion(s)

2 finding(s) are included in the review body only; the current diff does not expose stable inline anchors for the carried-forward production issue or the commit-history note.

🤖 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/llmq/utils.cpp`:
- [BLOCKING] src/llmq/utils.cpp:490-500: Missing rotated snapshots still produce known predictions
  In prediction mode, this loop stops as soon as a previous cycle ancestor or snapshot is unavailable, but it still proceeds with the remaining PreviousQuorumQuarters entries left empty. BuildNewQuorumQuarterMembers then computes from incomplete history, ComputeQuorumMembersFromWorkBlock returns a value, and quorum dkginfo reports known=true. The feature commit explicitly promises structured unknown results for unavailable rotated snapshots, so this can falsely report a masternode as not selected when the missing historical quarter would have included it.

In `<commit:e0e1e8f>`:
- [SUGGESTION] <commit:e0e1e8f>:1: Squash memberIndex test fix into the feature commit
  Commit e0e1e8f6d49 only adjusts the functional test helper added by the preceding feature commit so it verifies memberIndex correctly. This is review-fix history rather than a separate logical change, and Dash PRs are kept cleaner when these small corrections are folded into the commit that introduced the behavior.

@knst

knst commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

prior-1 is STILL VALID: the current rotated prediction path can still return a known result after missing historical quarter data.

Concrete cases when it happens:

first few rotated cycles after DIP0024 activation / before 3 prior rotated snapshots exist
devnet/regtest with DIP0024 active from height 1
node with incomplete/corrupt/rebuilt EvoDB snapshot data

That's not real life scenarios and have nothing to do with PR description. there's no combination of "historical data" and "alive valid masternode"

@knst knst requested a review from thepastaclaw July 8, 2026 18:35
knst and others added 3 commits July 9, 2026 02:03
Dashmate currently uses quorum dkginfo/quorum dkgstatus to avoid unsafe
restart/reindex operations around DKG windows, but Core only exposes global DKG
timing. That forces Dashmate to treat "a DKG is soon" as "this node might be
needed", which blocks harmless recovery operations for masternodes that are not
actually selected for the upcoming DKG.

This PR extends quorum dkginfo so tooling can ask whether a specific
proTxHash is selected for an upcoming, already-determinable DKG.
What was done?

Added an optional quorum dkginfo proTxHash parameter, defaulting to the
local active masternode when available.
Added an upcoming_dkgs result array with quorum type, planned quorum height,
blocks until start, known/unknown status, and per-proTxHash membership
fields when prediction is possible. The RPC reports only upcoming sessions
whose work block is already mined.
Added utility helpers that compute future v20 quorum members from already-known
DKG work blocks for both non-rotated and rotated quorum types.
For rotated quorums, prediction uses the cycle base work block and historical
quarter-rotation snapshots, without storing a snapshot for the future cycle
base block.
Shared the post-v20 work-block hash modifier helper with normal quorum
selection, so prediction does not duplicate modifier logic.
Snapshot the chain tip/work-block lookup consistently for the prediction path.
Return structured unknown reasons instead of guessing for cases that cannot be
predicted safely, including unavailable work blocks, unavailable rotated
snapshots, and pre-v20 quorum selection.

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
…after missing historical quarter data

It never happens in real-life scenarios, only some corner cases such as:
     - first few rotated cycles after DIP0024 activation / before 3 prior rotated snapshots exist
     - devnet/regtest with DIP0024 active from height 1
     - node with incomplete/corrupt/rebuilt EvoDB snapshot data

Though, review agents are concerned about that issue very much, so it should be fixed.
@knst knst force-pushed the rpc-dkg-scheduled-participation-2 branch from 6f3f841 to 2629a3b Compare July 8, 2026 19:04

@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.

Code Review

Source: reviewers: codex/gpt-5.5 general, codex/gpt-5.5 dash-core-commit-history; failed lanes: claude/opus general, claude/opus dash-core-commit-history, claude/opus verifier (quota); verifier: codex/gpt-5.5.

The prior rotated-snapshot correctness finding is fixed at the current head: prediction mode now returns unknown when required historical rotated quorum data is unavailable. No new code-correctness issue was verified in the latest delta. The remaining verified issue is commit hygiene: both follow-up fix commits correct behavior introduced by the main feature commit and should be folded before merge.

🟡 1 suggestion

Prior Reconciliation

  • prior-1 FIXED: 2629a3b3570 makes prediction mode return no result when a required previous rotated cycle ancestor or snapshot is missing, so quorum dkginfo reports known=false instead of computing from incomplete historical quarters.
  • prior-2 STILL VALID: the memberIndex test correction is still present as a separate follow-up commit, now rewritten as 1f745e1f8db, rather than being folded into the feature commit that introduced the helper.

Carried-Forward Prior Findings

  • <commit:1f745e1> - Squash the memberIndex test fix into a1e59f1b8b0 so the feature lands with the corrected test helper from the start.

New Findings In Latest Delta

  • <commit:2629a3b> - The rotated prediction repair fixes the prior production issue, but it is also a direct review-fix commit for behavior introduced by a1e59f1b8b0; fold it into the feature commit before merge.
🤖 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 `<commit:1f745e1..2629a3b>`:
- [SUGGESTION] <commit:1f745e1..2629a3b>:1: Squash review-fix commits into the feature commit
  The current stack still has one feature commit followed by two small corrective commits: 1f745e1f8db only fixes the functional test helper added by a1e59f1b8b0, and 2629a3b3570 only fixes the rotated prediction behavior introduced by that same feature. These are not independent logical changes; they are review fixes for the new RPC/LLMQ prediction behavior. Since Dash preserves PR commit history, fold both fix commits into a1e59f1b8b0 so the merged history does not retain a known-bad intermediate implementation.

@PastaPastaPasta PastaPastaPasta left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

utACK 2629a3b

@knst knst requested a review from UdjinM6 July 9, 2026 19:34
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