Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a gas-based Storage limit per tx #1142

Conversation

ahmadkaouk
Copy link
Contributor

@ahmadkaouk ahmadkaouk commented Aug 4, 2023

Introduction

This pull request tackles the challenge of unsustainable storage growth in our blockchain, a complex issue constrained by the Evm gasometer's ability to record only gas usage. Storage growth refers to the new storage added on-chain after an execution. Without control, this can lead to storage congestions.

Approach: Introduce a gas-based Storage limit

The proposed solution tackles the problem of unsustainable storage growth within blockchains by introducing a concept of mapping storage to gas. By translating bytes into gas units and setting a storage limit per transaction, it establishes a flexible and effective control mechanism. The proposed solution maintains the existing behaviour of the EVM gasometer. It introduces controls for storage growth without altering the core gas tracking system within the EVM.

The core of this approach revolves around the definition of a ratio that encapsulates the relationship between storage growth (in bytes) and gas. For example:

  • RATIO = BLOCK_GAS_LIMIT / BLOCK_STORAGE_LIMIT

Once this ratio is established, we can further define a transaction-wide storage growth limit:

  • TX_STORAGE_LIMIT = TX_GAS_LIMIT / RATIO

The storage growth is dynamically monitored throughout the execution of the transaction. Each time the EVM steps into an opcode, the corresponding storage growth is calculated and recorded. Should the recorded storage growth exceed the pre-established TX_STORAGE_LIMIT, the transaction will trigger an OutOfGas error.

Example

Given:

  • BLOCK_GAS_LIMIT = 15,000,000 (Maximum gas per block)
  • BLOCK_STORAGE_LIMIT = 40 * 1024 bytes (40 KB per block)

The ratio between gas and storage is:

  • RATIO = BLOCK_GAS_LIMIT / BLOCK_STORAGE_LIMIT = 15,000,000 / (40 * 1024) ≈ 366

For a transaction with TX_GAS_LIMIT = 1,000,000, the storage limit is:

  • TX_STORAGE_LIMIT = TX_GAS_LIMIT / RATIO = 1,000,000 / 366 ≈ 2,732 bytes

Changes Introduced

The following changes are introduced to address storage growth within the EVM:

  • Introducing GasLimitStorageGrowthRatio: A new configurable parameter in pallet-evm, defining the ratio of gas to storage. It serves to control the mapping of storage growth to gas. When set to 0, it disables recording the storage growth.
  • Introducing StorageMeter: An utility struct within SubstrateStackState to track and manage storage growth during execution.
  • Storage Recording Mechanism: targets specific EVM opcodes that modify storage: CREATE, CREATE2, and SSTORE:
    • For SSTORE, Storage growth is recorded during pre-execution in record_external_dynamic_opcode_cost, which is called from pre_validate in the executor (that is per each evm runtime step).
    • For CREATE and CREATE2, since the bytecode size to be stored is unknown before execution, recording occurs in record_external_operation during execution, specifically in cleanup_for_create before storing the contract bytecode.
  • Gas Computation: On Post-execution, storage growth is translated into gas, and the charge is applied based on the greater value between this computed gas and the legacy gas from the EVM gasometer.

frame/evm/src/resource.rs Outdated Show resolved Hide resolved
frame/evm/src/resource.rs Outdated Show resolved Hide resolved
frame/evm/src/resource.rs Outdated Show resolved Hide resolved
frame/evm/src/resource.rs Outdated Show resolved Hide resolved
@ahmadkaouk
Copy link
Contributor Author

@sorpaas can we review this one please.

@koushiro
Copy link
Collaborator

koushiro commented Nov 2, 2023

@ahmadkaouk you could use evm 0.41.0 now

@ahmadkaouk
Copy link
Contributor Author

@koushiro Using evm 0.41.0 now.

Cargo.toml Outdated Show resolved Hide resolved
@crystalin
Copy link
Collaborator

@sorpaas We would like to merge this PR as we are cherry-picking it every release.
We could resolve the conflicts but I want to make sure this could be merged soon and tht all comments have been addressed before

@boundless-forest
Copy link
Collaborator

Please merge the master, and I'll review and merge it later. @crystalin

@ahmadkaouk
Copy link
Contributor Author

@boundless-forest I merged to master. PR is ready to be reviewed and merged

Copy link
Collaborator

@boundless-forest boundless-forest left a comment

Choose a reason for hiding this comment

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

Just one comment, LGTM

frame/evm/src/runner/meter.rs Outdated Show resolved Hide resolved
@boundless-forest boundless-forest merged commit b9b1c62 into polkadot-evm:master Dec 11, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants