Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

v2.5.8-stable (rev2) #11051

Merged
merged 2 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 12 additions & 6 deletions ethcore/evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,18 @@ pub trait Finalize {
impl Finalize for Result<GasLeft> {
fn finalize<E: Ext>(self, ext: E) -> Result<FinalizationResult> {
match self {
Ok(GasLeft::Known(gas_left)) => Ok(FinalizationResult { gas_left: gas_left, apply_state: true, 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: gas_left,
apply_state: apply_state,
return_data: data,
}),
Ok(GasLeft::Known(gas_left)) => {
Ok(FinalizationResult {
gas_left,
apply_state: true,
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),
}
}
Expand Down
3 changes: 3 additions & 0 deletions ethcore/evm/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ enum_with_from_u8! {
GASLIMIT = 0x45,
#[doc = "get chain ID"]
CHAINID = 0x46,
#[doc = "get balance of own account"]
SELFBALANCE = 0x47,

#[doc = "remove item from stack"]
POP = 0x50,
Expand Down Expand Up @@ -502,6 +504,7 @@ lazy_static! {
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[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[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow));
arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow));
Expand Down
3 changes: 3 additions & 0 deletions ethcore/evm/src/interpreter/gasometer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
Request::Gas(Gas::from(1))
},
instructions::SSTORE => {
if schedule.eip1706 && self.current_gas <= Gas::from(schedule.call_stipend) {
return Err(vm::Error::OutOfGas);
}
let address = H256::from(stack.peek(0));
let newval = stack.peek(1);
let val = U256::from(&*ext.storage_at(&address)?);
Expand Down
15 changes: 12 additions & 3 deletions ethcore/evm/src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,12 @@ impl<Cost: CostType> Interpreter<Cost> {
let result = if self.gasometer.is_none() {
InterpreterResult::Done(Err(vm::Error::OutOfGas))
} 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 {
self.step_inner(ext)
};
Expand All @@ -317,7 +322,7 @@ impl<Cost: CostType> Interpreter<Cost> {
self.done = true;
self.informant.done();
}
return result;
result
}

/// Inner helper function for step.
Expand Down Expand Up @@ -446,7 +451,8 @@ impl<Cost: CostType> Interpreter<Cost> {
(instruction == instructions::REVERT && !schedule.have_revert) ||
((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) ||
(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 {
instruction: instruction as u8
Expand Down Expand Up @@ -864,6 +870,9 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::CHAINID => {
self.stack.push(ext.chain_id().into())
},
instructions::SELFBALANCE => {
self.stack.push(ext.balance(&self.params.address)?);
}

// Stack instructions

Expand Down
26 changes: 26 additions & 0 deletions ethcore/evm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,32 @@ fn test_origin(factory: super::Factory) {
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}
fn test_sender(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
Expand Down
33 changes: 31 additions & 2 deletions ethcore/src/spec/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn fmt_err<F: ::std::fmt::Display>(f: F) -> String {
/// we define a "bugfix" hard fork as any hard fork which
/// you would put on-by-default in a new chain.
#[derive(Debug, PartialEq, Default)]
#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))]
#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))]
pub struct CommonParams {
/// Account start nonce.
pub account_start_nonce: U256,
Expand Down Expand Up @@ -121,10 +121,16 @@ pub struct CommonParams {
pub eip1283_transition: BlockNumber,
/// Number of first block where EIP-1283 rules end.
pub eip1283_disable_transition: BlockNumber,
/// Number of first block where EIP-1283 rules re-enabled.
pub eip1283_reenable_transition: BlockNumber,
/// Number of first block where EIP-1014 rules begin.
pub eip1014_transition: BlockNumber,
/// Number of first block where EIP-1706 rules begin.
pub eip1706_transition: BlockNumber,
/// Number of first block where EIP-1344 rules begin: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md
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.
pub eip2028_transition: BlockNumber,
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
Expand Down Expand Up @@ -194,7 +200,18 @@ impl CommonParams {
schedule.have_bitwise_shifting = block_number >= self.eip145_transition;
schedule.have_extcodehash = block_number >= self.eip1052_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)) ||
block_number >= self.eip1283_reenable_transition;
schedule.eip1706 = block_number >= self.eip1706_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 {
schedule.tx_data_non_zero_gas = 16;
}
Expand Down Expand Up @@ -312,6 +329,14 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value,
Into::into,
),
eip1283_reenable_transition: p.eip1283_reenable_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip1706_transition: p.eip1706_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip1014_transition: p.eip1014_transition.map_or_else(
BlockNumber::max_value,
Into::into,
Expand All @@ -320,6 +345,10 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value,
Into::into,
),
eip1884_transition: p.eip1884_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip2028_transition: p.eip2028_transition.map_or_else(
BlockNumber::max_value,
Into::into,
Expand Down
2 changes: 1 addition & 1 deletion ethcore/vm/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub trait Ext {

/// 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(
&mut self,
gas: &U256,
Expand Down
6 changes: 1 addition & 5 deletions ethcore/vm/src/return_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ impl ReturnData {
}
/// Create `ReturnData` from give buffer and slice.
pub fn new(mem: Vec<u8>, offset: usize, size: usize) -> Self {
ReturnData {
mem: mem,
offset: offset,
size: size,
}
ReturnData { mem, offset, size }
}
}

Expand Down
28 changes: 25 additions & 3 deletions ethcore/vm/src/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.

//! Cost schedule and other parameterisations for the EVM.
use std::collections::HashMap;
use ethereum_types::U256;

/// Definition of schedules that can be applied to a version.
#[derive(Debug)]
pub enum VersionedSchedule {
PWasm,
}

/// Definition of the cost schedule and other parameterisations for the EVM.
#[derive(Debug)]
pub struct Schedule {
/// Does it support exceptional failed code deposit
pub exceptional_failed_code_deposit: bool,
Expand Down Expand Up @@ -117,17 +126,22 @@ pub struct Schedule {
pub have_bitwise_shifting: bool,
/// CHAINID opcode enabled.
pub have_chain_id: bool,
/// SELFBALANCE opcode enabled.
pub have_selfbalance: bool,
/// Kill basic accounts below this balance if touched.
pub kill_dust: CleanDustMode,
/// Enable EIP-1283 rules
pub eip1283: bool,
/// Enable EIP-1706 rules
pub eip1706: bool,
/// VM execution does not increase null signed address nonce if this field is true.
pub keep_unsigned_nonce: bool,
/// Wasm extra schedule settings, if wasm activated
pub wasm: Option<WasmCosts>,
}

/// Wasm cost table
#[derive(Debug)]
pub struct WasmCosts {
/// Default opcode cost
pub regular: u32,
Expand Down Expand Up @@ -181,7 +195,7 @@ impl Default for WasmCosts {
}

/// Dust accounts cleanup mode.
#[derive(PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub enum CleanDustMode {
/// Dust cleanup is disabled.
Off,
Expand Down Expand Up @@ -212,6 +226,7 @@ impl Schedule {
have_return_data: false,
have_bitwise_shifting: false,
have_chain_id: false,
have_selfbalance: false,
have_extcodehash: false,
stack_limit: 1024,
max_depth: 1024,
Expand Down Expand Up @@ -256,6 +271,7 @@ impl Schedule {
have_static_call: false,
kill_dust: CleanDustMode::Off,
eip1283: false,
eip1706: false,
keep_unsigned_nonce: false,
wasm: None,
}
Expand All @@ -281,8 +297,12 @@ impl Schedule {
/// Schedule for the Istanbul fork of the Ethereum main net.
pub fn new_istanbul() -> Schedule {
let mut schedule = Self::new_constantinople();
schedule.have_chain_id = true;
schedule.tx_data_non_zero_gas = 16;
schedule.have_chain_id = true; // EIP 1344
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
}

Expand All @@ -295,6 +315,7 @@ impl Schedule {
have_return_data: false,
have_bitwise_shifting: false,
have_chain_id: false,
have_selfbalance: false,
have_extcodehash: false,
stack_limit: 1024,
max_depth: 1024,
Expand Down Expand Up @@ -339,6 +360,7 @@ impl Schedule {
have_static_call: false,
kill_dust: CleanDustMode::Off,
eip1283: false,
eip1706: false,
keep_unsigned_nonce: false,
wasm: None,
}
Expand Down
6 changes: 6 additions & 0 deletions json/src/spec/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,16 @@ pub struct Params {
/// See `CommonParams` docs.
pub eip1283_disable_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip1283_reenable_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip1014_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip1706_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip1344_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip1884_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip2028_transition: Option<Uint>,
/// See `CommonParams` docs.
pub dust_protection_transition: Option<Uint>,
Expand Down