Skip to content

fix(platform-wallet): derive the shield fee reserve from the versioned fee - #4366

Merged
llbartekll merged 1 commit into
codex/fix-platform-to-shielded-maxfrom
claude/shield-fee-reserve-versioned
Aug 11, 2026
Merged

fix(platform-wallet): derive the shield fee reserve from the versioned fee#4366
llbartekll merged 1 commit into
codex/fix-platform-to-shielded-maxfrom
claude/shield-fee-reserve-versioned

Conversation

@QuantumExplorer

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

Targets #4360's branch. The preflight/planner introduced there computes can_shield, max_shieldable_credits, and the input-0 viability threshold from the fixed SHIELDED_SHIELD_FEE_RESERVE_CREDITS = 1_000_000_000 reserve. That value is ~6× the fee the network actually charges a Type 15 shield (metered note/nullifier storage/processing + compute_shielded_verification_fee(2) ≈ 1.65e8 credits at current constants), which turns internal slop into wrong host-visible capacity:

  • Any account whose funded addresses each hold ≤ 1e9 credits (0.01 DASH) reports can_shield == false with zero capacity, regardless of aggregate balance. Platform payment accounts accumulate many small per-payment addresses, so this shape is the norm, and the loss is unbounded.
  • Max understates real capacity by ~8.3e8 credits, and after a Max shield input 0 retains reserve − actual fee ≈ 8.3e8 credits — below the 1e9 viability threshold — so every account that shields Max converges to a permanently unshieldable transparent residue.

The reserve's only real job is covering the execution-side fee that drive deducts from input 0's post-reallocation residue (DeductFromInput(0)). The structure gate (Σ claims ≥ amount + fee) is satisfied by the claimed fee reserve_shield_fee_on_input_0 loads, which is already versioned-exact — an oversized unclaimed reserve contributes nothing there.

What was done?

  • Replaced the constant with shield_fee_reserve_credits(platform_version) = 2 × compute_minimum_shielded_fee(SHIELD_NUM_ACTIONS) in operations.rs, next to the action-count constant it depends on. The 2× keeps one full fee of headroom for the GroveDB metering the client cannot reproduce, and the value now tracks fee-constant bumps instead of freezing (at current constants: 325,702,400 credits, ~0.0033 DASH).
  • Threaded the reserve through plan_shield_inputs as a parameter, like the versioned min_input_amount / max_address_inputs the planner already takes from sdk.version(). ShieldedShieldPreflight.fee_reserve_credits and the FFI struct field now carry the versioned value; no FFI/Swift/Kotlin shape changes.
  • Updated the planner tests to derive the reserve from LATEST_PLATFORM_VERSION, keeping every scenario parametric; the real-account regression test now guards its own shape (leading address must stay below the reserve).
  • Extended the headroom test to bound the reserve from above (≤ 4× fee) so an oversized reserve can't silently reintroduce the capacity loss, and refreshed the stale ~1.2e8 fee comment (pre-bump value; it's ~1.63e8 at current constants).

How Has This Been Tested?

  • cargo test -p platform-wallet --features shielded --lib — 775 passed, including the 12 planner tests, 4 reserve tests, and the fetch-error mapping test.
  • cargo clippy -p platform-wallet -p platform-wallet-ffi --all-targets --all-features and no-feature cargo check for both crates — clean.
  • cargo fmt --all.

Breaking Changes

None on-wire. The SHIELDED_SHIELD_FEE_RESERVE_CREDITS export (added on this branch, unreleased) is replaced by the shield_fee_reserve_credits function; hosts should keep reading fee_reserve_credits from the preflight, which is unchanged in shape.

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

🤖 Generated with Claude Code

…d fee

The fixed 1e9-credit input-0 reserve was ~6x the actual charged fee
(metered storage/processing + compute, ~1.65e8 at current constants),
and the preflight promoted that slop into authoritative capacity
numbers: accounts fragmented into sub-1e9 addresses reported
can_shield=false regardless of aggregate balance, Max understated real
capacity by ~8.3e8 credits, and a Max shield left its residue below the
viability threshold, permanently unshieldable.

Replace the constant with shield_fee_reserve_credits(platform_version)
= 2 x compute_minimum_shielded_fee(SHIELD_NUM_ACTIONS), threaded through
plan_shield_inputs like the other versioned planner limits. The reserve
only has to cover the execution-side metered fee taken from input 0's
post-reallocation residue (the structure gate is satisfied by the
claimed fee reserve_shield_fee_on_input_0 loads, which is already
versioned-exact), so one extra fee of metering headroom suffices, and
the value now tracks fee-constant bumps instead of freezing.

The headroom test now also bounds the reserve from above (<= 4x fee) so
an oversized reserve can't silently reintroduce the capacity loss.

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

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3baf0c85-507b-456c-8630-a4fb6655840f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@thepastaclaw

thepastaclaw commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

🕓 Ready for review — next in queue (commit 0ba8231)
Queue position: 1/1
ETA: start ~08:10 UTC · complete ~08:21 UTC (median 11m across 30 recent reviews; 2 slots)
Queued 9m ago · Last checked: 2026-08-11 08:10 UTC

@llbartekll
llbartekll merged commit 1e691aa into codex/fix-platform-to-shielded-max Aug 11, 2026
5 checks passed
@llbartekll
llbartekll deleted the claude/shield-fee-reserve-versioned branch August 11, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants