Skip to content

feat(gas-keys): charge compute for gas key nonce removal#15068

Open
darioush wants to merge 2 commits intodarioush/gaskeys-txfeesfrom
darioush/gaskeys-compute
Open

feat(gas-keys): charge compute for gas key nonce removal#15068
darioush wants to merge 2 commits intodarioush/gaskeys-txfeesfrom
darioush/gaskeys-compute

Conversation

@darioush
Copy link
Contributor

@darioush darioush commented Feb 12, 2026

Charge compute costs when removing gas key nonces during DeleteKey and DeleteAccount actions.

  • Adds storage_removes_compute helper computing storage_remove_{base,key_byte,ret_value_byte} costs from ExtCosts
  • DeleteKey on a gas key: charges per-nonce compute based on exact gas_key_nonce_key_len and NONCE_VALUE_LEN
  • DeleteAccount: remove_account now returns RemoveAccountResult with nonce count and total key bytes collected during iteration, used in runtime to charge per-byte compute

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements proper compute cost charging for gas key nonce removal operations during DeleteKey and DeleteAccount actions, replacing the previous Gas::ZERO placeholder implementation.

Changes:

  • Introduces a storage_removes_compute helper function that calculates compute costs based on storage removal operation counts and byte sizes
  • Updates DeleteKey action to charge accurate per-nonce compute costs based on exact key and value lengths when deleting gas keys
  • Modifies DeleteAccount action to track and charge compute costs for all gas key nonces removed during account deletion

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
runtime/runtime/src/config.rs Adds storage_removes_compute helper function to calculate compute costs for storage removals
runtime/runtime/src/access_keys.rs Updates action_delete_key and delete_gas_key to accept RuntimeConfig and charge proper compute costs for gas key nonce removals
runtime/runtime/src/actions.rs Updates action_delete_account to charge compute costs using information from RemoveAccountResult
core/store/src/utils/mod.rs Adds RemoveAccountResult struct and updates remove_account to track nonce count and key bytes during iteration
runtime/runtime/src/lib.rs Updates function calls to pass RuntimeConfig instead of just RuntimeFeesConfig
runtime/runtime/src/actions_test_utils.rs Updates test helper to pass RuntimeConfig parameter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +357 to +361
let compute = storage_removes_compute(
&config.wasm_config.ext_costs,
remove_result.gas_key_nonce_count,
remove_result.gas_key_nonce_total_key_bytes,
AccessKey::NONCE_VALUE_LEN * remove_result.gas_key_nonce_count,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The multiplication AccessKey::NONCE_VALUE_LEN * remove_result.gas_key_nonce_count could potentially overflow. For consistency with similar code patterns in the codebase, consider using checked arithmetic (e.g., checked_mul().unwrap() or returning a Result on overflow).

Suggested change
let compute = storage_removes_compute(
&config.wasm_config.ext_costs,
remove_result.gas_key_nonce_count,
remove_result.gas_key_nonce_total_key_bytes,
AccessKey::NONCE_VALUE_LEN * remove_result.gas_key_nonce_count,
let nonce_value_bytes = AccessKey::NONCE_VALUE_LEN
.checked_mul(remove_result.gas_key_nonce_count)
.ok_or_else(|| {
StorageError::StorageInconsistentState(
"gas_key_nonce_count overflow when computing nonce bytes".to_string(),
)
})?;
let compute = storage_removes_compute(
&config.wasm_config.ext_costs,
remove_result.gas_key_nonce_count,
remove_result.gas_key_nonce_total_key_bytes,
nonce_value_bytes,

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +87
ext.compute_cost(ExtCosts::storage_remove_base) * count
+ ext.compute_cost(ExtCosts::storage_remove_key_byte) * total_key_bytes
+ ext.compute_cost(ExtCosts::storage_remove_ret_value_byte) * total_value_bytes
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The arithmetic operations in storage_removes_compute should use checked arithmetic for consistency with similar functions like storage_read_gas and storage_write_gas. These functions use checked_mul().unwrap() and checked_add().unwrap() to catch potential overflows during development. Without checked arithmetic, silent integer overflow could lead to incorrect compute cost calculations.

Suggested change
ext.compute_cost(ExtCosts::storage_remove_base) * count
+ ext.compute_cost(ExtCosts::storage_remove_key_byte) * total_key_bytes
+ ext.compute_cost(ExtCosts::storage_remove_ret_value_byte) * total_value_bytes
ext.compute_cost(ExtCosts::storage_remove_base)
.checked_mul(count)
.unwrap()
.checked_add(
ext.compute_cost(ExtCosts::storage_remove_key_byte)
.checked_mul(total_key_bytes)
.unwrap(),
)
.unwrap()
.checked_add(
ext.compute_cost(ExtCosts::storage_remove_ret_value_byte)
.checked_mul(total_value_bytes)
.unwrap(),
)
.unwrap()

Copilot uses AI. Check for mistakes.
Comment on lines +110 to +114
let nonce_remove_compute = storage_removes_compute(
&config.wasm_config.ext_costs,
num_nonces,
nonce_key_len * num_nonces,
AccessKey::NONCE_VALUE_LEN * num_nonces,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The multiplication nonce_key_len * num_nonces could potentially overflow. For consistency with similar code patterns in the codebase, consider using checked arithmetic (e.g., checked_mul().unwrap() or returning a Result on overflow).

Suggested change
let nonce_remove_compute = storage_removes_compute(
&config.wasm_config.ext_costs,
num_nonces,
nonce_key_len * num_nonces,
AccessKey::NONCE_VALUE_LEN * num_nonces,
let nonce_keys_total_len =
nonce_key_len.checked_mul(num_nonces).ok_or(IntegerOverflowError)?;
let nonce_values_total_len =
AccessKey::NONCE_VALUE_LEN.checked_mul(num_nonces).ok_or(IntegerOverflowError)?;
let nonce_remove_compute = storage_removes_compute(
&config.wasm_config.ext_costs,
num_nonces,
nonce_keys_total_len,
nonce_values_total_len,

Copilot uses AI. Check for mistakes.
Comment on lines +110 to +114
let nonce_remove_compute = storage_removes_compute(
&config.wasm_config.ext_costs,
num_nonces,
nonce_key_len * num_nonces,
AccessKey::NONCE_VALUE_LEN * num_nonces,
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The multiplication AccessKey::NONCE_VALUE_LEN * num_nonces could potentially overflow. For consistency with similar code patterns in the codebase, consider using checked arithmetic (e.g., checked_mul().unwrap() or returning a Result on overflow).

Suggested change
let nonce_remove_compute = storage_removes_compute(
&config.wasm_config.ext_costs,
num_nonces,
nonce_key_len * num_nonces,
AccessKey::NONCE_VALUE_LEN * num_nonces,
let total_nonce_key_len =
nonce_key_len.checked_mul(num_nonces).ok_or(IntegerOverflowError)?;
let total_nonce_value_len =
AccessKey::NONCE_VALUE_LEN
.checked_mul(num_nonces)
.ok_or(IntegerOverflowError)?;
let nonce_remove_compute = storage_removes_compute(
&config.wasm_config.ext_costs,
num_nonces,
total_nonce_key_len,
total_nonce_value_len,

Copilot uses AI. Check for mistakes.
@darioush darioush requested a review from pugachAG February 12, 2026 01:28
@darioush darioush marked this pull request as ready for review February 12, 2026 01:28
@darioush darioush requested a review from a team as a code owner February 12, 2026 01:28
@codecov
Copy link

codecov bot commented Feb 12, 2026

Codecov Report

❌ Patch coverage is 93.68421% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.83%. Comparing base (4e957a7) to head (62f0a71).

Files with missing lines Patch % Lines
runtime/runtime/src/actions.rs 66.66% 1 Missing and 4 partials ⚠️
runtime/runtime/src/access_keys.rs 98.11% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##           darioush/gaskeys-txfees   #15068      +/-   ##
===========================================================
- Coverage                    68.83%   68.83%   -0.01%     
===========================================================
  Files                          921      921              
  Lines                       203760   203868     +108     
  Branches                    203760   203868     +108     
===========================================================
+ Hits                        140262   140333      +71     
- Misses                       57515    57520       +5     
- Partials                      5983     6015      +32     
Flag Coverage Δ
pytests-nightly 1.29% <0.00%> (-0.01%) ⬇️
unittests 68.47% <93.68%> (-0.02%) ⬇️
unittests-nightly 68.39% <93.68%> (+<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.

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.

2 participants