Skip to content

fix(platform)!: charge authenticated shield proof failures at PV14 - #5262

Open
shumkov wants to merge 6 commits into
v5.0-devfrom
fix/shield-paid-proof-failure
Open

shumkov wants to merge 6 commits into
v5.0-devfrom
fix/shield-paid-proof-failure

Conversation

@shumkov

@shumkov shumkov commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

Basic explanation

What this does: From protocol version 14, an address-authenticated Shield with a bad Orchard proof pays its failure fee and consumes its input nonces. Its principal stays in the addresses. A new signed Shield format separates this authorization from legacy transactions, which are refused unpaid after activation.

Value: Validators can retain an adequately funded bad proof as a paid failure, matching the other shielding transitions. Honest pending PV12/13 transactions cannot lose fees or nonces merely because activation changed the proof domain. CheckTx continues to keep bad proofs out of the mempool.

Risks: Consensus and wire-format changes at unreleased PV14. Pending Shield V0 transactions must be rebuilt and re-signed after activation; changing the tag alone cannot upgrade the old signatures. Historical PV12/13 bytes and execution are preserved. Current-head Shield/proposal tests pass; fresh CI and bot re-review are pending. The preceding run has an inherited Swift V0-proof fixture failure and a quorum-cache failure in the Node suite. The subsequent validation-read accounting finding is fixed in 15f4719a51.

Issue being fixed or feature implemented

Closes #5181. Based on v5.0-dev after #5014 merged. Also fixes the activation finding in the legacy-signature review: an unchanged, valid PV13 Shield must not become chargeable at PV14 without new address authorization.

What was done?

  • PV14 selects processor v1 and Shield transform v2. Authenticate and validate balances/nonces before checking the proof. On failure, restore principal and prepare only nonce updates.
  • Include the metered pool-balance/nullifier reads only in the failed-proof context, reserve the complete estimated failure fee F, sum funds A reachable through distinct signed fee-strategy payers, and cap the fixed penalty at min(configured_penalty, A - F). If A < F, refuse unpaid. Apply the penalty once, without the user fee increase. Duplicate-nullifier refusals stay unpaid and precede proof work.
  • Introduce Shield V1, choose it before signing, and set PV14 serialization bounds/default to 1. V0 is active only at PV12/13; raw decoding, PV14 processor entry, and transform v2 refuse it before paid work. The shared CheckTx proof predicate and processor v0 stay unchanged.
  • Update Rust builder dispatch, raw WASM constructor version selection, wallet activity extraction, and DAPI failed-proof budgeting for both formats. Update the book and PV14 change list. No database schema or fee schedule change.

In-place changes to shipped generations

  • Shield transform v0 and its reallocation helper: replace the concrete V0 parameter with the same input map and fee strategy, obtained through accessors. The allocation algorithm and every historical value remain identical; PV12/13 select transform v0 and cannot decode V1.
  • Shared validate_shielded_proof_v0: read the same V0 fields through accessors, retaining its empty extra preimage and all verification arguments. PV12/13 still select it. V1 is unreachable from their external decoding.
  • Shared action conversion and enum/accessor glue add V1 projections only; existing V0 arms and fields are preserved. The Shield dispatcher gains an existing validation-mode argument, which historical branches ignore. V0 payload/signing modules, processor v0, and shared is_allowed remain unchanged.

How Has This Been Tested?

Actual RED before the activation fix: an exact, genuinely valid PV13-built Shield executed historically, then lost 50,991,540 credits and its nonce at PV14. GREEN submits those identical signed bytes at PV12/13 and PV14; CheckTx, Recheck, committed block processing, and direct processor calls now refuse legacy authorization unpaid. A one-byte version retag fails address authentication, with balances/nonces/pool/notes/nullifiers unchanged. Fixed historical wire/signable SHA-256 hashes were captured before production edits.

Earlier local wire-format verification on 32c92fe3d4, with zero ignored in these targeted runs:

  • 55 Shield tests, including all eight paid-proof-failure cases, multiple independent signed payers in both fee orders, affordability, fee increase, replay, proof binding, and historical rollback/nullifier behavior.
  • 32 ShieldFromAssetLock tests; 1,231 DPP state-transition tests; 23 platform-version tests.
  • Real PrepareProposal, independent ProcessProposal, and FinalizeBlock paid-failure regression with sum-tree checks enabled.
  • 10 WASM Shield wrapper tests against a freshly built wasm32 artifact: explicit PV13/PV14/default format selection, supplied witnesses, JSON/object/binary round trips, and getters.
  • 18 DAPI proof-failure-budget tests, including both serialized Shield formats; 15 shielded wallet sync tests, including V1 live activity recording and real note decryption/recovery.
  • Formatting and whitespace checks passed. Independent consensus, accounting, and client code reviews are clean.

CI on the preceding head 32c92fe3d4 passed the full Rust workspace suite, workspace all-target/all-feature compilation and Clippy (--locked -- --no-deps -D warnings), formatting, wallet dependency closure, unused-dependency checks, JS package tests, WASM/browser unit tests, and all three Docker image builds. This covers the planned workspace compile/lint gate; no separate standalone cargo check was run for this head. Functional tests, all Dashmate E2E jobs, and both browser shards passed. The Node platform suite finished with 69 passing, 10 pending, and one failure: the identity document-after-top-up case could not verify its proof because the quorum hash was missing from the context-provider cache. This is not yet confirmed against a base-only run. No manual live-network Shield test was run.

Current-head accounting verification (15f4719a51): all 55 Shield tests and the real independent proposal/finalization regression passed, zero ignored. Actual RED before the correction: the failed event had zero validation-read operations where independent Drive reads required one. The same regression is GREEN after adding the unsurcharged read fee once, before estimating F. The independent oracle prices pool/nullifier reads separately from the prepared event, verifies exact inclusion and the complete nonce/authentication/read estimate before fee increase, and pins the old-affordable/full-fee-minus-one refusal. Existing maximum-action, multiple-payer, fee-increase and committed-state assertions remain green. The genuine successful-proof test verifies the exact flat compute fee and absence of an extra read surcharge. Formatting/whitespace and three independent code reviews are clean. Fresh CI for this head is queued; its results and the bot re-review are pending.

Inherited CI failure: Swift SDKMethodTests.testSimpleIdentityFetch replays a recorded protocol-9 GroveDB V0 proof, rejected by the unconditional V1 floor merged in #5294. The current base run fails the same test with the same error; the test, fixture, and identity-fetch paths are unchanged by this PR. Repair requires a fresh V1 proof and matching quorum-key fixture from a seeded Platform. It remains a separate base repair; proof verification and test assertions were not weakened here.

Breaking Changes

PV14 admits only Shield wire format 1 and changes bad-proof block acceptance and nonce/fee effects. Pending V0 Shields must be rebuilt and re-signed after activation. PV12/13 retain format 0 and their original behavior.

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
  • If I added or changed GroveDB structure, I described it in the area's structure.rs, regenerated grovedb-structure.json, and checked the structure viewer link posted on this pull request

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

PR Hygiene · 15f4719

  • Bots — coderabbitai ✓ · thepastaclaw 2 threads unresolved — resolve them
  • Self-review — post /self-reviewed
  • Within your 5 open PRs — this one is beyond the limit; it waits until one merges
  • Build failed
  • Approvals
    • files with no dedicated owner — you own it
    • rust-dapi (packages/rs-dapi/src/services/platform_service/shielded_proof_failure_budget.rs) — QuantumExplorer or lklimek
    • dpp — you own it
    • rs-drive-abci — you own it
    • rs-drive — you own it
    • rs-platform-wallet (packages/rs-platform-wallet/src/wallet/shielded/operations.rs, packages/rs-platform-wallet/src/wallet/shielded/sync/memo_roundtrip_tests.rs, packages/rs-platform-wallet/src/wallet/shielded/sync/ovk_builder_roundtrip_tests.rs and 1 more) — HashEngineering or ZocoLini or llbartekll or romchornyi

When every box is checked the PR Hygiene check passes and this can merge.

Summary by CodeRabbit

  • New Features

    • From protocol version 14, Shield transactions use wire format 1; format 0 remains supported only in versions 12 and 13. Legacy transactions are refused after activation without authentication or proof verification.
    • Funded Shield transactions with invalid proofs can be included as paid failures. Input funds are restored rather than added to the shielded pool, while the nonce is consumed and applicable fees and a capped penalty are charged.
    • Failures unable to cover the estimated base fee and duplicate-nullifier refusals remain unpaid. CheckTx rejects invalid proofs before mempool admission.
  • Documentation

    • Clarified Shield format activation, invalid-proof fees, and differences between CheckTx and block processing.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Review in 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: e7d5daee-93c7-4526-b063-4ed42673f917
📥 Commits

Reviewing files that changed from the base of the PR and between 5975278 and 15f4719.

📒 Files selected for processing (34)
  • book/src/fees/shielded-fees.md
  • book/src/versioning/feature-versions.md
  • packages/rs-dapi/src/services/platform_service/shielded_proof_failure_budget.rs
  • packages/rs-dpp/src/state_transition/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/state_transition_estimated_fee_validation.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/state_transition_like.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/state_transition_validation.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v1/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v1/state_transition_like.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v1/state_transition_validation.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v1/types.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v1/v1_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v1/version.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/version.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/processor/traits/shielded_proof.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/processor/v1/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v0/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v1/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield_from_asset_lock/tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/shield_paid_proof_failure_tests.rs
  • packages/rs-drive/src/state_transition_action/shielded/shield/transformer.rs
  • packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v3.rs
  • packages/rs-platform-version/src/version/v14.rs
  • packages/rs-platform-wallet/src/wallet/shielded/operations.rs
  • packages/rs-platform-wallet/src/wallet/shielded/sync/memo_roundtrip_tests.rs
  • packages/rs-platform-wallet/src/wallet/shielded/sync/ovk_builder_roundtrip_tests.rs
  • packages/rs-platform-wallet/src/wallet/shielded/sync/shield_decrypt_tests.rs
  • packages/wasm-dpp2/src/shielded/shield_transition.rs
  • packages/wasm-dpp2/tests/unit/ShieldTransition.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-platform-version/src/version/v14.rs

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


📝 Walkthrough

Walkthrough

Protocol version 14 activates Shield transition format V1. The validation pipeline defers Shield proof verification to a versioned transformer, which can charge eligible funded failures through a nonce-bump action. The change also updates client handling, compatibility checks, tests, and protocol documentation.

Changes

Shield V1 and paid proof-failure handling

Layer / File(s) Summary
Shield V1 transition contract and activation
packages/rs-dpp/src/state_transition/..., packages/rs-platform-version/src/version/...
Adds the V1 Shield transition type and its validation, signing, accessors, and version-specific activation. Format V0 remains active for protocol versions 12–13; V1 is active from version 14.
V1 construction and action integration
packages/rs-drive/src/state_transition_action/..., packages/rs-platform-wallet/src/wallet/shielded/..., packages/wasm-dpp2/src/shielded/...
Updates Shield action conversion, wallet accessors, and WASM transition construction and getters to support V1. The WASM constructor accepts an optional platform version and selects the configured Shield format.
Versioned validation and proof-failure processing
packages/rs-drive-abci/src/execution/validation/state_transition/..., packages/rs-platform-version/src/version/drive_abci_versions/...
Adds processor version 1 and Shield transformer version 2. In validator mode, a failed proof can produce a nonce-bump action and paid error when signed fee inputs cover the estimated base fee; insufficient funds and duplicate-nullifier refusals remain unpaid.
Compatibility, tests, and protocol documentation
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/..., packages/rs-drive-abci/tests/strategy_tests/test_cases/..., packages/rs-dapi/src/services/..., book/src/...
Adds tests for format selection, legacy V0 refusal after activation, paid and unpaid proof failures, and block commitment. The documentation describes the protocol version 14 fee behavior and Shield format bounds.

Priority: ⬆️ High

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

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant StateTransitionProcessor
  participant ShieldTransitionTransformerV2
  participant ShieldState
  StateTransitionProcessor->>ShieldTransitionTransformerV2: Transform Shield with validation mode
  ShieldTransitionTransformerV2->>ShieldState: Read pool balance and check nullifiers
  ShieldTransitionTransformerV2->>ShieldTransitionTransformerV2: Verify proof in validator mode
  alt Invalid proof and base fee is covered
    ShieldTransitionTransformerV2-->>StateTransitionProcessor: Nonce-bump action and paid proof error
  else Base fee is not covered
    ShieldTransitionTransformerV2-->>StateTransitionProcessor: Unpaid insufficient-funds error
  end
Loading

Suggested reviewers: thepastaclaw

Merge Risk: 🔵 Low · up to 15f47

From protocol version 14, a funded, authenticated Shield transition whose proof fails is charged a capped penalty, and its input nonces are consumed. Legacy-format Shields are refused without charge. The reported blocking issues appear addressed, and tests and CI pass. The remaining risk is whether the estimated failure fee exactly matches the fee actually deducted, so owners should confirm fee parity before activation.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 15f47

Protocol 14 introduces financial side effects for authenticated proof failures and requires pending legacy transactions to be rebuilt and re-signed. The inspected authorization and fee controls support the intended behavior, but deployment and failure-recovery assurance remains incomplete.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — A submitter or proposer can supply invalid proof data, but the inspected paid-failure path requires valid address witnesses and next nonces before producing financial state updates. Its direct mutation scope is the authenticated transparent input addresses: selected payers lose fees, input nonces are consumed, and no Shield action is emitted to move principal or create shielded state. Validation behavior is consensus-visible across participating validators.

Trust Boundaries and Controls

  • observed — V1 structure validation requires matching witness and input counts and a valid fee strategy, including payer-index and duplicate-step checks. Witness authentication precedes paid processing, while exact next-nonce validation provides the control against replay or competing transactions using a consumed nonce.
  • observed — Public failed-proof budgeting now counts Shield actions through an accessor supporting both V0 and V1. DAPI reserves source-based capacity before forwarding a broadcast, and Drive independently limits concurrent CheckTx proof verification. The scoped comparison found no V1-specific metering bypass; deployment guarantees for source identification remain unverified.

Resilience and Maintainability Implications

  • observed — Address nonce-bump updates use the shared Drive operation batch. Its application path uses the caller transaction or creates an owned transaction and commits it only after conversion and batch application succeed. This supports atomic address updates, but the inspected evidence does not establish end-to-end crash recovery or rollback after every possible outer execution failure.

Hardening Proposals

  • proposed — Extend security-invariant validation with multi-address paid failures, competing same-nonce transactions, and injected storage failures across proposal rejection and commit recovery. Assert that fees and nonces change together, rejected attempts leave no financial residue, and shielded state remains unchanged. This addresses an assurance gap rather than an observed defect.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.44% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 136 functions across 38 files. (2 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed [#5181] PV14 selects the new processor and Shield transform generations. The processor authenticates address witnesses and checks input balances and nonces before Shield proof work. On an invalid proo…
Out of Scope Changes check ✅ Passed The client, wallet, DAPI, serialization, documentation, and test changes support the Shield V1 format and paid-failure behavior. The processor's prefunded-specialized-balance check was flagged in the …
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: charging authenticated Shield proof failures starting at protocol version 14.
Full details: Docstring Coverage

Explanation

Docstring coverage is 65.44% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 136 functions across 38 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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 Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

🔍 Review in progress — actively reviewing now (commit 15f4719) · triage: critical
███████████░░░░░░░░░ 55% · about 10 min left · running for 11 min
✅ triage → ⏳ Phase 2 (6/6 lanes, 3 comparison still going) → ✅ Phase 1 → ▫️ verify 2 → ▫️ publish
Estimated from recent reviews of this tier · updated 00:47 UTC · live progress

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

📖 Book Preview built successfully.

Download the preview from the workflow artifacts.
To view locally: download the artifact, unzip, and open index.html.

Updated at 2026-10-06T00:05:54.494Z

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

Final validation — Phase 1 + Phase 2

Static verification of the complete PR range at head 7cb6ced found no actionable in-scope defects. The processor duplication follows the repository's explicit frozen-generation convention, and the affordability calculation matches fee deduction through guaranteed BTreeMap ordering and preserved input keys. No local builds or tests were run; the supplied exact-head CI snapshot reports Rust workspace tests passing, with the platform test suite and one browser shard still pending.

Review provenance

Source: reviewer 1: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 2: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); reviewer 6: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 7: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: critical by gpt-6.1-sol (effort low) — The new processor/v1/mod.rs and shield/transform_into_action/v2/mod.rs implement intricate consensus and funds-accounting changes that make authenticated bad-proof Shields charge fees and consume nonces while preserving principal under payer-strategy and affordability constraints.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 15% left, 5h 100% left), glm-5.3-flash (not used above high effort; tier asks max)
  • Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer

@shumkov

shumkov commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

/self-reviewed

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

Re-review — Final validation — Phase 1 + Phase 2

Reviewed the complete 12-file diff at exact head 4c1a125 and traced the surrounding authentication, proof-verification, fee-estimation, and execution paths; no blocking defects were found. The behavior is confined to PV14, preserves historical processing and CheckTx rejection, and reuses existing nonce and fee machinery. One non-blocking regression-coverage gap remains; validation was static, with no local builds or tests run, and the supplied exact-head CI snapshot shows all listed checks passing.

🟡 1 suggestion(s)

Review provenance

Source: reviewer 1: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 2: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); reviewer 6: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 7: gpt-6-astra (agent: phase2-reviewer, role: architecture-layering); reviewer 8: gpt-6-astra (agent: phase2-reviewer, role: platform-versioning); reviewer 9: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 10: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 11: gpt-6-astra (agent: phase2-reviewer, role: security-auditor); reviewer 12: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 13: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 14: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 15: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 16: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 17: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: critical by gpt-6.1-sol (effort low) — The new processor/v1/mod.rs and shield/transform_into_action/v2/mod.rs implement intricate consensus and funds-accounting changes governing bad-proof acceptance, nonce consumption, fee affordability, and signed payer strategies.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 15% left, 5h 100% left), glm-5.3-flash (not used above high effort; tier asks max)
  • Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
  • Fresh final gate: an independent Phase-2 review ran after iterative findings were reconciled
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — general (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — security-auditor (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer
  • Model comparison: every Phase-2 reviewer also ran on gpt-6-astra; the verifier weighed both sets without knowing which model wrote which
🤖 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 `packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs`:
- [SUGGESTION] packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs:3275-3277: Cover failure fees split across multiple signed payers
  The new paid-proof-failure tests use only one DeductFromInput step, including the multi-input affordability boundary and maximum-input cases. They therefore do not cover the new transform's aggregation across multiple signed payers or its agreement with sequential fee deduction when the first payer is exhausted. Add a committed failure case with two payers whose combined balance covers the estimated base fee plus the prepared penalty but neither can cover that charge alone, and order the strategy differently from the input map. Assert the prepared penalty, each address's deduction, and the consumed nonces. This pins the composition of the new affordability gate with the existing stable-index deduction machinery without implying that the current implementation is incorrect.

Comment on lines +3275 to +3277
AddressFundsFeeStrategy::from(vec![
AddressFundsFeeStrategyStep::DeductFromInput(payer_index),
]),

@thepastaclaw thepastaclaw Oct 4, 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.

✅ Withdrawn at 5975278f; see the replies below.

🟡 Suggestion: Cover failure fees split across multiple signed payers

The new paid-proof-failure tests use only one DeductFromInput step, including the multi-input affordability boundary and maximum-input cases. They therefore do not cover the new transform's aggregation across multiple signed payers or its agreement with sequential fee deduction when the first payer is exhausted. Add a committed failure case with two payers whose combined balance covers the estimated base fee plus the prepared penalty but neither can cover that charge alone, and order the strategy differently from the input map. Assert the prepared penalty, each address's deduction, and the consumed nonces. This pins the composition of the new affordability gate with the existing stable-index deduction machinery without implying that the current implementation is incorrect.

source: gpt-6-astra (phase2-reviewer: rust-quality)

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.

Resolved (re-reviewed at 56b03be7): Your new should_split_failed_proof_fees_across_signed_payers_in_strategy_order test independently signs both inputs and exercises both payer orders, requiring the actual charge to exceed either payer's individual balance. It checks the full prepared penalty, exact committed deductions, both consumed nonces, and unchanged pool balance, note count, and nullifier state, resolving the requested coverage.

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.

Withdrawn (re-reviewed at 5975278f): Your two-payer regression verifies both payment orders, the full prepared penalty, exact deductions, consumed nonces, and unchanged pool/nullifier state. I confirmed that the tests file is byte-identical at the prior reviewed head and this head, so I withdraw the earlier coverage request rather than crediting the restack with a new fix.

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

Re-review — Final validation — Phase 1 + Phase 2

Verified the complete 12-file diff at head 56b03be. The multi-payer regression resolves the prior coverage finding, but the new paid-failure path exposes valid pending PV12/13 Shields to fee deductions and nonce consumption after PV14 activation without reauthorization. This was a static review; Rust workspace tests and numerous other checks were still pending in the supplied exact-head CI snapshot.

🔴 1 blocking

Review provenance

Source: reviewer 1: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); reviewer 7: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 9: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 10: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 11: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 12: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: critical by gpt-6.1-sol (effort low) — The new processor/v1/mod.rs and shield/transform_into_action/v2/mod.rs implement intricate consensus-changing failure handling that calculates and charges fees across signed payers, consumes nonces, and preserves shielded-pool principal under PV14.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 15% left, 5h 100% left), glm-5.3-flash (not used above high effort; tier asks max)
  • Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
  • Fresh final gate: an independent Phase-2 review ran after iterative findings were reconciled
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer
🤖 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 `packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs`:
- [BLOCKING] packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs:94-104: Retire legacy Shield signatures before charging PV14 proof failures
  A valid Shield signed under PV12/13 reaches this branch with unchanged, valid address witnesses, but its Orchard signatures fail the PV14 signing domain. `shield_extra_sighash_data` returns an empty preimage for PV12/13 and `kind tag || funding digest` for PV14. Shield still has only transition version 0, PV14's serialization bounds admit version 0, and `StateTransition::active_version_range()` admits Shield from 12 through the latest version. Address witnesses authenticate `self.signable_bytes()` without a protocol-version binding, so they do not reject the unchanged legacy bytes.

  A malicious proposer can retain an observed, uncommitted PV13 Shield and include its exact bytes after PV14 activates. If its input nonces remain current, nullifiers are unused, and the signed payers have sufficient funds, this proof failure returns the nonce-bump action at lines 168–170. The resulting address-paid event deducts the metered fee plus up to 50,000,000 penalty credits and consumes the victim's input nonces without shielding anything. No forgery or reauthorization is needed. CheckTx rejection does not prevent direct proposal inclusion. At the PR base, the same proof failure returned an unpaid refusal from processor v0, so this PR newly introduces the loss.

  Introduce a distinct Shield transition version for the PV14 signing domain and reject legacy version 0 unpaid at activation, following the existing ShieldFromAssetLock version/decode protection; do not restore acceptance of unbound bundles. Add a regression that builds and signs a valid PV13 Shield, submits its unchanged serialized bytes under PV14 with current input nonces, and verifies unchanged balances and nonces.

Comment on lines +94 to +104
let extra_sighash_data =
shield_extra_sighash_data(&transition.inputs, platform_version)?;
if let Err(error) = reconstruct_and_verify_bundle(
&transition.actions,
FLAGS_OUTPUTS_ONLY,
-(transition.amount as i64),
&transition.anchor,
&transition.proof,
&transition.binding_signature,
&extra_sighash_data,
) {

@thepastaclaw thepastaclaw Oct 5, 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.

✅ Resolved at 32c92fe3; see the replies below.

🔴 Blocking: Retire legacy Shield signatures before charging PV14 proof failures

A valid Shield signed under PV12/13 reaches this branch with unchanged, valid address witnesses, but its Orchard signatures fail the PV14 signing domain. shield_extra_sighash_data returns an empty preimage for PV12/13 and kind tag || funding digest for PV14. Shield still has only transition version 0, PV14's serialization bounds admit version 0, and StateTransition::active_version_range() admits Shield from 12 through the latest version. Address witnesses authenticate self.signable_bytes() without a protocol-version binding, so they do not reject the unchanged legacy bytes.

A malicious proposer can retain an observed, uncommitted PV13 Shield and include its exact bytes after PV14 activates. If its input nonces remain current, nullifiers are unused, and the signed payers have sufficient funds, this proof failure returns the nonce-bump action at lines 168–170. The resulting address-paid event deducts the metered fee plus up to 50,000,000 penalty credits and consumes the victim's input nonces without shielding anything. No forgery or reauthorization is needed. CheckTx rejection does not prevent direct proposal inclusion. At the PR base, the same proof failure returned an unpaid refusal from processor v0, so this PR newly introduces the loss.

Introduce a distinct Shield transition version for the PV14 signing domain and reject legacy version 0 unpaid at activation, following the existing ShieldFromAssetLock version/decode protection; do not restore acceptance of unbound bundles. Add a regression that builds and signs a valid PV13 Shield, submits its unchanged serialized bytes under PV14 with current input nonces, and verifies unchanged balances and nonces.

source: gpt-6.1-sol (phase2-reviewer: security-auditor)

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.

Resolved (re-reviewed at 32c92fe3): Your signed V1 format and early V0 refusals now prevent legacy PV12/13 signatures from authorizing PV14 charges or nonce consumption. The activation regression exercises unchanged historically valid bytes through CheckTx, Recheck, committed processing, and direct processor entry, and verifies that changing only the format tag fails authentication unpaid.

Base automatically changed from claude/strange-elbakyan-00b175 to v5.0-dev October 5, 2026 15:09
@github-actions github-actions Bot added this to the v5.0.0 milestone Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai not yet · thepastaclaw requested changes — dismiss the review or push a fix, 1 thread unresolved — resolve it. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Oct 5, 2026
Select new processor and Shield transform generations at protocol 14. Restore principal on proof failure, reserve the estimated nonce-update fee, and cap the fixed penalty by the signed payer strategy. Unfunded failures stay unpaid; shipped protocol replay and CheckTx proof admission stay unchanged.

Test would have caught this in CI: RED before the fix (funded proof failure was unpaid), GREEN after. The underfunded boundary was also RED without the affordability guard (InternalError), GREEN with it. Verified 52 Shield tests, independent PrepareProposal/ProcessProposal/FinalizeBlock, 25 platform-version tests, all-feature all-target Clippy, and formatting.
Describe how processor v1 delegates Shield proof verification to the action
transformer and how transform v2 turns affordable proof failures into nonce
updates with fees and a bounded penalty while preserving principal.

Comment-only change with no behavior delta. Tests omitted because no
executable code changed; cargo fmt --all -- --check and git diff --check
passed, and the non-documentation source is byte-identical to the parent.
Commit an authenticated bad-proof Shield with two signed payers whose
combined balances cover the estimated fee and full penalty while neither
can cover the actual charge alone. Exercise both fee orders, including
reverse BTreeMap order, and verify exact deductions, consumed nonces,
and unchanged pool balance, notes, and nullifiers.

Validation: all 8 paid-proof-failure tests passed, zero ignored; formatting
and whitespace checks passed. A mutation counting only the first payer
failed the prepared-penalty assertion (22,287,880 versus 50,000,000);
restoring production code made the new test pass. Independent accounting,
consensus, and scope reviews were clean. No production behavior changed.
@shumkov
shumkov force-pushed the fix/shield-paid-proof-failure branch from 56b03be to 5975278 Compare October 5, 2026 15:15
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai not yet · thepastaclaw 1 thread unresolved — resolve it. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw requested changes on this head; dismiss the review or push a fix; thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

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

Re-review — Final validation — Phase 1 + Phase 2

Static verification at head 5975278 confirms one blocking activation issue: an unchanged, previously valid PV12/13 Shield can become a paid failure at PV14 without new sender authorization. The multi-payer coverage claim is withdrawn because the regression already existed at the prior reviewed head and exercises both payment orders with exact accounting. The supplied exact-head CI snapshot reports successful Rust workspace tests; PR Hygiene remains pending, and no local builds or tests were run.

🔴 1 blocking

1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

Review provenance

Source: reviewer 1: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 2: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); reviewer 6: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 7: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: critical by gpt-6.1-sol (effort low) — The new processor/v1/mod.rs and shield/transform_into_action/v2/mod.rs implement intricate consensus-changing failure handling involving fee affordability, signed payer ordering, principal restoration, and nonce consumption.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 15% left, 5h 100% left), glm-5.3-flash (not used above high effort; tier asks max)
  • Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer
🤖 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 `packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs`:
- [BLOCKING] packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs:94-104: Retire legacy Shield signatures before charging PV14 proof failures
  (existing thread: https://github.com/dashpay/platform/pull/5262#discussion_r4182548716)
  This verification changes the Orchard authorization context without establishing a corresponding transparent-signature activation boundary. PV12/13 select `credit_pool_bundle_binding: None`, so the client builder signs the bundle with empty extra sighash data. PV14 selects `Some(0)`, supplying the kind tag and funding-address digest here. However, `StateTransition::active_version_range` still admits Shield from PV12 through the latest version, PV14's Shield serialization bounds remain version 0 only, and address witnesses verify the unchanged `signable_bytes()` without a target protocol version.

  A proposer can retain a genuinely valid, uncommitted PV13 Shield and include its identical signed bytes after activation. With usable input nonces, absent nullifiers, and sufficient fee-payer funds, it passes transparent authentication and balance checks but fails Orchard authorization because the sighash changed. The new branch at lines 168–170 then returns a paid nonce-bump action, consuming the sender's nonces and deducting the metered fee plus the capped penalty without shielding any principal. The base processor returned this verification failure without an action; this PR newly makes it chargeable and retainable in a block. CheckTx rejection does not protect against direct proposal inclusion.

  Introduce a distinct signed Shield format for the PV14-bound generation and retire the legacy format before proof work or charging, following the existing ShieldFromAssetLock V0/V1 activation gate, or implement an equivalent explicit unpaid legacy refusal. Update the serialization bounds and client-builder selection while preserving PV12/13 execution; do not accept unbound bundles as successful PV14 shields. Add an activation regression that processes the exact bytes of a genuinely valid PV13-built Shield at PV14 and asserts unchanged balances and nonces.

Use a signed Shield V1 format for the bound proof domain and paid-failure policy. Refuse legacy V0 before authentication, fees, nonce changes, and proof work at activation; preserve PV12/13 bytes and behavior. Update builder, WASM, wallet activity, and DAPI proof-budget consumers.

Test would have caught this in CI: RED before fix, GREEN after. An exact valid PV13 transaction previously lost 50,991,540 credits and its nonce at PV14. The unchanged PV12/13 fixtures now execute historically and are refused unpaid after activation, including CheckTx/Recheck and direct processing. A one-byte format retag fails authentication unpaid. All 55 Shield tests and 10 fresh WASM wrapper tests pass; historical wire/signable hashes are fixed regression oracles. Independent consensus, accounting, and client reviews are clean.
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai not yet · thepastaclaw 1 thread unresolved — resolve it. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed labels Oct 5, 2026
@shumkov shumkov changed the title fix(drive-abci)!: charge authenticated shield proof failures fix(platform)!: charge authenticated shield proof failures at PV14 Oct 5, 2026

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

Re-review — Final validation — Phase 1 + Phase 2

The signed Shield V1 activation boundary and independently signed multi-payer regression address both prior findings. One blocking accounting issue remains in the new paid-failure path: validation-read costs never reach the fee estimate or execution event. This was a static review only; the supplied CI snapshot shows Rust and WASM checks passing, an independently confirmed inherited Swift failure, and two test-suite jobs still running.

🔴 1 blocking

Review provenance

Source: reviewer 1: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: ffi-engineer); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); reviewer 8: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 9: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 10: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 11: gpt-6.1-sol (agent: phase2-reviewer, role: ffi-engineer); reviewer 12: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 13: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 14: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: critical by gpt-6.1-sol (effort low) — The intricate changes in processor/v1/mod.rs and shield/transform_into_action/v2/mod.rs alter consensus-critical fee deductions and nonce consumption, while Shield V1 changes signed authorization and protocol-gated wire decoding.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 15% left, 5h 100% left), glm-5.3-flash (not used above high effort; tier asks max)
  • Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
  • Fresh final gate: an independent Phase-2 review ran after iterative findings were reconciled
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — ffi-engineer (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — architecture-layering (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — ffi-engineer (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — platform-versioning (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer
🤖 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 `packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs`:
- [BLOCKING] packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/transform_into_action/v2/mod.rs:137-141: Include validation-read costs in the paid Shield failure fee
  The pool-balance read and per-action nullifier lookups append metered costs to the local `drive_operations`, but this accumulator is never converted into an execution-context operation. Consequently, the new bad-proof path reserves and charges only the nonce-update batch and previously recorded authentication costs, plus the capped penalty. Unlike a successful `ShieldAction`, its `BumpAddressInputNoncesAction` receives no shielded compute fee containing the per-action lookup charge. This omits validation work from the base fee F: a payer can pass the affordability gate despite being unable to cover the complete metered base fee, and fully funded failures are undercharged. The boundary tests derive their estimate from the same incomplete execution event, so they cannot detect the omission. In the failed-proof branch, convert the accumulated reads through versioned `Drive::calculate_fee` and append a `ValidationOperation::PrecalculatedOperation` before estimating F; the execution event will then retain those costs too. Follow the handoff used by `shield_from_identity/transform_into_action/v0`. Preserve unpaid duplicate-nullifier refusals, historical generations, and successful Shield's existing flat per-action pricing rather than indiscriminately adding another read charge to successful actions.
Out-of-scope follow-up suggestions (1)

These are valid observations, but they are outside this PR's scope and should be handled in separate issues or author/maintainer-requested PRs rather than blocking this review.

  • Refresh the inherited Swift identity-fetch proof fixture — Out of scope — head job 111877989660 and base job 111857912433 both report rejection of GroveDB proof envelope version 0 because version 1 is required. The complete PR diff leaves the Swift tests, recorded fixtures, FFI identity-fetch implementation, and proof verifier unchanged. This is already documented in the PR as separate base maintenance, not an introduced Shield regression or an exceptional new follow-up.
    • Follow-up: Consider creating a separate issue or author/maintainer-requested PR for this.

Comment on lines +137 to +141
ValidationOperation::add_many_to_fee_result(
execution_context.operations_slice(),
&mut estimated,
platform_version,
)?;

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.

🔴 Blocking: Include validation-read costs in the paid Shield failure fee

The pool-balance read and per-action nullifier lookups append metered costs to the local drive_operations, but this accumulator is never converted into an execution-context operation. Consequently, the new bad-proof path reserves and charges only the nonce-update batch and previously recorded authentication costs, plus the capped penalty. Unlike a successful ShieldAction, its BumpAddressInputNoncesAction receives no shielded compute fee containing the per-action lookup charge. This omits validation work from the base fee F: a payer can pass the affordability gate despite being unable to cover the complete metered base fee, and fully funded failures are undercharged. The boundary tests derive their estimate from the same incomplete execution event, so they cannot detect the omission. In the failed-proof branch, convert the accumulated reads through versioned Drive::calculate_fee and append a ValidationOperation::PrecalculatedOperation before estimating F; the execution event will then retain those costs too. Follow the handoff used by shield_from_identity/transform_into_action/v0. Preserve unpaid duplicate-nullifier refusals, historical generations, and successful Shield's existing flat per-action pricing rather than indiscriminately adding another read charge to successful actions.

source: gpt-6.1-sol (phase2-reviewer: general, architecture-layering, ffi-engineer, platform-versioning, rust-quality, security-auditor)

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw requested changes on this head; dismiss the review or push a fix; thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed bot-review-skipped A required review bot did not report; it was skipped by the window or by a person. and removed waiting-bots Waiting for the review bots to report on this head labels Oct 5, 2026
Meter the pool-balance and nullifier reads in the PV14 failed-proof branch
before reserving the complete base fee and capping its fixed penalty. Keep
the same operation in the execution context for the committed charge.
Successful Shield keeps its existing flat compute fee; legacy and
nullifier refusals remain unpaid.

Strengthen the affordability oracle with independently priced Drive reads,
exact single inclusion and a nonce/authentication/read estimate assembled
before the ordinary fee increase. Pin successful fee composition too.

Test would have caught this in CI: ✖ before fix (0 read-fee operations,
expected 1), ✔ after fix on the same regression. All 55 Shield tests and
the independent proposal/finalization regression passed, zero ignored.
Formatting and three independent code reviews are clean.

Addresses the validation-read accounting review on #5262; fixes #5181.
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai not yet · thepastaclaw 2 threads unresolved — resolve them. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed bot-review-skipped A required review bot did not report; it was skipped by the window or by a person. labels Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-self-review Waiting for the author to post /self-reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A failed Shield proof is refused free although its payer is already proven

2 participants