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

Open
wants to merge 45 commits into
base: master
Choose a base branch
from

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
template/runtime/src/lib.rs Outdated Show resolved Hide resolved
template/runtime/src/lib.rs Outdated Show resolved Hide resolved
frame/evm/src/mock.rs Outdated Show resolved Hide resolved
frame/evm/src/runner/meter.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
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.

5 participants