EIP 1884 Re-pricing of trie-size dependent operations (#10992)
* Add client-traits crate Move the BlockInfo trait to new crate * New crate `machine` Contains code extracted from ethcore that defines `Machine`, `Externalities` and other execution related code. * Use new machine and client-traits crates in ethcore * Use new crates machine and client-traits instead of ethcore where appropriate * Fix tests * Don't re-export so many types from ethcore::client * Fixing more fallout from removing re-export * fix test * More fallout from not re-exporting types * Add some docs * cleanup * import the macro edition style * Tweak docs * Add missing import * remove unused ethabi_derive imports * Use latest ethabi-contract * Move many traits from ethcore/client/traits to client-traits crate Initial version of extracted Engine trait * Move snapshot related traits to the engine crate (eew) * Move a few snapshot related types to common_types Cleanup Executed as exported from machine crate * fix warning * Gradually introduce new engine crate: snapshot * ethcore typechecks with new engine crate * Sort out types outside ethcore * Add an EpochVerifier to ethash and use that in Engine.epoch_verifier() Cleanup * Document pub members * Sort out tests Sort out default impls for EpochVerifier * Add test-helpers feature and move EngineSigner impl to the right place * Sort out tests * Sort out tests and refactor verification types * Fix missing traits * More missing traits Fix Histogram * Fix tests and cleanup * cleanup * Put back needed logger import * Don't rexport common_types from ethcore/src/client Don't export ethcore::client::* * Remove files no longer used Use types from the engine crate Explicit exports from engine::engine * Get rid of itertools * Move a few more traits from ethcore to client-traits: BlockChainReset, ScheduleInfo, StateClient * Move ProvingBlockChainClient to client-traits * Don't re-export ForkChoice and Transition from ethcore * Address grumbles: sort imports, remove commented out code * Fix merge resolution error * Extract the Clique engine to own crate * Extract NullEngine and the block_reward module from ethcore * Extract InstantSeal engine to own crate * Extract remaining engines * Extract executive_state to own crate so it can be used by engine crates * Remove snapshot stuff from the engine crate * Put snapshot traits back in ethcore * cleanup * Remove stuff from ethcore * Don't use itertools * itertools in aura is legit-ish * More post-merge fixes * Re-export less types in client * cleanup * Extract spec to own crate * Put back the test-helpers from basic-authority * Fix ethcore benchmarks * Reduce the public api of ethcore/verification * WIP * Add Cargo.toml * Fix compilation outside ethcore * Audit uses of import_verified_blocks() and remove unneeded calls Cleanup * cleanup * Remove unused imports from ethcore * Cleanup * remove double semi-colons * Add missing generic param * More missing generics * Update ethcore/block-reward/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/basic-authority/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/ethash/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/clique/src/lib.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * signers is already a ref * Add an EngineType enum to tighten up Engine.name() * Add CHAINID opcode * Introduce Snapshotting enum to distinguish the type of snapshots a chain uses * Rename supports_warp to snapshot_mode * Missing import * Add chain_id wherever we instantiate EnvInfo * more missing chain_id * Tell serde to ignore the chain_id field on Env * Update ethcore/src/snapshot/consensus/mod.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Use the chain_id from the machine by adding chain_id() to the Ext trait * cleanup * add missing impl cleanup * missing import * Fix import * Add transition marker for EIP 1344 * double semi * Fix merge problem * cleanup * reprice SLOAD to 800 gas * Reprice BALANCE and EXTCODEHASH * Add SELFBALANCE opcode * Add test for SELFBALANCE Use InstructionParams.address as the self-address * Use easier to read values in test * merge conflict error * Fix a few warnings * Update ethcore/vm/src/schedule.rs Co-Authored-By: Andronik Ordian <write@reusable.software> * more merge fallout
This commit is contained in:
parent
3420c2bac0
commit
dabfa2c663
@ -44,12 +44,18 @@ pub trait Finalize {
|
|||||||
impl Finalize for Result<GasLeft> {
|
impl Finalize for Result<GasLeft> {
|
||||||
fn finalize<E: Ext>(self, ext: E) -> Result<FinalizationResult> {
|
fn finalize<E: Ext>(self, ext: E) -> Result<FinalizationResult> {
|
||||||
match self {
|
match self {
|
||||||
Ok(GasLeft::Known(gas_left)) => Ok(FinalizationResult { gas_left: gas_left, apply_state: true, return_data: ReturnData::empty() }),
|
Ok(GasLeft::Known(gas_left)) => {
|
||||||
Ok(GasLeft::NeedsReturn { gas_left, data, apply_state }) => ext.ret(&gas_left, &data, apply_state).map(|gas_left| FinalizationResult {
|
Ok(FinalizationResult {
|
||||||
gas_left: gas_left,
|
gas_left,
|
||||||
apply_state: apply_state,
|
apply_state: true,
|
||||||
return_data: data,
|
return_data: ReturnData::empty()
|
||||||
}),
|
})
|
||||||
|
},
|
||||||
|
Ok(GasLeft::NeedsReturn { gas_left, data, apply_state }) => {
|
||||||
|
ext.ret(&gas_left, &data, apply_state).map(|gas_left|
|
||||||
|
FinalizationResult { gas_left, apply_state, return_data: data }
|
||||||
|
)
|
||||||
|
},
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,8 @@ enum_with_from_u8! {
|
|||||||
GASLIMIT = 0x45,
|
GASLIMIT = 0x45,
|
||||||
#[doc = "get chain ID"]
|
#[doc = "get chain ID"]
|
||||||
CHAINID = 0x46,
|
CHAINID = 0x46,
|
||||||
|
#[doc = "get balance of own account"]
|
||||||
|
SELFBALANCE = 0x47,
|
||||||
|
|
||||||
#[doc = "remove item from stack"]
|
#[doc = "remove item from stack"]
|
||||||
POP = 0x50,
|
POP = 0x50,
|
||||||
@ -502,6 +504,7 @@ lazy_static! {
|
|||||||
arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base));
|
arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base));
|
||||||
arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base));
|
arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base));
|
||||||
arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base));
|
arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base));
|
||||||
|
arr[SELFBALANCE as usize] = Some(InstructionInfo::new("SELFBALANCE", 0, 1, GasPriceTier::Low));
|
||||||
arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base));
|
arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base));
|
||||||
arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow));
|
arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow));
|
||||||
arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow));
|
arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow));
|
||||||
|
@ -299,7 +299,12 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
let result = if self.gasometer.is_none() {
|
let result = if self.gasometer.is_none() {
|
||||||
InterpreterResult::Done(Err(vm::Error::OutOfGas))
|
InterpreterResult::Done(Err(vm::Error::OutOfGas))
|
||||||
} else if self.reader.len() == 0 {
|
} else if self.reader.len() == 0 {
|
||||||
InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256())))
|
let current_gas = self.gasometer
|
||||||
|
.as_ref()
|
||||||
|
.expect("Gasometer None case is checked above; qed")
|
||||||
|
.current_gas
|
||||||
|
.as_u256();
|
||||||
|
InterpreterResult::Done(Ok(GasLeft::Known(current_gas)))
|
||||||
} else {
|
} else {
|
||||||
self.step_inner(ext)
|
self.step_inner(ext)
|
||||||
};
|
};
|
||||||
@ -308,7 +313,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
self.done = true;
|
self.done = true;
|
||||||
self.informant.done();
|
self.informant.done();
|
||||||
}
|
}
|
||||||
return result;
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inner helper function for step.
|
/// Inner helper function for step.
|
||||||
@ -429,7 +434,8 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
(instruction == instructions::REVERT && !schedule.have_revert) ||
|
(instruction == instructions::REVERT && !schedule.have_revert) ||
|
||||||
((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) ||
|
((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) ||
|
||||||
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) ||
|
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) ||
|
||||||
(instruction == instructions::CHAINID && !schedule.have_chain_id)
|
(instruction == instructions::CHAINID && !schedule.have_chain_id) ||
|
||||||
|
(instruction == instructions::SELFBALANCE && !schedule.have_selfbalance)
|
||||||
{
|
{
|
||||||
return Err(vm::Error::BadInstruction {
|
return Err(vm::Error::BadInstruction {
|
||||||
instruction: instruction as u8
|
instruction: instruction as u8
|
||||||
@ -847,6 +853,9 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
instructions::CHAINID => {
|
instructions::CHAINID => {
|
||||||
self.stack.push(ext.chain_id().into())
|
self.stack.push(ext.chain_id().into())
|
||||||
},
|
},
|
||||||
|
instructions::SELFBALANCE => {
|
||||||
|
self.stack.push(ext.balance(&self.params.address)?);
|
||||||
|
}
|
||||||
|
|
||||||
// Stack instructions
|
// Stack instructions
|
||||||
|
|
||||||
|
@ -124,6 +124,32 @@ fn test_origin(factory: super::Factory) {
|
|||||||
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
|
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evm_test!{test_selfbalance: test_selfbalance_int}
|
||||||
|
fn test_selfbalance(factory: super::Factory) {
|
||||||
|
let own_addr = Address::from_str("1337000000000000000000000000000000000000").unwrap();
|
||||||
|
// 47 SELFBALANCE
|
||||||
|
// 60 ff PUSH ff
|
||||||
|
// 55 SSTORE
|
||||||
|
let code = hex!("47 60 ff 55").to_vec();
|
||||||
|
|
||||||
|
let mut params = ActionParams::default();
|
||||||
|
params.address = own_addr.clone();
|
||||||
|
params.gas = U256::from(100_000);
|
||||||
|
params.code = Some(Arc::new(code));
|
||||||
|
let mut ext = FakeExt::new_istanbul();
|
||||||
|
ext.balances = {
|
||||||
|
let mut x = HashMap::new();
|
||||||
|
x.insert(own_addr, U256::from(1_025)); // 0x401
|
||||||
|
x
|
||||||
|
};
|
||||||
|
let gas_left = {
|
||||||
|
let vm = factory.create(params, ext.schedule(), ext.depth());
|
||||||
|
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
|
||||||
|
};
|
||||||
|
assert_eq!(gas_left, U256::from(79_992)); // TODO[dvdplm]: do the sums here, SELFBALANCE-5 + PUSH1-3 + ONEBYTE-4 + SSTORE-?? = 100_000 - 79_992
|
||||||
|
assert_store(&ext, 0xff, "0000000000000000000000000000000000000000000000000000000000000401");
|
||||||
|
}
|
||||||
|
|
||||||
evm_test!{test_sender: test_sender_int}
|
evm_test!{test_sender: test_sender_int}
|
||||||
fn test_sender(factory: super::Factory) {
|
fn test_sender(factory: super::Factory) {
|
||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
|
@ -92,6 +92,8 @@ pub struct CommonParams {
|
|||||||
pub eip1014_transition: BlockNumber,
|
pub eip1014_transition: BlockNumber,
|
||||||
/// Number of first block where EIP-1344 rules begin: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md
|
/// Number of first block where EIP-1344 rules begin: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md
|
||||||
pub eip1344_transition: BlockNumber,
|
pub eip1344_transition: BlockNumber,
|
||||||
|
/// Number of first block where EIP-1884 rules begin:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1884.md
|
||||||
|
pub eip1884_transition: BlockNumber,
|
||||||
/// Number of first block where EIP-2028 rules begin.
|
/// Number of first block where EIP-2028 rules begin.
|
||||||
pub eip2028_transition: BlockNumber,
|
pub eip2028_transition: BlockNumber,
|
||||||
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
|
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
|
||||||
@ -165,6 +167,13 @@ impl CommonParams {
|
|||||||
schedule.have_extcodehash = block_number >= self.eip1052_transition;
|
schedule.have_extcodehash = block_number >= self.eip1052_transition;
|
||||||
schedule.have_chain_id = block_number >= self.eip1344_transition;
|
schedule.have_chain_id = block_number >= self.eip1344_transition;
|
||||||
schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition);
|
schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition);
|
||||||
|
|
||||||
|
if block_number >= self.eip1884_transition {
|
||||||
|
schedule.have_selfbalance = true;
|
||||||
|
schedule.sload_gas = 800;
|
||||||
|
schedule.balance_gas = 700;
|
||||||
|
schedule.extcodehash_gas = 700;
|
||||||
|
}
|
||||||
if block_number >= self.eip2028_transition {
|
if block_number >= self.eip2028_transition {
|
||||||
schedule.tx_data_non_zero_gas = 16;
|
schedule.tx_data_non_zero_gas = 16;
|
||||||
}
|
}
|
||||||
@ -289,6 +298,10 @@ impl From<ethjson::spec::Params> for CommonParams {
|
|||||||
BlockNumber::max_value,
|
BlockNumber::max_value,
|
||||||
Into::into,
|
Into::into,
|
||||||
),
|
),
|
||||||
|
eip1884_transition: p.eip1884_transition.map_or_else(
|
||||||
|
BlockNumber::max_value,
|
||||||
|
Into::into,
|
||||||
|
),
|
||||||
eip2028_transition: p.eip2028_transition.map_or_else(
|
eip2028_transition: p.eip2028_transition.map_or_else(
|
||||||
BlockNumber::max_value,
|
BlockNumber::max_value,
|
||||||
Into::into,
|
Into::into,
|
||||||
|
@ -91,7 +91,7 @@ pub trait Ext {
|
|||||||
|
|
||||||
/// Creates new contract.
|
/// Creates new contract.
|
||||||
///
|
///
|
||||||
/// Returns gas_left and contract address if contract creation was succesfull.
|
/// Returns gas_left and contract address if contract creation was successful.
|
||||||
fn create(
|
fn create(
|
||||||
&mut self,
|
&mut self,
|
||||||
gas: &U256,
|
gas: &U256,
|
||||||
|
@ -44,11 +44,7 @@ impl ReturnData {
|
|||||||
}
|
}
|
||||||
/// Create `ReturnData` from give buffer and slice.
|
/// Create `ReturnData` from give buffer and slice.
|
||||||
pub fn new(mem: Vec<u8>, offset: usize, size: usize) -> Self {
|
pub fn new(mem: Vec<u8>, offset: usize, size: usize) -> Self {
|
||||||
ReturnData {
|
ReturnData { mem, offset, size }
|
||||||
mem: mem,
|
|
||||||
offset: offset,
|
|
||||||
size: size,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,13 @@ use std::collections::HashMap;
|
|||||||
use ethereum_types::U256;
|
use ethereum_types::U256;
|
||||||
|
|
||||||
/// Definition of schedules that can be applied to a version.
|
/// Definition of schedules that can be applied to a version.
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum VersionedSchedule {
|
pub enum VersionedSchedule {
|
||||||
PWasm,
|
PWasm,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Definition of the cost schedule and other parameterisations for the EVM.
|
/// Definition of the cost schedule and other parameterisations for the EVM.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Schedule {
|
pub struct Schedule {
|
||||||
/// Does it support exceptional failed code deposit
|
/// Does it support exceptional failed code deposit
|
||||||
pub exceptional_failed_code_deposit: bool,
|
pub exceptional_failed_code_deposit: bool,
|
||||||
@ -124,6 +126,8 @@ pub struct Schedule {
|
|||||||
pub have_bitwise_shifting: bool,
|
pub have_bitwise_shifting: bool,
|
||||||
/// CHAINID opcode enabled.
|
/// CHAINID opcode enabled.
|
||||||
pub have_chain_id: bool,
|
pub have_chain_id: bool,
|
||||||
|
/// SELFBALANCE opcode enabled.
|
||||||
|
pub have_selfbalance: bool,
|
||||||
/// Kill basic accounts below this balance if touched.
|
/// Kill basic accounts below this balance if touched.
|
||||||
pub kill_dust: CleanDustMode,
|
pub kill_dust: CleanDustMode,
|
||||||
/// Enable EIP-1283 rules
|
/// Enable EIP-1283 rules
|
||||||
@ -139,6 +143,7 @@ pub struct Schedule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wasm cost table
|
/// Wasm cost table
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct WasmCosts {
|
pub struct WasmCosts {
|
||||||
/// Default opcode cost
|
/// Default opcode cost
|
||||||
pub regular: u32,
|
pub regular: u32,
|
||||||
@ -192,7 +197,7 @@ impl Default for WasmCosts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Dust accounts cleanup mode.
|
/// Dust accounts cleanup mode.
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum CleanDustMode {
|
pub enum CleanDustMode {
|
||||||
/// Dust cleanup is disabled.
|
/// Dust cleanup is disabled.
|
||||||
Off,
|
Off,
|
||||||
@ -223,6 +228,7 @@ impl Schedule {
|
|||||||
have_return_data: false,
|
have_return_data: false,
|
||||||
have_bitwise_shifting: false,
|
have_bitwise_shifting: false,
|
||||||
have_chain_id: false,
|
have_chain_id: false,
|
||||||
|
have_selfbalance: false,
|
||||||
have_extcodehash: false,
|
have_extcodehash: false,
|
||||||
stack_limit: 1024,
|
stack_limit: 1024,
|
||||||
max_depth: 1024,
|
max_depth: 1024,
|
||||||
@ -294,8 +300,12 @@ impl Schedule {
|
|||||||
/// Schedule for the Istanbul fork of the Ethereum main net.
|
/// Schedule for the Istanbul fork of the Ethereum main net.
|
||||||
pub fn new_istanbul() -> Schedule {
|
pub fn new_istanbul() -> Schedule {
|
||||||
let mut schedule = Self::new_constantinople();
|
let mut schedule = Self::new_constantinople();
|
||||||
schedule.have_chain_id = true;
|
schedule.have_chain_id = true; // EIP 1344
|
||||||
schedule.tx_data_non_zero_gas = 16;
|
schedule.tx_data_non_zero_gas = 16; // EIP 2028
|
||||||
|
schedule.sload_gas = 800; // EIP 1884
|
||||||
|
schedule.balance_gas = 700; // EIP 1884
|
||||||
|
schedule.extcodehash_gas = 700; // EIP 1884
|
||||||
|
schedule.have_selfbalance = true; // EIP 1884
|
||||||
schedule
|
schedule
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,6 +318,7 @@ impl Schedule {
|
|||||||
have_return_data: false,
|
have_return_data: false,
|
||||||
have_bitwise_shifting: false,
|
have_bitwise_shifting: false,
|
||||||
have_chain_id: false,
|
have_chain_id: false,
|
||||||
|
have_selfbalance: false,
|
||||||
have_extcodehash: false,
|
have_extcodehash: false,
|
||||||
stack_limit: 1024,
|
stack_limit: 1024,
|
||||||
max_depth: 1024,
|
max_depth: 1024,
|
||||||
|
@ -96,6 +96,8 @@ pub struct Params {
|
|||||||
/// See `CommonParams` docs.
|
/// See `CommonParams` docs.
|
||||||
pub eip1344_transition: Option<Uint>,
|
pub eip1344_transition: Option<Uint>,
|
||||||
/// See `CommonParams` docs.
|
/// See `CommonParams` docs.
|
||||||
|
pub eip1884_transition: Option<Uint>,
|
||||||
|
/// See `CommonParams` docs.
|
||||||
pub eip2028_transition: Option<Uint>,
|
pub eip2028_transition: Option<Uint>,
|
||||||
/// See `CommonParams` docs.
|
/// See `CommonParams` docs.
|
||||||
pub dust_protection_transition: Option<Uint>,
|
pub dust_protection_transition: Option<Uint>,
|
||||||
|
Loading…
Reference in New Issue
Block a user