feat(gas-keys): add DelegateV2 action types for gas-key meta transactions (1/3)#15904
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #15904 +/- ##
==========================================
- Coverage 69.76% 69.73% -0.03%
==========================================
Files 946 946
Lines 203016 203374 +358
Branches 203016 203374 +358
==========================================
+ Hits 141636 141825 +189
- Misses 56611 56777 +166
- Partials 4769 4772 +3
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:
|
ff04076 to
b37e34b
Compare
| pub enum DelegateActionV2Payload { | ||
| V2(DelegateActionV2) = 0, | ||
| } |
There was a problem hiding this comment.
The main reason to introduce this is so future extensions don't need to add a new delegate action type & SignableMessageType.
There was a problem hiding this comment.
this is a bit confusing as it seems like V2 in DelegateActionV2Payload is the same as V2 in DelegateActionV2. I suggest renaming it to VersionedDelegateActionPayload
There was a problem hiding this comment.
Pull request overview
Adds the new Action::DelegateV2 wire/view types and supporting plumbing across nearcore for gas-key meta transactions, while intentionally keeping execution disabled (validation rejects; apply fails gracefully) until the next PR in the stack.
Changes:
- Introduces
DelegateActionV2/SignedDelegateActionV2(+ versioned payload) and updates signing discriminant (NEP-611). - Extends action validation, cost/fee computation, and various match sites to recognize
DelegateV2. - Adds view-layer support (
ActionView::DelegateV2) and updates tooling/non-consensus components to tolerate/ignore the new variant.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tools/state-viewer/src/contract_accounts.rs | Adds DelegateV2 to action filtering/mapping for state-viewer. |
| runtime/runtime/src/pipelining.rs | Treats DelegateV2 like Delegate in the pipelining receipt prep logic. |
| runtime/runtime/src/lib.rs | Adds a graceful runtime apply failure for DelegateV2 (should be unreachable due to validation for now). |
| runtime/runtime/src/config.rs | Extends fee/cost/gas/deposit accounting to include DelegateV2 inner actions/signatures. |
| runtime/runtime/src/actions.rs | Allows permission/existence checks to handle DelegateV2. |
| runtime/runtime/src/action_validation.rs | Extends “only one delegate action” rule and explicitly rejects DelegateV2 until feature execution lands. |
| core/primitives/src/views.rs | Adds JSON view round-trip support via ActionView::DelegateV2. |
| core/primitives/src/transaction.rs | Makes TransactionNonce serde-serializable so it can be used in DelegateActionV2. |
| core/primitives/src/signable_message.rs | Adds NEP-611 discriminant and SignableMessageType::DelegateActionV2. |
| core/primitives/src/errors.rs | Adds gas-key related access-key errors and a nonce-index error kind. |
| core/primitives/src/action/mod.rs | Adds Action::DelegateV2, introduces Action::is_delegate, and includes DelegateV2 in PQ signature recursion. |
| core/primitives/src/action/delegate.rs | Implements the new delegate V2 types, versioned wrappers, and extends non-nesting guards/tests. |
| chain/rosetta-rpc/src/adapters/mod.rs | Temporarily ignores DelegateV2 in Rosetta adapter (TODO). |
| chain/client/src/pending_transaction_queue.rs | Treats DelegateV2 as deploy-like if its inner actions are deploy-like. |
Comments suppressed due to low confidence (1)
runtime/runtime/src/action_validation.rs:109
- This loop re-implements the “delegate-style” classification with an explicit
Delegate | DelegateV2pattern. SinceAction::is_delegate()was added specifically to centralize that classification (and keep future variants from being missed), it’s better to use it here too.
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.
b37e34b to
8bdd4df
Compare
| pub enum DelegateActionV2Payload { | ||
| V2(DelegateActionV2) = 0, | ||
| } |
There was a problem hiding this comment.
this is a bit confusing as it seems like V2 in DelegateActionV2Payload is the same as V2 in DelegateActionV2. I suggest renaming it to VersionedDelegateActionPayload
| ProtocolSchema, | ||
| )] | ||
| #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] | ||
| pub struct SignedDelegateActionV2 { |
There was a problem hiding this comment.
same here: VersionedSignedDelegateAction
| /// Convenience wrapper for common logic accessing fields on delegate actions | ||
| /// of different versions. | ||
| #[derive(Clone, Copy, Debug)] | ||
| pub enum VersionedDelegateAction<'a> { |
There was a problem hiding this comment.
nice, that is exactly what I meant 👍
| /// Convenience wrapper for common logic accessing signed delegate actions of | ||
| /// different versions. | ||
| #[derive(Clone, Copy, Debug)] | ||
| pub enum VersionedSignedDelegateAction<'a> { |
There was a problem hiding this comment.
nit: add ref suffix: VersionedSignedDelegateActionRef, also for VersionedDelegateAction
…15905) Second PR of the stack (on top of #15904). Wires up execution of `DelegateV2`: - `validate_delegate_action_key` dispatches on `TransactionNonce`: a plain nonce advances `access_key.nonce` (and still rejects gas keys), a gas key nonce range-checks `nonce_index` against `num_nonces` and advances the selected gas key nonce row. - The separate V1/V2 apply paths collapse into one `apply_delegate_action` over `VersionedSignedDelegateActionRef`. - Validation now accepts `DelegateV2` behind the dedicated `ProtocolFeature::DelegateV2`, replacing the inert rejection arm from the previous PR. Adds an end-to-end test-loop test of a gas-key meta transaction plus unit tests for the nonce routing.
Adds a 2.13.0 changelog entry for the new `DelegateV2` meta-transaction action (`ProtocolFeature::DelegateV2`, protocol version 85), which lets gas keys ([NEP-611](near/NEPs#611)) sign relayed meta transactions. ([#15904](#15904), [#15905](#15905), [#15906](#15906)) Sorry I forgot this as part of the feature.
First of a 3-PR stack adding gas-key support to meta transactions via a new
Action::DelegateV2. Replaces the extension-based stack (#15883, #15884, #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:
DelegateActionV2mirrorsTransactionV1: itsnonce: TransactionNonceselects either the access key nonce or one of a gas key's parallel nonces by index.VersionedDelegateActionPayload(wire enum, currently justV2) is the signed payload ofVersionedSignedDelegateAction. Future versions add a variant here instead of a newActionvariant, so the delegate nesting guard stays frozen, and the variant byte is covered by the signature so versions cannot be confused.DelegateV2signs under its own NEP-461 discriminant (NEP-611, gas keys), making V1 and V2 signing domains disjoint by construction.VersionedDelegateActionRef/VersionedSignedDelegateActionRefare borrowing wrappers for code handling V1 and V2 uniformly (theVersionedActionReceiptpattern).ProtocolFeature::DelegateV2(protocol version 85) gates the action independently ofProtocolFeature::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.