Skip to content

test(drive-abci): pin that a token config update cannot set a perpetual distribution - #4836

Merged
QuantumExplorer merged 1 commit into
v4.2-devfrom
claude/vigorous-liskov-77f22f
Sep 19, 2026
Merged

QuantumExplorer merged 1 commit into
v4.2-devfrom
claude/vigorous-liskov-77f22f

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 19, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

While fixing the missing distribution storage for tokens added by a contract update (#4834), a sibling gap was suspected: a TokenConfigUpdate carrying TokenConfigurationChangeItem::PerpetualDistribution(..) goes through ApplyContract into update_contract, and nothing on that path creates or refreshes [Tokens, distributions, perpetual, token_id], because Drive only writes that storage when the token is created.

Investigation result: the Drive-side hazard is real, but it is not reachable, so there is nothing to fix in consensus code.

  • TokenConfigUpdateTransition::validate_structure v0 refuses every PerpetualDistribution(_) change item with UnsupportedFeatureError. It is called from batch basic structure validation, only v0 exists, and every protocol version selects it, including 14.
  • That gate came in with feat(dpp)!: disable changes to perpetual distribution in token configuration #2627, which is part of v2.0.0. Only the v2.0.0-dev.1 and v2.0.0-rc.1 to rc.11 tags had tokens without it, so mainnet never accepted such an update.
  • The other route is closed as well: a data contract update refuses any change to an existing token's configuration (validate_update_tokens).
  • No other change item touches Drive token storage, and there is no change item for pre-programmed distributions.

The existing rs-dpp unit test covers the structure check in isolation. Nothing covered the whole flow, and nothing recorded that Drive relies on this gate. This PR adds that test.

What was done?

Added test_token_config_update_by_owner_setting_perpetual_distribution_is_unsupported to the token config update tests in drive-abci. It creates a token with no perpetual distribution whose perpetual_distribution_rules authorize the contract owner, then:

  1. submits a config update that sets a block based perpetual distribution and asserts an UnpaidConsensusError with BasicError::UnsupportedFeatureError (it fails at basic structure, before the identity contract nonce is bumped);
  2. asserts the stored contract keeps its version and still has no perpetual distribution;
  3. submits a perpetual claim and asserts an ordinary StateError::InvalidTokenClaimPropertyMismatch, not an internal error.

The doc comment on the test states what Drive depends on, so that whoever lifts the gate sees it.

For whoever lifts the gate later

To check that the hazard is real I disabled the gate locally (not part of this PR) and ran the same scenario. The config update succeeded, and the claim then failed with:

InternalError("storage: grovedb: invalid path: could not get key for parent of subtree for batch at path [0x10/0x20/@/<token_id>] for key 0xc0")

This is the same signature as the bug fixed in #4834. Lifting the gate needs, at minimum:

  • the config update path has to create, refresh or remove the perpetual distribution storage (add_perpetual_distribution v0 returns CorruptedCodeExecution when the tree already exists, so a change needs its own operation);
  • a decision on stored last claim moments when the RewardDistributionType changes: block height and timestamp are both 8 bytes and would be silently misread by moment_from_bytes, epoch is 2 bytes and would raise CorruptedDriveState;
  • a decision on the start moment: a claim with no stored last claim starts from the contract's creation cycle, so a distribution introduced later would pay out retroactively from contract creation;
  • validation of the new distribution function, which config update state validation does not perform today.

TOKEN_PERPETUAL_DISTRIBUTIONS_INFO_KEY has no reader (claims use the contract's token configuration), so a stale info item would be inert.

How Has This Been Tested?

cargo test -p drive-abci --lib test_token_config_update_by_owner_setting_perpetual_distribution_is_unsupported

Passes. The change is test only, inside drive-abci, so that build is also the compile check. The experiment with the gate disabled was run locally and fully reverted; the branch contains one commit touching one test file.

Breaking Changes

None. Test only.

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 added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added regression coverage confirming that token configuration updates cannot enable perpetual distribution.
    • Verified that unsupported updates leave the existing contract configuration unchanged.
    • Confirmed that subsequent perpetual distribution claims return the expected property-mismatch error.

…al distribution

Drive writes a token's perpetual distribution storage only when the token
is created (insert_contract). A TokenConfigUpdate goes through ApplyContract
with its token already present in the original contract, so nothing would
create [Tokens, distributions, perpetual, token_id] if a config update could
introduce a distribution, and the first claim would fail inside the grove
batch.

That path is not reachable: TokenConfigUpdateTransition::validate_structure
has refused every PerpetualDistribution change item with
UnsupportedFeatureError since #2627, which shipped before v2.0.0, and a
data contract update refuses any change to an existing token. The rs-dpp
unit test covers the structure check in isolation; this test runs the whole
flow on a token whose perpetual_distribution_rules authorize the owner:
the update is an unpaid basic rejection, the stored contract is unchanged,
and a later claim is an ordinary InvalidTokenClaimPropertyMismatch.

Whoever lifts the gate has to make the config update maintain the
distribution storage, and decide what happens to stored last-claim moments
when the RewardDistributionType changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

PR Hygiene

State: waiting-slot · commit 37732cf284268e84f1ebb6df505a7b1aa6735ce8

  • Waiting for one of five author review slots

Self-review is an author attestation that you have read the diff:
/self-reviewed — covers everything pushed so far; post it again after a new push.

This report does not bypass CI or repository protection rules.

@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 19, 2026
@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: dashpay/platform/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: fdb2b42f-506b-4434-b96a-8ce9c0b62e34

📥 Commits

Reviewing files that changed from the base of the PR and between 51183be and 37732cf.

📒 Files selected for processing (1)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The token configuration update tests now reject perpetual distribution settings, verify that the token contract remains unchanged, and confirm the expected error from a later perpetual claim.

Changes

Token configuration update validation

Layer / File(s) Summary
Perpetual distribution validation
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs
Added supporting imports and regression coverage for rejected perpetual distribution updates, preserved contract and distribution state, and the later InvalidTokenClaimPropertyMismatch claim result.

Priority: ⬇️ Low

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

Change: Other

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the added regression test and the specific behavior it verifies: a token configuration update cannot set a perpetual distribution.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

@thepastaclaw

thepastaclaw commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

⚠️ DEGRADED — Queued for automated review — 22nd in line, estimated start in ~5 h (commit 37732cf)
Estimated review time once started: ~25 min (two-phase automated review; median of recent runs).
The primary review models are currently out of quota; this review will run on stand-in models and be marked as degraded.

  • Request priority review — click to move this review to the front of the queue.

@codecov

codecov Bot commented Sep 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.18%. Comparing base (d09c15d) to head (37732cf).
⚠️ Report is 4 commits behind head on v4.2-dev.

Additional details and impacted files
@@             Coverage Diff              @@
##           v4.2-dev    #4836      +/-   ##
============================================
+ Coverage     76.96%   77.18%   +0.22%     
============================================
  Files          2963     2963              
  Lines        429535   429535              
============================================
+ Hits         330609   331557     +948     
+ Misses        98926    97978     -948     
Components Coverage Δ
dpp 74.49% <ø> (+0.31%) ⬆️
drive 78.52% <ø> (+0.22%) ⬆️
drive-abci 78.63% <ø> (+0.15%) ⬆️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 86.09% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 27.90% <ø> (+0.45%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@QuantumExplorer
QuantumExplorer merged commit 8a8cc13 into v4.2-dev Sep 19, 2026
25 checks passed
@QuantumExplorer
QuantumExplorer deleted the claude/vigorous-liskov-77f22f branch September 19, 2026 04:34
QuantumExplorer added a commit that referenced this pull request Sep 19, 2026
…ument-token-costs

#4826 landed on v4.2-dev as a squash whose tree is identical to the head this
branch already carried, so every conflict is resolved to this branch's side:
the squashed base plus the optional token cost changes. The merge brings in
nothing else but the token config update test of #4836.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants