feat(gas-keys): charge gas from gas key balance, deposit from account#14969
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #14969 +/- ##
===========================================
+ Coverage 1.30% 68.84% +67.54%
===========================================
Files 725 919 +194
Lines 140594 201273 +60679
Branches 140594 201273 +60679
===========================================
+ Hits 1835 138569 +136734
+ Misses 138706 56739 -81967
- Partials 53 5965 +5912
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Implements the new gas-keys charging model by splitting transaction costs into gas vs deposit components, charging gas from the gas key balance while charging deposits from the signer account balance, and updating tests accordingly.
Changes:
- Extend
TransactionCostwithgas_costanddeposit_costcomputed incalculate_tx_cost. - Update gas key verification to deduct
gas_costfrom the gas key balance anddeposit_costfrom the account balance, addingNotEnoughGasKeyBalance. - Update runtime/test-loop tests to fund gas keys and assert the split balance effects.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test-loop-tests/src/tests/gas_keys.rs | Funds gas keys in test-loop and asserts deposit vs gas charging split using RPC views/outcomes. |
| runtime/runtime/src/verifier.rs | Changes gas key verification to mutate access key balance and charge split costs; adds/updates tests. |
| runtime/runtime/src/tests/apply.rs | Updates apply test to fund gas key and assert account/deposit vs gas-key/gas cost split; uses tx_cost. |
| runtime/runtime/src/config.rs | Adds gas_cost/deposit_cost to TransactionCost and computes them in calculate_tx_cost. |
| core/primitives/src/views.rs | Adds helpers for reading gas key balance from permission view and summing tokens burnt in outcomes. |
| core/primitives/src/errors.rs | Adds InvalidTxError::NotEnoughGasKeyBalance and its Display formatting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <[email protected]>
| Ok(TransactionCost { gas_burnt, gas_remaining, receipt_gas_price, total_cost, burnt_amount }) | ||
| let gas_cost = safe_add_balance(burnt_amount, remaining_gas_amount)?; | ||
| let deposit_cost = total_deposit(actions)?; | ||
| let total_cost = safe_add_balance(gas_cost, deposit_cost)?; |
There was a problem hiding this comment.
nit: I think having it as a member function on TransactionCost is cleaner
There was a problem hiding this comment.
I think it's better to do the addition and overflow check as part of calculate_tx_cost.
If we move to member functions, we have awkward choices:
- Methods return Result -- callers now deal with errors from what looks like a getter, and the overflow rejection no longer happens at construction time. (i.e., we still should check
total_costdoes not overflow for gas keys transactions, even though we charge gas and deposit separately). - Check overflow at construction, then recompute in methods, doing the work twice.
Let me know if you have a good solution here.
| } | ||
| } | ||
|
|
||
| impl FinalExecutionOutcomeView { |
There was a problem hiding this comment.
I'd rather avoid adding such helper functions as part of primitives since it is part of the public API now and we have to maintain it forever
# Gas Keys ([NEP-611](near/NEPs#611)) Gas keys are a new type of access key that carries a pre-funded NEAR balance and multiple independent nonce sequences. When a transaction is signed with a gas key, gas costs are deducted from the gas key's balance rather than the signer's account balance (deposits like NEAR transfers still come from the account). ## Why do we need gas keys? - Enabling SPICE without a DoS vector. The SPICE project (Separation of Execution from Consensus) decouples transaction execution from block production: transactions are included in blocks first, and executed asynchronously later. This means chunk producers can no longer verify account balances at inclusion time. An attacker could drain an account's balance in one transaction, then flood the chain with many transactions signed by that account. All would be accepted (since execution hasn't caught up), consuming block space for free when they inevitably fail. Gas keys close this gap by requiring gas to be pre-committed in the key itself, so chunk producers can verify gas availability without access to the latest state. - Parallel transaction submission. Today, programmatic users who submit many transactions in parallel must manage multiple access keys (each with its own nonce sequence). A gas key supports up to 1,024 independent nonce slots via a single key, removing that complexity. # Context - NEP (if exists): near/NEPs#611 - Implementation: - near#14868 - near#14869 - near#14883 - near#14891 - near#14892 - near#14911 - near#14924 - near#14925 - near#14930 - near#14933 - near#14969 - near#14985 - near#15033 - near#15034 - near#15067 - near#15068 - near#15100 - near#15101 - near#15186 # Testing and QA - unit tests - test-loop: https://github.com/near/nearcore/blob/master/test-loop-tests/src/tests/gas_keys.rs - forknet (automated): near#15207 - forknet (manual testing, planned) # Checklist - [x] Link to nightly nayduck run: https://nayduck.nearone.org/#/run/4756 - [x] Update CHANGELOG.md to include this protocol feature in the `Unreleased` section.
gas_costanddeposit_costfields toTransactionCost(precomputed incalculate_tx_cost)NotEnoughGasKeyBalanceerror variant for insufficient gas key balance.verify_and_charge_gas_key_tx_ephemeralsignature to take&mut AccessKeyso it can modify the gas key balanceTesting changes:
test_gas_key_tx_not_enough_balanceintotest_gas_key_tx_not_enough_gas_key_balanceandtest_gas_key_tx_not_enough_account_balance_for_deposit,apply&test-looptests to fund gas keys and assert balances.Will update protocol_schema.toml and openapi.json after review.
Out of scope for this PR: