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 4bbf58d): 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 9e97a97

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

📒 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 25d3e4a, 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 8e5b54a: 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 d8b9867. 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 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.

Prior Finding Reconciliation: prior fd245702 remains clean/no active findings; current-head inspection did not uncover evidence that changes that conclusion. Carried-forward prior findings: none. New findings in latest delta: none; the object_fetch early return matches the empty-filter object-fetch semantics and the added assertions cover the absence of vote-sync status messages. CodeRabbit had no actionable inline findings to validate or react to, and the targeted unit test could not be run because src/test/test_dash is not built in this worktree.

review_poster failed (1); posted exact-SHA body-only review.

@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/governance/net_governance.cpp`:
- Around line 129-131: The MNGOVERNANCESYNC handling in net_governance.cpp
returns early for object_fetch requests before relaying any object inventory,
which leaves empty-filter retries stalled. Update the object_fetch branch in the
governing sync flow so an empty filter still serves the object-fetch response
instead of returning immediately, and ensure the logic in the
MNGOVERNANCESYNC/object_fetch path only skips the normal relay work when
appropriate.
🪄 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: 65ba6ce4-0ace-44be-9da3-6e9b73274040

📥 Commits

Reviewing files that changed from the base of the PR and between fd24570 and f70dbd2.

📒 Files selected for processing (4)
  • src/governance/governance.cpp
  • src/governance/governance.h
  • src/governance/net_governance.cpp
  • src/test/governance_inv_tests.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/governance/governance.h
  • src/governance/governance.cpp

Comment thread src/governance/net_governance.cpp
@thepastaclaw thepastaclaw force-pushed the fix/governance-vote-sync-throttle branch from f70dbd2 to 8b0ec1d Compare July 8, 2026 16:38
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the latest CodeRabbit object-fetch feedback in 8b0ec1d4c76:

  • empty-filter nonzero MNGOVERNANCESYNC now queues a targeted MSG_GOVERNANCE_OBJECT inventory to the requesting peer when the object is known
  • object-fetch requests still return before GetSyncableVoteInvs(), so they do not scan votes, set fulfilled-request state, or penalize duplicates
  • the focused governance test now deserializes queued inv messages to assert the object-fetch response, while preserving the no-SYNCSTATUSCOUNT and no-misbehavior checks

Validation:

git diff --check
COMMIT_RANGE=HEAD^..HEAD test/lint/lint-whitespace.py
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

@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 "=== net_governance.cpp MNGOVERNANCESYNC block ==="
rg -n -C 40 'MNGOVERNANCESYNC|object_fetch|track_request|HaveSyncableObjectForHash|SYNCSTATUSCOUNT|PeerMisbehaving|MSG_GOVERNANCE_OBJECT' src/governance/net_governance.cpp

echo "=== test file relevant sections ==="
rg -n -C 15 'object_fetch|MSG_GOVERNANCE_OBJECT|inv|SYNCSTATUSCOUNT' src/test/governance_inv_tests.cpp | head -200

Length of output: 23384


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C 20 'per_object_vote_sync_is_fulfilled_request_limited' src/test/governance_inv_tests.cpp | sed -n '1,400p'

Length of output: 2175


🏁 Script executed:

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

Length of output: 9274


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -A10 'bool CGovernanceManager::HaveObjectForHash' src/governance/governance.cpp
rg -n -A10 'bool CGovernanceManager::HaveSyncableObjectForHash' src/governance/governance.cpp
rg -n -A6 'void CGovernanceManager::AddGovernanceObjectForTesting' src/governance/governance.cpp

Length of output: 1405


Everything checks out. The implementation and test coverage in 8b0ec1d4c76 correctly address the object-fetch feedback:

  • In Line 129-134 of src/governance/net_governance.cpp, object_fetch requests now check m_gov_manager.HaveObjectForHash(nProp) and, when known, push a targeted MSG_GOVERNANCE_OBJECT inv via PeerPushInventory before returning early — so they still skip track_request/fulfilled-request bookkeeping and never reach GetSyncableVoteInvs().
  • The track_request predicate (Line 112) is unchanged: full_sync || (!object_fetch && HaveSyncableObjectForHash(nProp)), so this new inv-push doesn't leak into fulfilled-request state.
  • In src/test/governance_inv_tests.cpp, the new CountQueuedInventory helper deserializes queued inv messages, and the syncable_object_fetch_stream/duplicate_syncable_object_fetch_stream cases confirm exactly one MSG_GOVERNANCE_OBJECT inv is queued on the first empty-filter request for a known object and none on the duplicate, while HasFulfilledRequest stays false and SYNCSTATUSCOUNT/misbehavior remain untouched in both cases.
  • The unknown-hash object-fetch case (object_fetch_hash) still correctly results in no inv (since HaveObjectForHash returns false), no fulfilled-request tracking, and no misbehavior penalty.

This looks good to me — the object-fetch response now correctly serves the requesting peer without introducing throttling side effects.

✅ 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: 8b0ec1d4c7

ℹ️ 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
@thepastaclaw thepastaclaw force-pushed the fix/governance-vote-sync-throttle branch from 8b0ec1d to 0eb6d88 Compare July 8, 2026 16:45
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the latest current-head Codex feedback in 0eb6d88697c:

  • empty-filter object-fetch replies now push a direct INV response to the requesting peer, bypassing known-inventory suppression
  • object-fetch requests still return before vote-sync scanning and remain unfulfilled-request-tracked/unpenalized
  • the focused governance test now asserts repeated known-object empty-filter fetches each queue the object INV while still sending no SYNCSTATUSCOUNT

Validation:

git diff --check HEAD^..HEAD
COMMIT_RANGE=HEAD^..HEAD test/lint/lint-whitespace.py
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 "=== net_governance.cpp MNGOVERNANCESYNC block ==="
rg -n -C 45 'MNGOVERNANCESYNC|object_fetch|track_request|HaveSyncableObjectForHash|SYNCSTATUSCOUNT|PeerMisbehaving|MSG_GOVERNANCE_OBJECT|PeerPushInventory|PushInventory' src/governance/net_governance.cpp

echo "=== test file relevant section ==="
rg -n -C 15 'object_fetch|MSG_GOVERNANCE_OBJECT|SYNCSTATUSCOUNT|CountQueuedInventory' src/test/governance_inv_tests.cpp

Length of output: 27712


@thepastaclaw Confirmed — the object_fetch branch in Line 129-136 of src/governance/net_governance.cpp now pushes a direct INV{MSG_GOVERNANCE_OBJECT, nProp} via m_connman.PushMessage when HaveObjectForHash(nProp) is true, and returns before reaching track_request's AddFulfilledRequest/penalty logic or GetSyncableVoteInvs(). The test correctly validates:

  • syncable_object_fetch_stream queues exactly one matching INV (Line 324) with no SYNCSTATUSCOUNT (Line 326) and no fulfilled-request/misbehavior side effects.
  • duplicate_syncable_object_fetch_stream queues the INV again (Line 334), confirming repeated empty-filter fetches are not throttled, while still leaving HasFulfilledRequest false and misbehavior unchanged.
  • The non-empty filtered vote-sync path (Line 341-353) still correctly marks the request fulfilled and penalizes the duplicate with +20.
  • Unknown-hash and unknown object-fetch paths (Lines 376-406) remain untracked and unpenalized beyond the existing 20 from the prior duplicate.

This looks good to me — the object-fetch response now correctly serves the object to the peer on every retry without introducing throttling side effects, addressing the Codex feedback.

✅ 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 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 findings: none; I read the prior f70dbd2 review artifact and revalidated the clean state at current head 8b0ec1d. New findings in the latest delta: none; the object-fetch response now advertises the available governance object without marking the per-object vote-sync fulfilled key, and the duplicate suppression follows the existing peer inventory-known filter behavior. CodeRabbit had no actionable inline findings, and static diff checks passed; the unit test binary is not built in this worktree, so I did not run the new Boost test.

Note: posted as a COMMENT review because GitHub does not allow approving/requesting changes on my own PR via the normal review event. Fallback reason: review_poster_failed_rc_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: 0eb6d88697

ℹ️ 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
Comment on lines +130 to +133
if (m_gov_manager.HaveObjectForHash(nProp)) {
CNetMsgMaker msgMaker(peer.GetCommonVersion());
m_connman.PushMessage(&peer, msgMaker.Make(NetMsgType::INV,
std::vector<CInv>{CInv{MSG_GOVERNANCE_OBJECT, 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 Avoid advertising non-syncable governance objects

When an empty-filter fetch names an object we still have but have already marked deleted or expired, HaveObjectForHash() still returns true, so this new direct INV advertises it even though GetSyncableObjectInvs()/GetSyncableVoteInvs() deliberately suppress non-syncable objects. The requester can then GETDATA it via SerializeObjectForHash(), causing us to serve stale governance objects until cleanup; gate this response on the same syncable-object predicate, with any separate explicit handling needed for postponed objects.

Useful? React with 👍 / 👎.

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.

Addressed in 4bbf58db309. Empty-filter object-fetch replies now use HaveSyncableObjectForHash() before sending the direct MSG_GOVERNANCE_OBJECT INV, so postponed/deleted/expired objects are not advertised through this retry path. I also extended governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited to assert postponed empty-filter retries queue no object INV while remaining unfulfilled/unpenalized.

Validation:

  • git diff --check HEAD^..HEAD && git diff --check
  • COMMIT_RANGE=HEAD^..HEAD test/lint/lint-whitespace.py
  • ./autogen.sh && ./configure --without-gui
  • 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

@thepastaclaw

Copy link
Copy Markdown
Author

CI triage note for the old linux64-test / Test source failure on run https://github.com/dashpay/dash/actions/runs/28901391714/job/85743984063:

The failing test was feature_dip3_v19.py, ending in dynamically_add_masternode(evo=True, rnd=7) with AssertionError: not(False == True). That path is outside this PR's governance vote-sync diff, and this PR does not modify feature_dip3_v19.py or the DIP3 masternode registration helper path. The occurrence matches the existing flaky-test tracker #6702, which I updated with this CI log.

No branch change is appropriate for that failure; the PR branch is proper as-is for this unrelated CI result.

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

@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: 4bbf58db30

ℹ️ 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
@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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants