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

EIP-1559 support #429

Merged
merged 73 commits into from
Nov 10, 2021
Merged

Conversation

tgmichel
Copy link
Contributor

@tgmichel tgmichel commented Jul 29, 2021

This PR is bigger than usual but in essence changes relate to:

  • Enveloped transactions handling.
  • Signing and validation.
  • Serializing / deserializing rpc payloads.
  • Runtime Api versioning.
  • Fee payment.
  • Base fee handling.

Decision to include all this changes in a single PR instead of splitting in various is compatibility: we are moving away from legacy transaction type to new typed transactions at runtime level, and those changes cascade into many modules. Is just more convenient to do it at once.

Review checkpoints

  • Transaction response conversion here.
  • TransactionMessage conversion here.
  • Transaction response build here.
  • Identify Transaction type in eth_sendRawTransaction here.
  • public_key function here.
  • Schema override V2 here.
  • pallet-base-fee here.
  • pallet-ethereum recover_signer function here.
  • pallet-ethereum transaction validation logic here, here and here.
  • Integrate new precompile architecture here and here.
  • pallet-evm dispatchable signature changes here.
  • Handle author tips in OnChargeEVMTransaction here.

Base Fee

A new pallet-base-fee is introduced, and can be configured with a BaseFeeThreshold to define the upper/lower block fullness bounds, and a Modifier. By default upper is 100, lower is 0 and Modifier is 12.5%.

The algorithm follows the one decsribed in the original EIP1559 specification. Will use upper to determine the ideal network congestion (upper / 2), and modify the storage BaseFee - defaults to 1_000_000_000 (1GWEI), can be customized in the chain spec - depending on how far we are from this ideal. This happens on_finalize, and in most cases will slightly increase or decrease the BaseFee up to the Modifier - in the unlikely case that the block is 100% full it will increase 12.5%, and if totally empty 12.5%.

The pallet also implements pallet-evm::FeeCalculator that returns the current BaseFee.

Priority Fee

The block author now is tipped with the max_priority_fee_per_gas if any. The OnChargeTransaction trait is changed for this purpose, we added a method pay_priority_fee(U256) that will find the author of the current block using the pre-runtime digest and deposit the priority fee.

max_priority_fee_per_gas is also used for the TransactionValidity priority.

Fee handling example

Refunds work slightly different now. Previously gas_price was a combination of both the minimum viable fee and an artifical increase as an incentive for miners to prioritize the transaction.

Now the EVM will only see whatever the current BaseFee is, which will be always burnt.

Consider the following request:

+-----------+---------+--------------+
| Gas_limit | Max_Fee | Max_Priority |
+-----------+---------+--------------+
|        20 |      10 |            6 |
+-----------+---------+--------------+

And execution:

+----------+----------+
| Gas_used | Base_Fee |
+----------+----------+
|        5 |        2 |
+----------+----------+
  • Initially withdrawn (10 + 6) * 20 = 320.
  • Actual cost (2 + 6) * 5 = 40.
  • Refunded 320 - 40 = 280.
  • Tip 5 * 6 = 30.
  • Burned 320 - (280 + 30) = 10. Which is equivalent to gas_used * base_fee.

RPC payload changes

They are described https://hackmd.io/@timbeiko/1559-json-rpc

Signing and verification

We now use a new ethereum crates version that correctly hashes Transaction messages.

Runtime Api versioning and pallet-ethereum schema V2

pallet-ethereum storage types changed so a new EthereumStorageSchema::V2 is required in addition to a new EthereumRuntimeRPCApi version (2).

Important!! for those Frontier implementors that want to get this upgrade in and they are running a live chain, a migration is mandatory, something like:

// In pallet-ethereum
fn on_runtime_upgrade() -> Weight {
    frame_support::storage::unhashed::put::<EthereumStorageSchema>(
        &PALLET_ETHEREUM_SCHEMA,
        &EthereumStorageSchema::V2,
    );
}

Of course this new schema has it's SchemaV2Override counterpart.

Additionally for the frontier-schema-cache-task essential task one can set the EthereumStorageSchema version that is mapped at genesis. Existing chains should set this to EthereumStorageSchema::V1, and new chains or people trying out frontier should use the new EthereumStorageSchema::V2.

Breaks Api on pallet-evm

pallet-evm dispatchables now accept max_fee_per_gas and max_priority_fee_per_gas instead of gas_price.

Tests

  • pallet-base-fee is fully tested but is specially sensible so a good review on it is required.
  • Original integration tests for pallet-etherum are not replicated for all transaction types.
  • Priority fee test in pallet-evm makes sure the author gets the tip.
  • Refund test in pallet-evm makes sure the fees are correctly handled.
  • Typescript tests now include ethersjs to build, sign and send EIP2930 and 1559 transactions types.

What's not included in this PR

  • One of the core parts of EIP-1559 is expanding the block size when the network is congested. This is not included in this PR and is left to be implemented in the future.
  • A new rpc method eth_feeHistory was introduced in EIP1559 but my main focus for this PR was the new fee mechanics as well as supporting the current transaction types. I left that for a followup PR and will come right after this one.

@tgmichel tgmichel mentioned this pull request Jul 29, 2021
@tgmichel
Copy link
Contributor Author

tgmichel commented Oct 8, 2021

@sorpaas to support this we need a new release of ethereum crate with changes introduced in:
rust-ethereum/ethereum#23 (merged)
rust-ethereum/ethereum#24
rust-ethereum/ethereum#25
rust-ethereum/ethereum#26

@tgmichel tgmichel marked this pull request as ready for review November 5, 2021 09:55
@tgmichel tgmichel requested a review from sorpaas as a code owner November 5, 2021 09:55
@sorpaas sorpaas merged commit bcae569 into polkadot-evm:master Nov 10, 2021
@JoshOrndorff JoshOrndorff mentioned this pull request Nov 10, 2021

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_finalize(_n: <T as frame_system::Config>::BlockNumber) {
Copy link
Contributor

Choose a reason for hiding this comment

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

To keep track of the weight taken by the operations performed in on_finalize, we need to add an empty on_initialize that returns the weight needed by on_finalize.

@librelois librelois deleted the tgm-eip-1559 branch November 12, 2021 20:41
tgmichel added a commit to moonbeam-foundation/frontier that referenced this pull request Nov 16, 2021
* Add `pallet-base-fee`

* WIP pallet-ethereum changes

* Rpc wips: send_raw_transaction

* Rpc wips: send_transaction

* More

* Rework for ethereum 0.9.0

* Rollback package-lock.json..

* Fix typed transaction encoding and hashing

* Add ethers dep and init provider

* Typed transaction basic test

* editorconfig

* Reintroduce `pallet-base-fee`

* Update `pallet-ethereum` tests

* `pallet-base-fee` work + integration tests

* Use `pallet_evm::FeeCalculator` trait

* Add runtime api call/create version

* Update runner (breaks api)

* Update CallRequest + eth_call/estimate_gas

* Update ts-tests

* rpc: post-eip1559 blocks include `baseFeePerGas`

* rpc: calculate `gasPrice` for post-eip1559 txns

* Do not serialize 1559 fields in pre-1559 txns

* Add eip helper to `StorageOverride` trait

* rpc: add `effectiveGasPrice` to receipt

* Fix package.json

* fmt

* Customize `ethereum_schema_cache_task` version from service

* Fix integration tests

* `EthDevSigner` fix `odd_y_parity`

* Replicate integration tests for each txn type

* Default gas_price/fee_per_gas in `sign_transaction`

* Remove todo comments

* Oops

* Introduce `OnChargeEVMTransaction::pay_priority_fee`

* Fix warnings

* Add test for priority tip

* fmt

* Fix fees / priority + test

* Comment fee handling in pallet-evm runner

* Set defaults for `pallet-base-fee` storage

* Rename `Modifier` to `Elasticity` + move it to storage + dispatchable

* fmt

* `pallet-base-fee` dispatchables integration tests

* WIP Bump ethereum + evm version

* Handle `access_list`

* Oops

* fmt

* Fix test-balance test

* Bump evm version to 0.32.0

* fmt

* Warning cleanup

* Oops rollback package.json

* Fix test

* Fix `gas_limit` on `eth_sendTransaction`

* Implement `is_cold` / `is_storage_cold`

* Err when no chain id for eth_sendTransaction

* Move fee details logic to own function

* Safer match `base_fee`

* Just evaluate and return

* Cleaner map into

* Fix priority for legacy transactions

* Safer check over gas_price

* fmt

* Fix priority in tests

* Bump evm 0.33.0

* Update pallet-evm test

* Remove std feature gate on rpc-core

(cherry picked from commit bcae569)

# Conflicts:
#	Cargo.lock
#	client/consensus/Cargo.toml
#	client/rpc/Cargo.toml
#	client/rpc/src/eth.rs
#	frame/dynamic-fee/src/lib.rs
#	frame/ethereum/Cargo.toml
#	frame/ethereum/src/lib.rs
#	primitives/rpc/Cargo.toml
#	primitives/self-contained/Cargo.toml
#	template/node/src/service.rs
#	template/runtime/Cargo.toml
#	template/runtime/src/lib.rs
abhijeetbhagat pushed a commit to web3labs/frontier that referenced this pull request Jan 11, 2023
* Add `pallet-base-fee`

* WIP pallet-ethereum changes

* Rpc wips: send_raw_transaction

* Rpc wips: send_transaction

* More

* Rework for ethereum 0.9.0

* Rollback package-lock.json..

* Fix typed transaction encoding and hashing

* Add ethers dep and init provider

* Typed transaction basic test

* editorconfig

* Reintroduce `pallet-base-fee`

* Update `pallet-ethereum` tests

* `pallet-base-fee` work + integration tests

* Use `pallet_evm::FeeCalculator` trait

* Add runtime api call/create version

* Update runner (breaks api)

* Update CallRequest + eth_call/estimate_gas

* Update ts-tests

* rpc: post-eip1559 blocks include `baseFeePerGas`

* rpc: calculate `gasPrice` for post-eip1559 txns

* Do not serialize 1559 fields in pre-1559 txns

* Add eip helper to `StorageOverride` trait

* rpc: add `effectiveGasPrice` to receipt

* Fix package.json

* fmt

* Customize `ethereum_schema_cache_task` version from service

* Fix integration tests

* `EthDevSigner` fix `odd_y_parity`

* Replicate integration tests for each txn type

* Default gas_price/fee_per_gas in `sign_transaction`

* Remove todo comments

* Oops

* Introduce `OnChargeEVMTransaction::pay_priority_fee`

* Fix warnings

* Add test for priority tip

* fmt

* Fix fees / priority + test

* Comment fee handling in pallet-evm runner

* Set defaults for `pallet-base-fee` storage

* Rename `Modifier` to `Elasticity` + move it to storage + dispatchable

* fmt

* `pallet-base-fee` dispatchables integration tests

* WIP Bump ethereum + evm version

* Handle `access_list`

* Oops

* fmt

* Fix test-balance test

* Bump evm version to 0.32.0

* fmt

* Warning cleanup

* Oops rollback package.json

* Fix test

* Fix `gas_limit` on `eth_sendTransaction`

* Implement `is_cold` / `is_storage_cold`

* Err when no chain id for eth_sendTransaction

* Move fee details logic to own function

* Safer match `base_fee`

* Just evaluate and return

* Cleaner map into

* Fix priority for legacy transactions

* Safer check over gas_price

* fmt

* Fix priority in tests

* Bump evm 0.33.0

* Update pallet-evm test

* Remove std feature gate on rpc-core
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.

3 participants