feat(gas-keys): add DelegateV2 action type and nesting guard (1/3)#15883
feat(gas-keys): add DelegateV2 action type and nesting guard (1/3)#15883darioush wants to merge 9 commits into
Conversation
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new on-wire action variant Action::DelegateV2 (for upcoming gas-keys meta-tx support), wires it through workspace match sites, and strengthens the “no nested delegate actions” guard by centralizing delegate-variant classification.
Changes:
- Added
SignedDelegateActionV2+ extensibleDelegateActionExtension, and newAction::DelegateV2variant with schema / borsh nesting guard updates. - Threaded
DelegateV2through runtime validation/apply paths (currently rejected viaUnsupportedProtocolFeature) and fee/cost accounting recursion. - Added
ActionView::DelegateV2and minimal Rosetta adapter support mirroring existingDelegateoperations.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/state-viewer/src/contract_accounts.rs | Adds DelegateV2 to action-type classification for state viewer output. |
| runtime/runtime/src/pipelining.rs | Treats DelegateV2 like Delegate in receipt preparation pipeline matching. |
| runtime/runtime/src/lib.rs | Fails DelegateV2 gracefully in apply (returns UnsupportedProtocolFeature receipt-validation error). |
| runtime/runtime/src/config.rs | Extends fee/cost recursion to descend into DelegateV2 inner actions; adds regression test. |
| runtime/runtime/src/actions.rs | Includes DelegateV2 in permission/existence checks alongside Delegate. |
| runtime/runtime/src/action_validation.rs | Rejects DelegateV2 during validation (until execution lands) and includes it in “only one delegate action” rule. |
| core/primitives/src/views.rs | Adds ActionView::DelegateV2 view conversion (Action ⇄ ActionView). |
| core/primitives/src/errors.rs | Updates gas-key related access-key errors and introduces a new nonce-index error kind. |
| core/primitives/src/action/mod.rs | Adds Action::DelegateV2 and Action::is_delegate() as an exhaustive delegate-style classifier. |
| core/primitives/src/action/delegate.rs | Implements DelegateActionExtension, SignedDelegateActionV2, and extends nesting guard + schema filtering + tests. |
| chain/rosetta-rpc/src/adapters/mod.rs | Adds interim Rosetta operation mapping for DelegateV2 mirroring Delegate. |
| chain/client/src/pending_transaction_queue.rs | Ensures deploy-like detection recurses into DelegateV2 inner actions. |
Comments suppressed due to low confidence (1)
runtime/runtime/src/action_validation.rs:118
- This "single delegate action" guard is manually matching
Delegate/DelegateV2. SinceAction::is_delegate()was added as the exhaustive source of truth for delegate-style variants, using it here avoids future bugs if another delegate variant is introduced but this match isn’t updated.
if let Action::Delegate(_) | Action::DelegateV2(_) = action {
if found_delegate_action {
return Err(ActionsValidationError::DelegateActionMustBeOnlyOne);
}
found_delegate_action = true;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## darioush/gas-keys/reject-delegate-action #15883 +/- ##
============================================================================
- Coverage 69.90% 69.89% -0.01%
============================================================================
Files 945 945
Lines 202339 202448 +109
Branches 202339 202448 +109
============================================================================
+ Hits 141442 141503 +61
- Misses 56143 56180 +37
- Partials 4754 4765 +11
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
67e0a4c to
cc524e6
Compare
| ProtocolSchema, | ||
| )] | ||
| #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] | ||
| pub struct SignedDelegateActionV2 { |
There was a problem hiding this comment.
could you please elaborate on why extension approach was chosen instead of introducing DelegateActionV2 with embedded gas key support? Then you introduce VesionedDelegateAction enum and replace all DelegateAction usage in runtime code with that. That seems like a more straightforward approach
There was a problem hiding this comment.
The goal was to reduce duplication / boilerplate, and also avoid introducing a new signature distinguisher (SignableMessageType).
However I agree that introducing the VesionedDelegateAction is more consistent with the codebase.
This approach is attempted in this set of PRs: #15904 #15905 #15906 and I mark the prior set of PRs as draft for now.
Let me know if you prefer that approach.
…ions (1/3) (near#15904) First of a 3-PR stack adding gas-key support to meta transactions via a new `Action::DelegateV2`. Replaces the extension-based stack (near#15883, near#15884, near#15885) with the versioned design suggested in review there. Adds the wire types and the nesting guard, but no execution yet: validation rejects `DelegateV2` (`UnsupportedProtocolFeature`) and the apply path fails it gracefully. Execution lands in the next PR in the stack. Design: - `DelegateActionV2` mirrors `TransactionV1`: its `nonce: TransactionNonce` selects either the access key nonce or one of a gas key's parallel nonces by index. - `VersionedDelegateActionPayload` (wire enum, currently just `V2`) is the signed payload of `VersionedSignedDelegateAction`. Future versions add a variant here instead of a new `Action` variant, so the delegate nesting guard stays frozen, and the variant byte is covered by the signature so versions cannot be confused. - `DelegateV2` signs under its own NEP-461 discriminant (NEP-611, gas keys), making V1 and V2 signing domains disjoint by construction. - `VersionedDelegateActionRef`/`VersionedSignedDelegateActionRef` are borrowing wrappers for code handling V1 and V2 uniformly (the `VersionedActionReceipt` pattern). - A dedicated `ProtocolFeature::DelegateV2` (protocol version 85) gates the action independently of `ProtocolFeature::GasKeys`, so it can be pulled from the release on its own if needed. Includes `ActionView::DelegateV2`, cost/fee handling, and trivial match arms across the workspace. Protocol schema and openapi specs (1.2.11) are regenerated.
First of a 3-PR stack splitting the gas-key
DelegateV2work. (original non-splitted: #15877)Adds the
Action::DelegateV2wire type and its nesting guard, but does not execute it yet — validation rejectsDelegateV2(UnsupportedProtocolFeature) and the apply path fails it gracefully. Execution lands in the next PR in the stack.Includes:
SignedDelegateActionV2, the extensibleDelegateActionExtensionenum,Action::is_delegate(exhaustive, the single source of truth for the nesting guard, borsh reject set, and JSON schema filter),ActionView::DelegateV2, cost/fee handling, and the trivial match arms across the workspace. Rosetta left as TODO.