Skip to content

A PreferContractOwner batch can still get Orchard verification for free (PV14) #5251

Open

Description

@shumkov

Follow-up to #4760, which closed the same hole for GasFeesPaidBy::ContractOwner and left this one open deliberately.

The gap

requests_gas_sponsorship() returns true for PreferContractOwner as well as ContractOwner, so the batch identity-minimum-balance pre-check treats both the same: the signer funds its principal plus the compute fee of the bundles the batch carries (processor/traits/identity_balance.rs, generation 1).

That reserve is what makes somebody chargeable for a verification whatever the outcome. It works for ContractOwner. For PreferContractOwner the fallback is the signer by design — fee validation deliberately falls through to them when the sponsor falls short — so when both the sponsor and the signer are short, the verification has already run and nobody can be charged. The refusal is unpaid, the nonce is untouched, and the same bytes stay valid.

#4760 narrowed the pre-check to require the compute fee from the signer, which covers the ordinary case. It does not cover a signer who holds the compute fee at pre-check time but is short of the full metered fee at settlement while the preferred sponsor is also short.

Why it was not fixed there

Closing it needs a second rule — the sponsor or the signer must cover the compute fee — and a decision about which consensus error the refusal carries. GasSponsorInsufficientBalanceError does not fit: for a preference nobody insisted, and its own documentation says nobody is charged. IdentityInsufficientBalanceError against the signer is the honest one, since the signer is the payer of last resort. Either way it is a new refusal path on a consensus path, not a patch, so it was left to its own change rather than invented at the end of a large PR.

Constraints worth knowing before starting

  • The rule that drops a sponsor when any sub-transition is replaced by a nonce bump lives in execution_event/mod.rs and is in the base, not introduced by feat(platform)!: token shielded pools #4760. It cannot be refined here without changing released behaviour.
  • BumpIdentityDataContractNonceActionV0 records only the identity, contract, nonce and fee multiplier, so a bump raised by a shielded payment cannot be told from any other one to gate a change on protocol version 14.
  • Protocol version 14 is unreleased, so this can still be fixed without a new generation.

Scope

  • decide the rule for PreferContractOwner: sponsor or signer must cover the compute fee before verification
  • decide which consensus error the refusal carries
  • a regression with an underfunded signer and an underfunded preferred sponsor, asserting the bundle is not verified

🤖 Generated with Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions