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

Add London Support #54

Merged
merged 29 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
bcffb19
Update minimum version of dependencies
joshuajbouw Aug 10, 2021
01e000c
add is_static back in
joshuajbouw Aug 13, 2021
124f69b
Add in EIP-3541
joshuajbouw Aug 19, 2021
d663c1f
Merge branch 'feat/london/eip-3541' into feat/london-support
joshuajbouw Aug 19, 2021
08cad4c
Initial work, requires EIP-1559
joshuajbouw Aug 19, 2021
79f9a33
Add `block_base_fee_per_gas` to `Backend` trait
joshuajbouw Aug 20, 2021
36b1bf8
Merge branch 'feat/london/eip-3198' into feat/london-support
joshuajbouw Aug 20, 2021
0aa3941
Merge branch 'feat/london-support' into london-support-type-rollback
joshuajbouw Aug 20, 2021
3c66240
Add MAX_REFUND_QUOTIENT parameter
birchmd Aug 25, 2021
33737b6
Reduce SSTORE_CLEARS_SCHEDULE value
birchmd Aug 25, 2021
6d2be2c
Remove the SELFDESTRUCT refund.
birchmd Aug 25, 2021
5251f48
Avoid some runtime arithmetic
birchmd Aug 25, 2021
ede2398
Merge branch 'london-support-type-rollback' into feat/london-support
joshuajbouw Aug 27, 2021
e576abd
Revert "Update minimum version of dependencies"
birchmd Sep 7, 2021
01c2834
Merge pull request #3 from aurora-is-near/feat/london/eip-3529
birchmd Sep 7, 2021
9ce2851
Merge branch 'master' into feat/london-support
birchmd Sep 7, 2021
a9e0ac1
Fix: benches compilation
birchmd Sep 8, 2021
8df12f0
Fix(EIP-3541): the correct implementation is to deny the actual deplo…
birchmd Sep 8, 2021
a8caa20
Fix(EIP-1559): complete the implementation
birchmd Sep 8, 2021
e654235
Merge branch 'master' into feat/london-support
birchmd Sep 27, 2021
1afe7c5
Merge branch 'master' into feat/london-support
birchmd Oct 19, 2021
876d731
Merge branch 'master' into feat/london-support
birchmd Oct 27, 2021
81132c2
Fix benches build
birchmd Oct 27, 2021
cef9bf4
cargo fmt
birchmd Oct 27, 2021
072d8bf
Split up create_init function
birchmd Oct 27, 2021
cdb5a8c
Factor out inputs to config_with_derived_values as separate struct
birchmd Oct 27, 2021
14b82b7
Remove has_base_fee check from runtime system (it is not needed becau…
birchmd Oct 27, 2021
33d9e15
Remove gasometer fail
birchmd Oct 27, 2021
0b61849
Revert "Remove gasometer fail"
birchmd Oct 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions benches/loop.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use criterion::{criterion_group, criterion_main, Criterion};
use evm::backend::{MemoryAccount, MemoryBackend, MemoryVicinity};
use evm::executor::{self, MemoryStackState, StackExecutor, StackSubstateMetadata};
use evm::executor::{MemoryStackState, StackExecutor, StackSubstateMetadata};
use evm::Config;
use primitive_types::{H160, U256};
use std::{collections::BTreeMap, str::FromStr};
Expand All @@ -18,6 +18,7 @@ fn run_loop_contract() {
block_difficulty: Default::default(),
block_gas_limit: Default::default(),
chain_id: U256::one(),
block_base_fee_per_gas: U256::zero(),
};

let mut state = BTreeMap::new();
Expand All @@ -43,8 +44,8 @@ fn run_loop_contract() {
let backend = MemoryBackend::new(&vicinity, state);
let metadata = StackSubstateMetadata::new(u64::MAX, &config);
let state = MemoryStackState::new(metadata, &backend);
let mut executor =
StackExecutor::new_with_precompile(state, &config, executor::Precompile::new());
let precompiles = BTreeMap::new();
let mut executor = StackExecutor::new_with_precompiles(state, &config, &precompiles);

let _reason = executor.transact_call(
H160::from_str("0xf000000000000000000000000000000000000000").unwrap(),
Expand Down
2 changes: 2 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ pub enum ExitError {
CreateCollision,
/// Create init code exceeds limit (runtime).
CreateContractLimit,
/// Starting byte must not begin with 0xef. See [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md).
InvalidCode,

/// An opcode accesses external information, but the request is off offset
/// limit (runtime).
Expand Down
2 changes: 2 additions & 0 deletions core/src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ impl Opcode {
pub const BALANCE: Opcode = Opcode(0x31);
/// `SELFBALANCE`
pub const SELFBALANCE: Opcode = Opcode(0x47);
/// `BASEFEE`
pub const BASEFEE: Opcode = Opcode(0x48);
/// `ORIGIN`
pub const ORIGIN: Opcode = Opcode(0x32);
/// `CALLER`
Expand Down
28 changes: 6 additions & 22 deletions gasometer/src/costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,10 @@ pub fn sstore_refund(original: H256, current: H256, new: H256, config: &Config)
}

if original == new {
let (gas_sstore_reset, gas_sload) = if config.increase_state_access_gas {
(
config.gas_sstore_reset - config.gas_sload_cold,
config.gas_storage_read_warm,
)
} else {
(config.gas_sstore_reset, config.gas_sload)
};
if original == H256::default() {
refund += (config.gas_sstore_set - gas_sload) as i64;
refund += (config.gas_sstore_set - config.gas_sload) as i64;
} else {
refund += (gas_sstore_reset - gas_sload) as i64;
refund += (config.gas_sstore_reset - config.gas_sload) as i64;
}
}

Expand Down Expand Up @@ -214,37 +206,29 @@ pub fn sstore_cost(
is_cold: bool,
config: &Config,
) -> Result<u64, ExitError> {
let (gas_sload, gas_sstore_reset) = if config.increase_state_access_gas {
(
config.gas_storage_read_warm,
config.gas_sstore_reset - config.gas_sload_cold,
)
} else {
(config.gas_sload, config.gas_sstore_reset)
};
let gas_cost = if config.sstore_gas_metering {
if config.sstore_revert_under_stipend && gas <= config.call_stipend {
return Err(ExitError::OutOfGas);
}

if new == current {
gas_sload
config.gas_sload
} else {
if original == current {
if original == H256::zero() {
config.gas_sstore_set
} else {
gas_sstore_reset
config.gas_sstore_reset
}
} else {
gas_sload
config.gas_sload
}
}
} else {
if current == H256::zero() && new != H256::zero() {
config.gas_sstore_set
} else {
gas_sstore_reset
config.gas_sstore_reset
}
};
Ok(
Expand Down
5 changes: 4 additions & 1 deletion gasometer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,9 @@ pub fn dynamic_opcode_cost<H: Handler>(
Opcode::SELFBALANCE if config.has_self_balance => GasCost::Low,
Opcode::SELFBALANCE => GasCost::Invalid,

Opcode::BASEFEE if config.has_base_fee => GasCost::Base,
Opcode::BASEFEE => GasCost::Invalid,

Opcode::EXTCODESIZE => {
let target = stack.peek(0)?.into();
storage_target = StorageTarget::Address(target);
Expand Down Expand Up @@ -832,7 +835,7 @@ impl<'config> Inner<'config> {
} => costs::sstore_refund(original, current, new, self.config),
GasCost::Suicide {
already_removed, ..
} => costs::suicide_refund(already_removed),
} if !self.config.decrease_clears_refund => costs::suicide_refund(already_removed),
_ => 0,
}
}
Expand Down
1 change: 1 addition & 0 deletions runtime/src/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub fn eval<H: Handler>(state: &mut Runtime, opcode: Opcode, handler: &mut H) ->
Opcode::DELEGATECALL => system::call(state, CallScheme::DelegateCall, handler),
Opcode::STATICCALL => system::call(state, CallScheme::StaticCall, handler),
Opcode::CHAINID => system::chainid(state, handler),
Opcode::BASEFEE => system::base_fee(state, handler),
_ => handle_other(state, opcode, handler),
}
}
8 changes: 8 additions & 0 deletions runtime/src/eval/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ pub fn gasprice<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
Control::Continue
}

pub fn base_fee<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
let mut ret = H256::default();
handler.block_base_fee_per_gas().to_big_endian(&mut ret[..]);
push!(runtime, ret);

Control::Continue
}

pub fn extcodesize<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
pop!(runtime, address);
push_u256!(runtime, handler.code_size(address.into()));
Expand Down
2 changes: 2 additions & 0 deletions runtime/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub trait Handler {
fn block_difficulty(&self) -> U256;
/// Get environmental gas limit.
fn block_gas_limit(&self) -> U256;
/// Environmental block base fee.
fn block_base_fee_per_gas(&self) -> U256;
/// Get environmental chain ID.
fn chain_id(&self) -> U256;

Expand Down
97 changes: 91 additions & 6 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ pub struct Config {
pub gas_sstore_reset: u64,
/// Gas paid for sstore refund.
pub refund_sstore_clears: i64,
/// EIP-3529
pub max_refund_quotient: u64,
/// Gas paid for BALANCE opcode.
pub gas_balance: u64,
/// Gas paid for SLOAD opcode.
Expand Down Expand Up @@ -209,6 +211,10 @@ pub struct Config {
pub sstore_revert_under_stipend: bool,
/// EIP-2929
pub increase_state_access_gas: bool,
/// EIP-3529
pub decrease_clears_refund: bool,
/// EIP-3541
pub disallow_executable_format: bool,
/// Whether to throw out of gas error when
/// CALL/CALLCODE/DELEGATECALL requires more than maximum amount
/// of gas.
Expand Down Expand Up @@ -245,6 +251,8 @@ pub struct Config {
pub has_self_balance: bool,
/// Has ext code hash.
pub has_ext_code_hash: bool,
/// Has ext block fee. See [EIP-3198](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3198.md)
pub has_base_fee: bool,
/// Whether the gasometer is running in estimate mode.
pub estimate: bool,
}
Expand All @@ -261,6 +269,7 @@ impl Config {
gas_sstore_set: 20000,
gas_sstore_reset: 5000,
refund_sstore_clears: 15000,
max_refund_quotient: 2,
gas_suicide: 0,
gas_suicide_new_account: 0,
gas_call: 40,
Expand All @@ -276,6 +285,8 @@ impl Config {
sstore_gas_metering: false,
sstore_revert_under_stipend: false,
increase_state_access_gas: false,
decrease_clears_refund: false,
disallow_executable_format: false,
err_on_call_with_more_gas: true,
empty_considered_exists: true,
create_increase_nonce: false,
Expand All @@ -293,6 +304,7 @@ impl Config {
has_chain_id: false,
has_self_balance: false,
has_ext_code_hash: false,
has_base_fee: false,
estimate: false,
}
}
Expand All @@ -308,6 +320,7 @@ impl Config {
gas_sstore_set: 20000,
gas_sstore_reset: 5000,
refund_sstore_clears: 15000,
max_refund_quotient: 2,
gas_suicide: 5000,
gas_suicide_new_account: 25000,
gas_call: 700,
Expand All @@ -323,6 +336,8 @@ impl Config {
sstore_gas_metering: true,
sstore_revert_under_stipend: true,
increase_state_access_gas: false,
decrease_clears_refund: false,
disallow_executable_format: false,
err_on_call_with_more_gas: false,
empty_considered_exists: false,
create_increase_nonce: true,
Expand All @@ -340,21 +355,53 @@ impl Config {
has_chain_id: true,
has_self_balance: true,
has_ext_code_hash: true,
has_base_fee: false,
estimate: false,
}
}

/// Berlin hard fork configuration.
pub const fn berlin() -> Config {
Self::config_with_derived_values(DerivedConfigInputs::berlin())
}

/// london hard fork configuration.
pub const fn london() -> Config {
Self::config_with_derived_values(DerivedConfigInputs::london())
}

const fn config_with_derived_values(inputs: DerivedConfigInputs) -> Config {
let DerivedConfigInputs {
gas_storage_read_warm,
gas_sload_cold,
gas_access_list_storage_key,
decrease_clears_refund,
has_base_fee,
disallow_executable_format,
} = inputs;

// See https://eips.ethereum.org/EIPS/eip-2929
let gas_sload = gas_storage_read_warm;
let gas_sstore_reset = 5000 - gas_sload_cold;

// See https://eips.ethereum.org/EIPS/eip-3529
let refund_sstore_clears = if decrease_clears_refund {
(gas_sstore_reset + gas_access_list_storage_key) as i64
} else {
15000
};
let max_refund_quotient = if decrease_clears_refund { 5 } else { 2 };

Config {
gas_ext_code: 0,
gas_ext_code_hash: 0,
gas_balance: 0,
gas_sload: 0,
gas_sload_cold: 2100,
gas_sload,
gas_sload_cold,
gas_sstore_set: 20000,
gas_sstore_reset: 5000,
refund_sstore_clears: 15000,
gas_sstore_reset,
refund_sstore_clears,
max_refund_quotient,
gas_suicide: 5000,
gas_suicide_new_account: 25000,
gas_call: 0,
Expand All @@ -364,12 +411,14 @@ impl Config {
gas_transaction_zero_data: 4,
gas_transaction_non_zero_data: 16,
gas_access_list_address: 2400,
gas_access_list_storage_key: 1900,
gas_access_list_storage_key,
gas_account_access_cold: 2600,
gas_storage_read_warm: 100,
gas_storage_read_warm,
sstore_gas_metering: true,
sstore_revert_under_stipend: true,
increase_state_access_gas: true,
decrease_clears_refund,
disallow_executable_format,
err_on_call_with_more_gas: false,
empty_considered_exists: false,
create_increase_nonce: true,
Expand All @@ -387,7 +436,43 @@ impl Config {
has_chain_id: true,
has_self_balance: true,
has_ext_code_hash: true,
has_base_fee,
estimate: false,
}
}
}

/// Independent inputs that are used to derive other config values.
/// See `Config::config_with_derived_values` implementation for details.
struct DerivedConfigInputs {
gas_storage_read_warm: u64,
gas_sload_cold: u64,
gas_access_list_storage_key: u64,
decrease_clears_refund: bool,
has_base_fee: bool,
disallow_executable_format: bool,
}

impl DerivedConfigInputs {
const fn berlin() -> Self {
Self {
gas_storage_read_warm: 100,
gas_sload_cold: 2100,
gas_access_list_storage_key: 1900,
decrease_clears_refund: false,
has_base_fee: false,
disallow_executable_format: false,
}
}

const fn london() -> Self {
Self {
gas_storage_read_warm: 100,
gas_sload_cold: 2100,
gas_access_list_storage_key: 1900,
decrease_clears_refund: true,
has_base_fee: true,
disallow_executable_format: true,
}
}
}
5 changes: 5 additions & 0 deletions src/backend/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct MemoryVicinity {
pub block_difficulty: U256,
/// Environmental block gas limit.
pub block_gas_limit: U256,
/// Environmental base fee per gas.
pub block_base_fee_per_gas: U256,
}

/// Account information of a memory backend.
Expand Down Expand Up @@ -105,6 +107,9 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> {
fn block_gas_limit(&self) -> U256 {
self.vicinity.block_gas_limit
}
fn block_base_fee_per_gas(&self) -> U256 {
self.vicinity.block_base_fee_per_gas
}

fn chain_id(&self) -> U256 {
self.vicinity.chain_id
Expand Down
4 changes: 3 additions & 1 deletion src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub enum Apply<I> {

/// EVM backend.
pub trait Backend {
/// Gas price.
/// Gas price. Unused for London.
fn gas_price(&self) -> U256;
/// Origin.
fn origin(&self) -> H160;
Expand All @@ -67,6 +67,8 @@ pub trait Backend {
fn block_difficulty(&self) -> U256;
/// Environmental block gas limit.
fn block_gas_limit(&self) -> U256;
/// Environmental block base fee.
fn block_base_fee_per_gas(&self) -> U256;
/// Environmental chain ID.
fn chain_id(&self) -> U256;

Expand Down
Loading