Skip to content

fix(net): throttle per-object governance vote sync requests - #7414

Merged
PastaPastaPasta merged 1 commit into
dashpay:developfrom
thepastaclaw:fix/governance-vote-sync-throttle
Jul 8, 2026
Merged

fix(net): throttle per-object governance vote sync requests#7414
PastaPastaPasta merged 1 commit into
dashpay:developfrom
thepastaclaw:fix/governance-vote-sync-throttle

Conversation

@thepastaclaw

Copy link
Copy Markdown

Issue being fixed or feature implemented

  • Per-object MNGOVERNANCESYNC vote requests were not recorded in NetFulfilledRequestManager, unlike full governance sync requests.
  • A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive.

What was done?

  • Add a fulfilled-request key for per-object vote sync requests: MNGOVERNANCESYNC-votes-<object hash>.
  • Return early and score repeat requests from the same peer/address.
  • Add unit coverage asserting the per-object request is registered as fulfilled.

How Has This Been Tested?

  • git diff --check upstream/develop..HEAD
  • COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py
  • Not run locally: src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited because this fresh worktree has no configured build/test binary.

Breaking Changes

None.

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 7, 2026

Copy link
Copy Markdown
Author

Review skipped (commit 4bbf58db): PR head moved to 5ad1ef1 before reviewer launch.

PastaPastaPasta
PastaPastaPasta previously approved these changes Jul 7, 2026

@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 9e97a979ce3be7d33767b5edf4da37e79ca0c48c

@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: 9e97a979ce

ℹ️ 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/governance/net_governance.cpp Outdated
m_peer_manager->PeerMisbehaving(peer.GetId(), 20);
return;
}
m_netfulfilledman.AddFulfilledRequest(peer.addr, vote_sync_request);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not cache arbitrary vote-sync hashes

With any nonzero random nProp that does not correspond to a governance object, this line still records a fulfilled request before GetSyncableVoteInvs() can return empty. Because the request key embeds the peer-controlled 256-bit hash and CNetFulfilledRequestManager stores every unique key until expiry, a single peer can send unlimited distinct hashes without hitting the repeat-request penalty and grow mapFulfilledRequests for the full expiry window. Gate the insertion on the object being known/syncable, or use a bounded per-peer throttle key.

Useful? React with 👍 / 👎.

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.

consider refactoring.

Now both if / else branches has m_netfulfilledman.HasFulfilledRequest() call.

Instead, call it externally once for both.

See my implementation: 2db9352

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This change centralizes governance object syncability checks, updates MNGOVERNANCESYNC to distinguish full sync, object-fetch retry, and per-object vote sync requests, and adds tests for duplicate-request handling, queued inventory output, and misbehavior scoring.

Sequence Diagram(s)

sequenceDiagram
  participant Peer
  participant NetGovernance
  participant CGovernanceManager
  participant NetFulfilledManager

  Peer->>NetGovernance: MNGOVERNANCESYNC
  NetGovernance->>CGovernanceManager: check syncable object / fetch eligibility
  NetGovernance->>NetFulfilledManager: check fulfilled request key
  alt already fulfilled
    NetGovernance->>Peer: PeerMisbehaving(20)
  else not fulfilled
    NetGovernance->>NetFulfilledManager: AddFulfilledRequest(...)
  end
Loading

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

Possibly related PRs

  • dashpay/dash#7397: Also changes NetGovernance::ProcessMessage for MNGOVERNANCESYNC vote-sync handling with CBloomFilter-based request logic.

Suggested reviewers: PastaPastaPasta, kwvg

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Title check ✅ Passed Concise and specific; it matches the main change to throttle per-object governance vote sync requests.
Description check ✅ Passed The description clearly matches the per-object vote-sync throttling and test coverage changes.
✨ 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.

🧹 Nitpick comments (1)
src/test/governance_inv_tests.cpp (1)

220-255: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test only covers the "not yet fulfilled" path.

The test verifies that a first-time per-object request correctly gets recorded via AddFulfilledRequest, but doesn't assert that a second identical request triggers PeerMisbehaving(peer.GetId(), 20) and returns early without re-processing vote invs — which is the actual throttling behavior this PR intends to fix. Consider extending the test to call ProcessMessage a second time with the same object_hash and verify the misbehavior score is bumped (e.g., via peerman's exposed banscore, if available in test scaffolding).


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cd41badb-02e0-47d8-b8ae-d33dce338021

📥 Commits

Reviewing files that changed from the base of the PR and between 82d1492 and 9e97a979ce3be7d33767b5edf4da37e79ca0c48c.

📒 Files selected for processing (2)
  • src/governance/net_governance.cpp
  • src/test/governance_inv_tests.cpp

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

Comment thread src/test/governance_inv_tests.cpp Outdated
Comment on lines +242 to +252
object_hash.ToString())};
BOOST_CHECK(!m_node.netfulfilledman->HasFulfilledRequest(peer.addr, vote_sync_request));

CDataStream stream{SER_NETWORK, PROTOCOL_VERSION};
stream << object_hash << CBloomFilter{};

NetGovernance net_gov(m_node.peerman.get(), *m_node.govman, *m_node.mn_sync,
*m_node.netfulfilledman, *m_node.connman);
net_gov.ProcessMessage(peer, NetMsgType::MNGOVERNANCESYNC, stream);

BOOST_CHECK(m_node.netfulfilledman->HasFulfilledRequest(peer.addr, vote_sync_request));

@knst knst Jul 7, 2026

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.

IMO this unit-test is very specific and not reliable for any refactoring because it tests very specific current implemntation rather than behaviour. It is hard dependency of netfulfilledman member but it test also high-level behaviour yet it's not a test of netfulfilledman.

Dunno, seems as having this regression test is worse than don't have it at all

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.

moreover, the test already has bugs - CI failed

Comment thread src/governance/net_governance.cpp Outdated
m_peer_manager->PeerMisbehaving(peer.GetId(), 20);
return;
}
m_netfulfilledman.AddFulfilledRequest(peer.addr, vote_sync_request);

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.

consider refactoring.

Now both if / else branches has m_netfulfilledman.HasFulfilledRequest() call.

Instead, call it externally once for both.

See my implementation: 2db9352

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

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

The production change matches the PR intent, but the new unit test does not actually exercise the added fulfilled-request throttling path. The fixture leaves masternode sync at GOVERNANCE, and NetGovernance::ProcessMessage() ignores MNGOVERNANCESYNC until sync is fully finished, so the final assertion fails instead of validating the new behavior.

🔴 1 blocking

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

- [BLOCKING] src/test/governance_inv_tests.cpp:248-250: Advance masternode sync before testing vote-sync throttling
  The fixture constructor calls `SwitchToNextAsset()` only once, which moves sync from BLOCKCHAIN to GOVERNANCE. That makes `IsBlockchainSynced()` true, but `IsSynced()` remains false. `NetGovernance::ProcessMessage()` returns immediately for `MNGOVERNANCESYNC` while `m_node_sync.IsSynced()` is false, so this test never reaches the new per-object fulfilled-request code and the following `HasFulfilledRequest()` check fails. Advance from GOVERNANCE to FINISHED before invoking `ProcessMessage()`, as the existing schedule test in this file already does for synced-only governance behavior.
  Suggested replacement:
    m_node.mn_sync->SwitchToNextAsset();
    BOOST_REQUIRE(m_node.mn_sync->IsSynced());

    NetGovernance net_gov(m_node.peerman.get(), *m_node.govman, *m_node.mn_sync,
                          *m_node.netfulfilledman, *m_node.connman);
    net_gov.ProcessMessage(peer, NetMsgType::MNGOVERNANCESYNC, stream);

Note: posted as a COMMENT review because GitHub does not allow approving/requesting changes on my own PR; the verified blocking finding is preserved above.

@knst knst left a comment

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.

CI failed

Comment thread src/test/governance_inv_tests.cpp Outdated
Comment on lines +242 to +252
object_hash.ToString())};
BOOST_CHECK(!m_node.netfulfilledman->HasFulfilledRequest(peer.addr, vote_sync_request));

CDataStream stream{SER_NETWORK, PROTOCOL_VERSION};
stream << object_hash << CBloomFilter{};

NetGovernance net_gov(m_node.peerman.get(), *m_node.govman, *m_node.mn_sync,
*m_node.netfulfilledman, *m_node.connman);
net_gov.ProcessMessage(peer, NetMsgType::MNGOVERNANCESYNC, stream);

BOOST_CHECK(m_node.netfulfilledman->HasFulfilledRequest(peer.addr, vote_sync_request));

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.

moreover, the test already has bugs - CI failed

@thepastaclaw thepastaclaw changed the title net: throttle per-object governance vote sync requests fix(net): throttle per-object governance vote sync requests Jul 7, 2026

@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: 25d3e4a04d

ℹ️ 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/governance/net_governance.cpp Outdated
if (m_netfulfilledman.HasFulfilledRequest(peer.addr, vote_sync_request)) {
LogPrint(BCLog::GOBJECT, "MNGOVERNANCESYNC -- peer already asked me for votes for %s\n",
nProp.ToString());
m_peer_manager->PeerMisbehaving(peer.GetId(), 20);

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 Don't penalize orphan-object retry requests

This duplicate penalty now applies to every nonzero MNGOVERNANCESYNC, but the same message is also emitted by the orphan-vote recovery path below (ProcessVote sets hashToRequest, then line 212 sends MNGOVERNANCESYNC(hashToRequest, empty filter) to ask the announcing peer for the missing parent object). If several orphan votes for the same new object arrive before the object does, the requester can legitimately repeat that same hash; each repeat is scored +20 here and reaches the 100 discouragement threshold after five duplicates, so normal propagation can get peers discouraged for following the existing orphan-recovery flow. Please distinguish/exempt the empty-filter object fetches or throttle only the filtered vote-sync requests.

Useful? React with 👍 / 👎.

@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the review feedback in 25d3e4a04d5:

  • advanced the unit test fixture from GOVERNANCE to fully synced before calling NetGovernance::ProcessMessage()
  • extended the test to send the duplicate per-object vote-sync request and assert the peer misbehavior score increases by 20
  • updated the PR title to fix(net): throttle per-object governance vote sync requests so semantic-title CI should pass

Local validation:

  • git diff --check upstream/develop..HEAD
  • COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py
  • src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited
  • src/test/test_dash --run_test=governance_inv_tests

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

@thepastaclaw Thanks for the update — I'll take a fresh look at commit 25d3e4a04d5, including the fixture change to fully-synced state and the added misbehavior-score assertion for duplicate per-object vote sync requests.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw
thepastaclaw force-pushed the fix/governance-vote-sync-throttle branch from 25d3e4a to 8e5b54a Compare July 7, 2026 18:25
@thepastaclaw

Copy link
Copy Markdown
Author

Handled the latest feedback and force-pushed the cleaned-up two-commit stack (d3a52812ee5, 8e5b54a26f7):

Local validation after rebuilding: ./src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited passes.

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the latest review feedback in bb9d4ccedcd:

  • govsync(hash, empty filter) is no longer fulfilled-request limited; that path is used for missing-object retries from orphan-vote recovery and should not penalize duplicate retries.
  • Filtered per-object vote sync is only fulfilled-request tracked when the object hash is already known, so arbitrary random hashes no longer get cached in mapFulfilledRequests.
  • Added coverage for all three paths: known-object filtered duplicate penalty, unknown filtered hash no-cache/no-penalty, and empty-filter object retry no-cache/no-penalty.

Validation:

git diff --check upstream/develop..HEAD
COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py
make -C src -j6 test/test_dash
src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited
src/test/test_dash --run_test=governance_inv_tests
src/test/test_dash --run_test=bloom_tests

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
git fetch origin pull/7414/head:pr7414 2>&1 | tail -5 || true
git checkout pr7414 2>&1 | tail -5 || true
sed -n '1,200p' src/governance/net_governance.cpp | grep -n "MNGOVERNANCESYNC" -A 60 | head -120

Length of output: 6654


🏁 Script executed:

#!/bin/bash
set -euo pipefail
grep -n "BOOST_AUTO_TEST_CASE\|HasFulfilledRequest\|AddFulfilledRequest\|misbehav\|filter" src/test/governance_inv_tests.cpp | head -80

Length of output: 2181


The refactor and test coverage look solid: track_request now correctly distinguishes full sync, known-object filtered vote sync (tracked/penalized), unknown-hash filtered requests (not cached, no penalty), and empty-filter object retries (not cached, no penalty) — matching the three scenarios described. The test case per_object_vote_sync_is_fulfilled_request_limited exercises all three paths with appropriate assertions on HasFulfilledRequest and misbehavior score.

@thepastaclaw Thanks for the update — this addresses the earlier concern about over-eager fulfilled-request tracking for orphan-vote retries and unknown-object filtered requests well. The logic in Line 93 (track_request) cleanly separates the three cases, and the added test coverage validates each path.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: bb9d4ccedc

ℹ️ 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/governance/net_governance.cpp Outdated
// Nonzero govsync with an empty filter is used to retry missing-object
// fetches for orphan votes. Only full sync and known-object filtered
// vote sync are fulfilled-request limited.
const bool track_request{full_sync || (!filter.IsEmpty() && m_gov_manager.HaveObjectForHash(nProp))};

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 Limit throttling to syncable governance objects

When the requested object is only in mapPostponedObjects (for example, a proposal waiting for collateral confirmations), HaveObjectForHash() makes this condition true, but CGovernanceManager::GetSyncableVoteInvs() only looks in mapObjects and returns no vote inventory for postponed objects (governance.cpp:622-624). The first filtered vote request is therefore cached as fulfilled even though no votes were served, so a retry from the same address after CheckPostponedObjects() promotes the object can be blocked/scored until the fulfilled-request entry expires. Please key this throttle on the same “syncable object” predicate used by the vote-inv path, not on postponed objects.

Useful? React with 👍 / 👎.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

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

Carried-forward prior finding prior-1 is STILL VALID at 8e5b54a26f79db561563f289ac5c65d85034d3ef: the second commit still repairs test setup introduced by the first commit. New findings in the latest delta: none beyond that carried-forward commit-stack hygiene issue. CodeRabbit had no concrete inline findings, so there are no reactions.

🟡 1 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/test/governance_inv_tests.cpp`:
- [SUGGESTION] src/test/governance_inv_tests.cpp:224-227: Squash the test setup repair into the throttling commit
  Commit 8e5b54a26f7 adds these lines to advance masternode sync from GOVERNANCE to FINISHED before calling `NetGovernance::ProcessMessage()`, but commit d3a52812ee5 already introduced this test without that setup. The fixture only advances sync to GOVERNANCE, and `ProcessMessage()` returns before handling `MNGOVERNANCESYNC` unless `IsSynced()` is true, so the first commit leaves the new unit test broken until the second commit repairs it. Squash this setup fix into d3a52812ee5, or rewrite the first commit so each commit in the final stack is self-contained and testable.

Comment thread src/test/governance_inv_tests.cpp

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

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

Incremental + cumulative review for bb9d4ccedc after prior review 8e5b54a26f7. CodeRabbit had no concrete inline findings, so there are no reactions.

Prior finding reconciliation:

  • prior-1 STILL VALID: the current stack still introduces per_object_vote_sync_is_fulfilled_request_limited in d3a52812ee5 and only adds the required masternode-sync setup in 8e5b54a26f7.

Carried-forward prior findings:

  • [SUGGESTION] src/test/governance_inv_tests.cpp:225-228: Squash the test setup repair into the throttling commit
    Commit d3a52812ee5 introduced the governance sync test without advancing masternode sync to FINISHED, but NetGovernance::ProcessMessage() returns before handling MNGOVERNANCESYNC unless IsSynced() is true. These lines were added later in 8e5b54a26f7, so the first commit remains a known-broken bisect point if the stack lands as-is. Squash this setup into d3a52812ee5, or rewrite the stack so the test is introduced only once it is self-contained.

New findings in latest delta:

  • [SUGGESTION] src/governance/net_governance.cpp:90-93: Throttle empty-filter requests for known objects
    The empty-filter exemption is only needed for missing-object retries, but it also applies when nProp is a locally known governance object. Those requests still fall through to GetSyncableVoteInvs(nProp, filter), which locks governance state and iterates the object's votes; with a default empty filter, CBloomFilter::contains() returns true immediately, so no inventory is sent but the vote file is still rescanned on every request. Limit unknown-object retries without letting known-object empty-filter requests bypass fulfilled-request tracking.
  • [SUGGESTION] src/governance/net_governance.cpp:90-107: Fold the govsync correction into the original fix
    Commit bb9d4ccedcd changes the behavior introduced by d3a52812ee5: the original throttling commit fulfilled every nonzero MNGOVERNANCESYNC hash, while this latest commit narrows tracking to full sync or known-object filtered vote sync. That is a correction to the same logical change, not a separate final behavior. Rewrite the stack so d3a52812ee5 contains the final throttling semantics and the matching test coverage is introduced in a self-contained commit.
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.

Carried-forward prior findings:
- [SUGGESTION] src/test/governance_inv_tests.cpp:225-228: Squash the test setup repair into the throttling commit
  Commit d3a52812ee5 introduced `per_object_vote_sync_is_fulfilled_request_limited` without advancing masternode sync to FINISHED, but `NetGovernance::ProcessMessage()` returns before handling `MNGOVERNANCESYNC` unless `IsSynced()` is true. These lines were added later in 8e5b54a26f7, so the first commit remains a known-broken bisect point if the stack lands as-is. Squash this setup into d3a52812ee5, or rewrite the stack so the test is introduced only once it is self-contained.

New findings in latest delta:
- [SUGGESTION] src/governance/net_governance.cpp:90-93: Throttle empty-filter requests for known objects
  The empty-filter exemption is only needed for missing-object retries, but it also applies when `nProp` is a locally known governance object. Those requests still fall through to `GetSyncableVoteInvs(nProp, filter)`, which locks governance state and iterates the object's votes; with a default empty filter, `CBloomFilter::contains()` returns true immediately, so no inventory is sent but the vote file is still rescanned on every request. Limit unknown-object retries without letting known-object empty-filter requests bypass fulfilled-request tracking.
- [SUGGESTION] src/governance/net_governance.cpp:90-107: Fold the govsync correction into the original fix
  Commit bb9d4ccedcd changes the behavior introduced by d3a52812ee5: the original throttling commit fulfilled every nonzero `MNGOVERNANCESYNC` hash, while this latest commit narrows tracking to full sync or known-object filtered vote sync. That is a correction to the same logical change, not a separate final behavior. Rewrite the stack so d3a52812ee5 contains the final throttling semantics and the matching test coverage is introduced in a self-contained commit.

Comment thread src/governance/net_governance.cpp Outdated
Comment thread src/governance/net_governance.cpp
@thepastaclaw
thepastaclaw force-pushed the fix/governance-vote-sync-throttle branch from bb9d4cc to d8b9867 Compare July 7, 2026 21:55
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the latest review feedback in d8b9867182e:\n\n- rewrote the PR branch to a single self-contained commit on current develop, folding the test setup repair and govsync correction into the original throttling change\n- fulfilled-request tracking now applies to full sync and any known-object per-object vote sync, including empty-filter requests for known objects\n- unknown-object retries remain untracked, and the unit test now covers filtered duplicate penalty, known-object empty-filter duplicate penalty, unknown filtered no-cache/no-penalty, and unknown empty-filter no-cache/no-penalty\n\nValidation:\n\nbash\ngit diff --check upstream/develop..HEAD\nCOMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py\nmake -C src -j6 test/test_dash\nsrc/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited\nsrc/test/test_dash --run_test=governance_inv_tests\n\n\n@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

@thepastaclaw Thanks for the update — I’ll review the latest changes in d8b9867182e, with attention to the known-object per-object sync throttling behavior and the expanded test coverage.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: d8b9867182

ℹ️ 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/governance/net_governance.cpp

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

Source: reviewers claude/general=opus(failed: extra usage quota), codex/general=gpt-5.5(completed), claude/dash-core-commit-history=opus(failed: extra usage quota), codex/dash-core-commit-history=gpt-5.5(completed); verifier=gpt-5.5 (Claude/opus verifier failed: extra usage quota)

Carried-forward prior findings: none remain valid at d8b9867182e7207d87c5d8dcaa07dda4b7f6bdd2. prior-1 and prior-3 were resolved by rewriting the branch to a single self-contained commit, and prior-2 was resolved because known-object requests are now tracked even when the peer sends an empty filter. New findings in the latest delta: none; CodeRabbit supplied no actionable inline findings.

Note: GitHub does not allow me to approve my own PR, so this clean result is posted as a COMMENT while preserving the exact-SHA review record.

@thepastaclaw
thepastaclaw force-pushed the fix/governance-vote-sync-throttle branch from d8b9867 to de0b70f Compare July 8, 2026 04:26
@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw
thepastaclaw force-pushed the fix/governance-vote-sync-throttle branch from 4bbf58d to 5ad1ef1 Compare July 8, 2026 17:35
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the latest Codex object-fetch feedback in 5ad1ef1b103:

  • added CGovernanceManager::HaveObjectForFetch() so empty-filter object-fetch replies include held postponed objects while still excluding erased/deleted/expired objects
  • kept non-empty per-object vote-sync throttling tied to HaveSyncableObjectForHash(), so postponed objects do not become fulfilled-request tracked before votes can be served
  • updated governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited to assert postponed empty-filter retries queue a direct MSG_GOVERNANCE_OBJECT INV on each retry with no fulfilled-request state, no SYNCSTATUSCOUNT, and no extra misbehavior

Validation:

git diff --check HEAD^..HEAD
COMMIT_RANGE=HEAD^..HEAD test/lint/lint-whitespace.py
env CCACHE_DISABLE=1 make -C src test/test_dash-governance_inv_tests.o test/test_dash -j4
src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited
src/test/test_dash --run_test=governance_inv_tests

@coderabbitai review
@codex review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
git fetch origin pull/7414/head:pr7414 2>&1 | tail -5 || true
git checkout pr7414 2>&1 | tail -5 || true
git log --oneline -3

echo "=== governance.h HaveObjectForFetch/HaveSyncableObjectForHash ==="
rg -n "HaveObjectForFetch|HaveSyncableObjectForHash|HaveObjectForHash" src/governance/governance.h

echo "=== governance.cpp implementations ==="
rg -n -B3 -A15 "bool CGovernanceManager::HaveObjectForFetch|bool CGovernanceManager::HaveSyncableObjectForHash|bool CGovernanceManager::HaveObjectForHash" src/governance/governance.cpp

echo "=== net_governance.cpp MNGOVERNANCESYNC block ==="
rg -n -C 50 "MNGOVERNANCESYNC" src/governance/net_governance.cpp | head -140

echo "=== test file postponed empty-filter section ==="
rg -n -C 20 "postponed.*empty|HaveObjectForFetch|object_fetch" src/test/governance_inv_tests.cpp | head -200

Length of output: 15639


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '230,305p' src/test/governance_inv_tests.cpp

Length of output: 3834


🏁 Script executed:

#!/bin/bash
set -euo pipefail
grep -n "postponed" src/test/governance_inv_tests.cpp
echo "---"
grep -n "CBloomFilter{}" src/test/governance_inv_tests.cpp
echo "---AddPostponedObject in governance.h/cpp---"
rg -n "AddPostponedObject" src/governance/governance.h src/governance/governance.cpp

Length of output: 2601


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '353,376p' src/test/governance_inv_tests.cpp

Length of output: 1892


@thepastaclaw Confirmed — commit 5ad1ef1 does exactly what's described:

  • CGovernanceManager::HaveObjectForFetch() (governance.cpp, Line 146-165) excludes erased objects via mapErasedGovernanceObjects, then checks both mapObjects and mapPostponedObjects through IsSyncableObject(...), so held-but-not-expired postponed objects are now correctly served on object-fetch retries.
  • net_governance.cpp Line 130 uses this new accessor in the object_fetch branch to push a targeted INV{MSG_GOVERNANCE_OBJECT, nProp} to the peer, while still returning before track_request/AddFulfilledRequest and before GetSyncableVoteInvs() — so this doesn't affect throttling state.
  • track_request (Line 112) is untouched, still gated on HaveSyncableObjectForHash() which only checks mapObjects, so postponed objects still correctly avoid being marked as fulfilled-request before votes can actually be served.
  • In the test, the new empty_filter_object case (Lines 356-375) adds a postponed object and verifies the empty-filter request queues exactly one matching MSG_GOVERNANCE_OBJECT INV on both the initial and duplicate request, with HasFulfilledRequest staying false, no SYNCSTATUSCOUNT queued, and misbehavior unchanged — correctly distinguishing this from the earlier non-empty-filter postponed-object case that remains untracked/unfulfilled as well.

This closes the gap where postponed objects weren't being served on retry. Looks good to me.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 5ad1ef1b10

ℹ️ 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".

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

utACK 5ad1ef1

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@PastaPastaPasta
PastaPastaPasta merged commit c168228 into dashpay:develop Jul 8, 2026
45 of 46 checks passed
@UdjinM6 UdjinM6 added this to the 24 milestone Jul 9, 2026
thepastaclaw added a commit to thepastaclaw/dash that referenced this pull request Jul 22, 2026
Backport prerequisite from dashpay#7387: expose RequestedHashCacheSizeForTesting()
and governance::RELIABLE_PROPAGATION_TIME so the v23.1.x unit-test migration
of governance inv cache coverage can observe ConfirmInventoryRequest /
CheckAndRemove expiration without scraping logs.

The full dashpay#7387 merge is intentionally not cherry-picked: v23.1.8 retains
p2p_governance_invs.py and only needs the unit-test fixture subset required
by later dashpay#7414/dashpay#7442 coverage.
thepastaclaw added a commit to thepastaclaw/dash that referenced this pull request Jul 22, 2026
Backport prerequisite for dashpay#7414/dashpay#7442: add the minimal governance inventory
unit-test fixture and NetGovernance::Schedule CheckAndRemove coverage that
dashpay#7387 introduced, without removing p2p_governance_invs.py from v23.1.x.

Covers ConfirmInventoryRequest request-cache expiration and the periodic
Schedule cleanup path used by later governance throttle/authorization tests.
thepastaclaw pushed a commit to thepastaclaw/dash that referenced this pull request Jul 22, 2026
…c requests

5ad1ef1 fix: throttle governance vote sync requests (PastaClaw)

Pull request description:

  ## Issue being fixed or feature implemented
  - Per-object `MNGOVERNANCESYNC` vote requests were not recorded in `NetFulfilledRequestManager`, unlike full governance sync requests.
  - A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive.

  ## What was done?
  - Add a fulfilled-request key for per-object vote sync requests: `MNGOVERNANCESYNC-votes-<object hash>`.
  - Return early and score repeat requests from the same peer/address.
  - Add unit coverage asserting the per-object request is registered as fulfilled.

  ## How Has This Been Tested?
  - `git diff --check upstream/develop..HEAD`
  - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py`
  - Not run locally: `src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited` because this fresh worktree has no configured build/test binary.

  ## Breaking Changes
  None.

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [x] 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)_

ACKs for top commit:
  UdjinM6:
    utACK 5ad1ef1

Tree-SHA512: 4d72826ddf3a5e1834281fb53a0c7af724ac97eba7a1a0cc73936641015215511c3cc9c409812cc8168be0523d53f2395d6e871f42ab0fcb36ed67404ab63a9e
thepastaclaw added a commit to thepastaclaw/dash that referenced this pull request Jul 22, 2026
Narrow exception from Dash dashpay#7387 for the v23.1.8 release history.

The full dashpay#7387 merge removes p2p_governance_invs.py after migrating
coverage to unit tests. v23.1.x still ships that functional test, so
only the prerequisite fixture/coverage subset is included here:

- expose RequestedHashCacheSizeForTesting() and
  governance::RELIABLE_PROPAGATION_TIME for unit observation of
  ConfirmInventoryRequest / CheckAndRemove
- add governance_inv_tests coverage for request-cache expiration and
  NetGovernance::Schedule periodic cleanup

Later dashpay#7414/dashpay#7442 build on these fixtures. p2p_governance_invs.py is
retained and updated with dashpay#7442.

Co-Authored-By: Claude <noreply@anthropic.com>
thepastaclaw pushed a commit to thepastaclaw/dash that referenced this pull request Jul 22, 2026
…c requests

5ad1ef1 fix: throttle governance vote sync requests (PastaClaw)

Pull request description:

  ## Issue being fixed or feature implemented
  - Per-object `MNGOVERNANCESYNC` vote requests were not recorded in `NetFulfilledRequestManager`, unlike full governance sync requests.
  - A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive.

  ## What was done?
  - Add a fulfilled-request key for per-object vote sync requests: `MNGOVERNANCESYNC-votes-<object hash>`.
  - Return early and score repeat requests from the same peer/address.
  - Add unit coverage asserting the per-object request is registered as fulfilled.

  ## How Has This Been Tested?
  - `git diff --check upstream/develop..HEAD`
  - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py`
  - Not run locally: `src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited` because this fresh worktree has no configured build/test binary.

  ## Breaking Changes
  None.

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [x] 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)_

ACKs for top commit:
  UdjinM6:
    utACK 5ad1ef1

Tree-SHA512: 4d72826ddf3a5e1834281fb53a0c7af724ac97eba7a1a0cc73936641015215511c3cc9c409812cc8168be0523d53f2395d6e871f42ab0fcb36ed67404ab63a9e
PastaPastaPasta added a commit to PastaPastaPasta/dash that referenced this pull request Jul 29, 2026
…it tests

Backport of dashpay#7387 (upstream merge da52293, cherry-picked with -m1). Included because dashpay#7414/dashpay#7442/dashpay#7450 modify src/test/governance_inv_tests.cpp, which this PR introduces; it also replaces the p2p_governance_invs.py functional test with equivalent unit-test coverage.

v23.1.x adaptations: (1) governance.h on this branch has no 'namespace governance' block at the top - added one containing only the RELIABLE_PROPAGATION_TIME constant this PR introduces (develop's SuperblockManager forward declaration does not exist here and was not brought along). (2) ProcessVoteAndRelay keeps this branch's 'override' specifier. (3) Makefile.test.include entry added without develop-only governance_superblock_tests.cpp. All other hunks unchanged from upstream.

(cherry picked from commit da52293e8d6ba51fca27a557f6efd83a439a4b70)
PastaPastaPasta added a commit to PastaPastaPasta/dash that referenced this pull request Jul 29, 2026
…c requests

5ad1ef1 fix: throttle governance vote sync requests (PastaClaw)

Pull request description:

  ## Issue being fixed or feature implemented
  - Per-object `MNGOVERNANCESYNC` vote requests were not recorded in `NetFulfilledRequestManager`, unlike full governance sync requests.
  - A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive.

  ## What was done?
  - Add a fulfilled-request key for per-object vote sync requests: `MNGOVERNANCESYNC-votes-<object hash>`.
  - Return early and score repeat requests from the same peer/address.
  - Add unit coverage asserting the per-object request is registered as fulfilled.

  ## How Has This Been Tested?
  - `git diff --check upstream/develop..HEAD`
  - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py`
  - Not run locally: `src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited` because this fresh worktree has no configured build/test binary.

  ## Breaking Changes
  None.

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [x] 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)_

ACKs for top commit:
  UdjinM6:
    utACK 5ad1ef1

Tree-SHA512: 4d72826ddf3a5e1834281fb53a0c7af724ac97eba7a1a0cc73936641015215511c3cc9c409812cc8168be0523d53f2395d6e871f42ab0fcb36ed67404ab63a9e
(cherry picked from commit c168228)
PastaPastaPasta added a commit to PastaPastaPasta/dash that referenced this pull request Jul 29, 2026
…c requests

5ad1ef1 fix: throttle governance vote sync requests (PastaClaw)

Pull request description:

  ## Issue being fixed or feature implemented
  - Per-object `MNGOVERNANCESYNC` vote requests were not recorded in `NetFulfilledRequestManager`, unlike full governance sync requests.
  - A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive.

  ## What was done?
  - Add a fulfilled-request key for per-object vote sync requests: `MNGOVERNANCESYNC-votes-<object hash>`.
  - Return early and score repeat requests from the same peer/address.
  - Add unit coverage asserting the per-object request is registered as fulfilled.

  ## How Has This Been Tested?
  - `git diff --check upstream/develop..HEAD`
  - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py`
  - Not run locally: `src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited` because this fresh worktree has no configured build/test binary.

  ## Breaking Changes
  None.

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [x] 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)_

ACKs for top commit:
  UdjinM6:
    utACK 5ad1ef1

Tree-SHA512: 4d72826ddf3a5e1834281fb53a0c7af724ac97eba7a1a0cc73936641015215511c3cc9c409812cc8168be0523d53f2395d6e871f42ab0fcb36ed67404ab63a9e
(cherry picked from commit c168228)
PastaPastaPasta added a commit to PastaPastaPasta/dash that referenced this pull request Jul 29, 2026
…c requests

5ad1ef1 fix: throttle governance vote sync requests (PastaClaw)

Pull request description:

  ## Issue being fixed or feature implemented
  - Per-object `MNGOVERNANCESYNC` vote requests were not recorded in `NetFulfilledRequestManager`, unlike full governance sync requests.
  - A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive.

  ## What was done?
  - Add a fulfilled-request key for per-object vote sync requests: `MNGOVERNANCESYNC-votes-<object hash>`.
  - Return early and score repeat requests from the same peer/address.
  - Add unit coverage asserting the per-object request is registered as fulfilled.

  ## How Has This Been Tested?
  - `git diff --check upstream/develop..HEAD`
  - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py`
  - Not run locally: `src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited` because this fresh worktree has no configured build/test binary.

  ## Breaking Changes
  None.

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [x] 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)_

ACKs for top commit:
  UdjinM6:
    utACK 5ad1ef1

Tree-SHA512: 4d72826ddf3a5e1834281fb53a0c7af724ac97eba7a1a0cc73936641015215511c3cc9c409812cc8168be0523d53f2395d6e871f42ab0fcb36ed67404ab63a9e
(cherry picked from commit c168228)
PastaPastaPasta added a commit that referenced this pull request Jul 30, 2026
24920a0 chore: prepare v23.1.8 release (pasta)
2194248 Merge #7348: fix: penalize oversized notfound messages (pasta)
f5c72c3 Merge #7347: fix: punish invalid dstx messages (pasta)
550caf7 Merge #7465: fix(qt): handle pixel-sized fonts when scaling widgets (pasta)
e203710 Merge #7419: fix(net): bound CoinJoin message vector intake (pasta)
5f5b960 Merge #7418: fix(net): bound signing message vector intake (Pasta)
7cc2cca Merge #7450: test: make governance vote fixtures wire-valid (Pasta)
f011c80 Merge #7440: fix(net): bound governance vote signature deserialization (Pasta)
4b4d96a Merge #7442: fix(net): authorize governance inv responses via the net-layer per-peer request tracker (Pasta)
f855b13 Merge #7444: fix(net): bound bloom message vectors before allocation (Pasta)
5b5c6fb Merge #7415: fix: bound pending sig share queue (Pasta)
9bbe808 Merge #7416: fix(net): bound quorum data response vectors (Pasta)
da42f50 Merge #7424: fix: bound ChainLock seen cache (Pasta)
5b310df Merge #7438: fix: bound SPORK signature deserialization (Pasta)
e118d0c Merge #7259: fix: dangling point to cj client (Pasta)
9921621 Merge #7439: refactor: add bounded vector deserialization (Pasta)
89bdf7c Merge #7414: fix(net): throttle per-object governance vote sync requests (Pasta)
44c396d Merge #7402: fix: bound pending recovered sig queue to prevent remote OOM (Pasta)
05cfe27 Merge #7351: fix: limit signing share sessions per peer (pasta)
3ef3a5b Merge #7408: fix: bound DKG contribution blob intake (pasta)
0ea6532 Merge #7387: test: migrate governance inv cache coverage to unit tests (Pasta)
8ffdf7f Merge #7398: backport: compact block relay hardening (bitcoin#26898, bitcoin#27626, bitcoin#27743, bitcoin#26969, bitcoin#29412, bitcoin#32646, bitcoin#33296) (Pasta)
2915142 backport: bitcoin#27608 - p2p: Avoid prematurely clearing download state for other peers (PastaClaw)
90b5473 Merge #7396: fix: run of circular-dependencies with python3.15 (Pasta)
b003cdc Merge #7395: ci: update GitHub Actions pins for Node 24 (pasta)
97c3dd1 Merge #7394: fix: stabilize par help text in manpages (pasta)
8f8616b Merge #7372: backport: bitcoin#32693: depends: fix cmake compatibility error for freetype (pasta)
48f72be Merge #7360: fix: empty platformP2PPort deprecated field in protx listdiff results (pasta)
a8cccff Merge #7298: fix(qt): keep PoSe score visible when hiding banned masternodes (pasta)

Pull request description:

  Release PR for Dash Core v23.1.8, a patch release on top of v23.1.7.

  Fast-forwards from `v23.1.x` (currently at `chore: prepare v23.1.7 release`), 29 commits, no merge commits, no conflicts.

  ## Contents

  Backports of PRs already reviewed and merged on `develop`:

  `#7259` `#7347` `#7348` `#7351` `#7298` `#7360` `#7372` `#7387` `#7394` `#7395` `#7396` `#7398` `#7402` `#7408` `#7414` `#7415` `#7416` `#7418` `#7419` `#7424` `#7438` `#7439` `#7440` `#7442` `#7444` `#7450` `#7465`

  Plus `backport: bitcoin#27608`, a single commit taken from Dash #7237 because #7398's compact-block hardening depends on it. The rest of that v0.26 batch is intentionally not included on v23.1.x. The commit is byte-identical to its reviewed counterpart inside #7237.

  And release preparation: version bump, regenerated man pages, release notes, archived 23.1.7 notes.

  ## Note for reviewers: this branch was rebuilt

  An earlier revision of this PR was discarded and the branch rebuilt from scratch. Review comments on the previous revision point at commits that no longer exist, though the feedback itself was carried over (see below).

  The reason: several commits titled `Merge #NNNN` in the earlier revision contained substantial code that exists nowhere upstream — apparently written from a description of each PR rather than ported from its diff. For example, `feature_llmq_simplepose.py` is byte-identical between v23.1.7 and `develop`, yet the earlier `Merge #7408` rewrote 66 lines of it; `test/functional/p2p_governance_invs.py` does not exist on `develop` at all, yet had grown from 62 to 148 lines.

  That mislabeling matters because a commit titled `Merge #NNNN` invites less scrutiny, not more. It also had consequences: the earlier revision was **missing #7440 entirely**, and contained eleven consecutive commits that did not compile (code written against newer upstream APIs this branch does not have — `Misbehaving(Peer&)`, and `PeerIsBanned` used five commits before it was declared).

  Every commit on this branch has now been diffed against its upstream merge commit. Where a backport differs, it is because v23.1.x predates an upstream refactor and the change had to be applied to the pre-refactor file — for example #7418 and #7438 patch `signing_shares.cpp` / `spork.cpp` where upstream patches `net_signing.cpp` / `net_processing.cpp`.

  ## Dropped from this branch

  - **#7350** (`net: don't lock cs_main while reading blocks`) — dropped on review feedback. It is a 110-line lock-structure refactor of `ProcessGetBlockData` with no measured benefit, and it would add avoidable churn to the eventual master→develop merge-back. Nothing on this branch depends on it: #7398's compact-block work precedes it, and the remaining 14 commits replay with zero conflicts once it is removed. Thanks @knst.

  ## Added after the initial review pass

  - **#7351** (`fix: limit signing share sessions per peer`) — cherry-picked as a single
    commit and placed before #7402, matching upstream's merge order. The include block
    additionally carries `<ranges>`: upstream's diff adds only `<algorithm>` because develop
    already had it, whereas v23.1.x did not and the backported `GetSessionCount()` /
    `GetAnnouncementSessionCount()` use `std::ranges::count_if`.
  - **#7465** (`fix(qt): handle pixel-sized fonts when scaling widgets`) — cherry-picked from
    the five upstream commits. `optiontests.cpp` additionally includes `qt/guiutil_font.h`,
    because `fontsLoaded()` and `updateFonts()` are declared there on v23.1.x while develop
    declares them in `qt/guiutil.h`, which is all the upstream test includes.

  Two further backports were added later and applied without any adaptation --
  their diffs are byte-for-byte identical to upstream:

  - **#7347** (`fix: punish invalid dstx messages`)
  - **#7348** (`fix: penalize oversized notfound messages`)

  ## Adaptations worth flagging

  - **#7360** — upstream gates `platformP2PPort` / `platformHTTPPort` in `protx listdiff` behind `IsServiceDeprecatedRPCEnabled()`. On 23.x those deprecated fields are deliberately not enforced through gating (see `bbcd9d543e6`), so shipping the gate as-is would silently drop two fields that v23.1.7 always returned. Changed to `if (true)` with a comment, per review feedback, keeping the block aligned with `develop`. The substantive fix from #7360 — reading the live port from `netInfo` instead of the always-zero scalar — is retained.

  - **#7415** — the pending-map caps (`MAX_PENDING_SIG_SHARES_PER_NODE`, `MAX_PENDING_SIG_SHARES_TOTAL`) are backported. The additional bound upstream places on batches awaiting verification is not, because it guards a condition that does not exist here: upstream's dispatcher pushes one task per batch inside an inner loop, whereas v23.1.x pushes a single looping worker per 10 ms tick. There is no unbounded task queue to bound.

  - **Man pages** — regenerated without the `lock` debug category, which only exists under `DEBUG_LOCKCONTENTION` and so is absent from release binaries. Thanks @UdjinM6 for catching this.

  ## Known CI failure

  macOS jobs are expected to fail. `actions/upload-artifact@v6` rejects filenames containing `:`, and the Xcode SDK ships Perl man pages with `::` in the name. A release-branch-only workaround existed on the earlier revision but was dropped as it corresponds to no upstream PR. This is accepted for this release.

  ## Testing

  - Every commit through #7465 compiles individually (verified for 27 of the 29; the three additions below were verified at the tip) — verified individually, not just at the tip.
  - Full build clean; no new warnings.
  - Unit tests pass.
  - Functional tests pass: `feature_llmq_signing` (both variants), `feature_llmq_chainlocks`, `feature_llmq_dkgerrors`, `feature_llmq_is_cl_conflicts`, `p2p_instantsend`, `feature_dip3_deterministicmns` (both wallet types), `rpc_coinjoin`.
  - Qt unit tests pass (32 cases, run under the `cocoa` platform plugin so the pixel-sized
    font regression from #7465 actually executes rather than self-skipping).
  - Lint: one pre-existing `lint-cppcheck-dash` failure, identical on v23.1.7, in files this branch does not touch.

Top commit has no ACKs.

Tree-SHA512: 0fa469c9a33820aa85fbb8b90c5877409d09490f746f1300b05ceda470a600765f900bec42e5aad5d90a2d46b44e28c20e44dc4a8fe719553a072298069eaec4
@UdjinM6 UdjinM6 modified the milestones: 24, 23.1.8 Jul 30, 2026
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