Skip to content

feat(gas-keys): add NonceIndex and TransactionV1 modifications#14883

Merged
darioush merged 13 commits into
masterfrom
darioush/gas-keys-transaction-v1
Jan 22, 2026
Merged

feat(gas-keys): add NonceIndex and TransactionV1 modifications#14883
darioush merged 13 commits into
masterfrom
darioush/gas-keys-transaction-v1

Conversation

@darioush

@darioush darioush commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

This PR aligns TransactionV1 with the specification of NEP-611. This includes:

  • Removing priority_fee from the unused TransactionV1 (priority_fee will be retained in json output for backwards compatibility)
  • Changing the type of nonce to TransactionNonce, which can include the nonce_index.

I update the pool to use a key containing the nonce_index when relevant and add basic add/remove UT for it.

I left removal of ReceiptV1, updating transaction processing, and fixing tool/mirrors for separate PRs.
Notably it is still not possible to use TransactionV1 which is gated by GasKeys protocol feature.

@codecov

codecov Bot commented Jan 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.90909% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.72%. Comparing base (3a8cc73) to head (0db5d51).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
tools/mirror/src/chain_tracker.rs 0.00% 6 Missing ⚠️
chain/client/src/client.rs 42.85% 4 Missing ⚠️
core/primitives/src/test_utils.rs 86.36% 3 Missing ⚠️
core/primitives/src/transaction.rs 92.59% 1 Missing and 1 partial ⚠️
tools/mirror/src/lib.rs 0.00% 2 Missing ⚠️
chain/chain/src/runtime/tests.rs 66.66% 1 Missing ⚠️
chain/pool/src/lib.rs 99.21% 1 Missing ⚠️
runtime/runtime/src/verifier.rs 95.45% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #14883      +/-   ##
==========================================
+ Coverage   68.70%   68.72%   +0.02%     
==========================================
  Files         916      916              
  Lines      199686   199835     +149     
  Branches   199686   199835     +149     
==========================================
+ Hits       137192   137335     +143     
- Misses      56581    56587       +6     
  Partials     5913     5913              
Flag Coverage Δ
pytests-nightly 1.31% <0.00%> (-0.01%) ⬇️
unittests 68.46% <89.54%> (+0.03%) ⬆️
unittests-nightly 68.22% <90.45%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@darioush darioush changed the title feat(gas-keys): add NonceIndex support and TransactionV1 modifications feat(gas-keys): add NonceIndex and TransactionV1 modifications Jan 15, 2026
Comment thread chain/pool/Cargo.toml
Comment on lines +22 to +25
[dev-dependencies]
near-crypto = { workspace = true, features = ["rand"] }
near-primitives = { workspace = true, features = ["test_utils"] }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding these allows running the pool tests separately like:
cargo test --package near-pool --features test_features --lib -- tests::test_order_nonce_with_nonce_index

@darioush darioush force-pushed the darioush/gas-keys-transaction-v1 branch from e399c1a to fcbbd11 Compare January 15, 2026 04:31
@darioush darioush force-pushed the darioush/gas-keys-transaction-v1 branch from fcbbd11 to d2e11b2 Compare January 15, 2026 04:32
@darioush darioush marked this pull request as ready for review January 15, 2026 04:45
@darioush darioush requested review from a team and frol as code owners January 15, 2026 04:45
@darioush

darioush commented Jan 15, 2026

Copy link
Copy Markdown
Contributor Author

If we think we may want the transaction/receipt priority in the future or that removing priority_fee is problematic, as alternative we could keep priority_fee and just enforce that it is 0 for now.

@@ -1632,29 +1632,29 @@ pub struct SignedTransactionView {
pub nonce: Nonce,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we use TransactionNonce in SignedTransactionView and have nonce and nonce index separate?

@darioush darioush Jan 15, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this as it seemed the most simple and doesn't change the type of any existing field.

If we change it to TransactionNonce, then in json we would have the simple nonces as "nonce": {"nonce": 200}, which I worry could break some downstream expectations.

We could also make it serde(untagged) to still have "nonce": 200 and then "nonce": {"nonce": 200, "nonce_index": 2} which seems fine if you prefer this.

Comment thread chain/pool/src/lib.rs Outdated
transactions.extend(generate_transactions_v1("alice.near", "alice.near", 1, 5, Some(1)));

let mut pool = TransactionPool::new(TEST_SEED, None, "");
let mut rng = thread_rng();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please avoid using thread_rng in tests, instead use deterministic one with hardcoded seed so that test failures are reproducible

Comment thread core/primitives/src/transaction.rs Outdated
/// Simple nonce without index, used by ordinary access keys
Nonce { nonce: Nonce },
/// Nonce with index, used by gas keys
NonceAndIndex { nonce: Nonce, nonce_index: NonceIndex },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is gas-key specific maybe let's call it GasKeyNonce for now? we can always rename it later if needed

@darioush darioush added this pull request to the merge queue Jan 22, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jan 22, 2026
@darioush darioush added this pull request to the merge queue Jan 22, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jan 22, 2026
Comment thread chain/pool/src/lib.rs
Comment on lines +81 to +83
if let Some(idx) = nonce_index {
v.extend_from_slice(&borsh::to_vec(&idx).unwrap());
}

@darioush darioush Jan 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this was unconditional and using None for access keys.
However this changed ordering, changing link_imbalance_ratio of ultra_slow_test_bandwidth_scheduler_three_shards_random_receipts resulting in nayduck failure

@darioush darioush enabled auto-merge January 22, 2026 03:44
@darioush darioush added this pull request to the merge queue Jan 22, 2026
Merged via the queue into master with commit a8a59cc Jan 22, 2026
31 checks passed
@darioush darioush deleted the darioush/gas-keys-transaction-v1 branch January 22, 2026 04:11
pull Bot pushed a commit to See887777/nearcore that referenced this pull request Jun 3, 2026
# 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants