From 4955c2e1b17ea86c5addb5c7146c80c1a9b61ce5 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 19 Jul 2018 15:12:54 +0800 Subject: [PATCH 1/9] Basic implementation for kip4 --- ethcore/vm/src/schedule.rs | 3 ++ ethcore/wasm/src/env.rs | 15 ++++++- ethcore/wasm/src/lib.rs | 2 +- ethcore/wasm/src/runtime.rs | 82 ++++++++++++++++++++++++++----------- 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index 960821e72c7..fcbd05675c0 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -145,6 +145,8 @@ pub struct WasmCosts { pub opcodes_mul: u32, /// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div` pub opcodes_div: u32, + /// Whether create2 extern function is activated. + pub have_create2: bool, } impl Default for WasmCosts { @@ -162,6 +164,7 @@ impl Default for WasmCosts { max_stack_height: 64*1024, opcodes_mul: 3, opcodes_div: 8, + have_create2: false, } } } diff --git a/ethcore/wasm/src/env.rs b/ethcore/wasm/src/env.rs index 9bcbee63fb0..a9e536f5f1f 100644 --- a/ethcore/wasm/src/env.rs +++ b/ethcore/wasm/src/env.rs @@ -17,6 +17,7 @@ //! Env module glue for wasmi interpreter use std::cell::RefCell; +use vm::WasmCosts; use wasmi::{ self, Signature, Error, FuncRef, FuncInstance, MemoryDescriptor, MemoryRef, MemoryInstance, memory_units, @@ -47,6 +48,7 @@ pub mod ids { pub const SENDER_FUNC: usize = 190; pub const ORIGIN_FUNC: usize = 200; pub const ELOG_FUNC: usize = 210; + pub const CREATE2_FUNC: usize = 220; pub const PANIC_FUNC: usize = 1000; pub const DEBUG_FUNC: usize = 1010; @@ -125,6 +127,11 @@ pub mod signatures { Some(I32), ); + pub const CREATE2: StaticSignature = StaticSignature( + &[I32, I32, I32, I32, I32], + Some(I32), + ); + pub const SUICIDE: StaticSignature = StaticSignature( &[I32], None, @@ -195,18 +202,21 @@ fn host(signature: signatures::StaticSignature, idx: usize) -> FuncRef { /// Maps all functions that runtime support to the corresponding contract import /// entries. /// Also manages initial memory request from the runtime. -#[derive(Default)] pub struct ImportResolver { max_memory: u32, memory: RefCell>, + + have_create2: bool, } impl ImportResolver { /// New import resolver with specifed maximum amount of inital memory (in wasm pages = 64kb) - pub fn with_limit(max_memory: u32) -> ImportResolver { + pub fn with_limit(max_memory: u32, schedule: &WasmCosts) -> ImportResolver { ImportResolver { max_memory: max_memory, memory: RefCell::new(None), + + have_create2: schedule.have_create2, } } @@ -263,6 +273,7 @@ impl wasmi::ModuleImportResolver for ImportResolver { "sender" => host(signatures::SENDER, ids::SENDER_FUNC), "origin" => host(signatures::ORIGIN, ids::ORIGIN_FUNC), "elog" => host(signatures::ELOG, ids::ELOG_FUNC), + "create2" if self.have_create2 => host(signatures::CREATE2, ids::CREATE2_FUNC), _ => { return Err(wasmi::Error::Instantiation( format!("Export {} not found", field_name), diff --git a/ethcore/wasm/src/lib.rs b/ethcore/wasm/src/lib.rs index f1290318e0f..1fcfe9371ee 100644 --- a/ethcore/wasm/src/lib.rs +++ b/ethcore/wasm/src/lib.rs @@ -90,7 +90,7 @@ impl vm::Vm for WasmInterpreter { let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?; - let instantiation_resolver = env::ImportResolver::with_limit(16); + let instantiation_resolver = env::ImportResolver::with_limit(16, ext.schedule().wasm()); let module_instance = wasmi::ModuleInstance::new( &loaded_module, diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index d99ab8645a1..01fc3c8231e 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -321,7 +321,7 @@ impl<'a> Runtime<'a> { if self.gas_counter > self.gas_limit { return Err(Error::InvalidGasState); } Ok(self.gas_limit - self.gas_counter) } - + /// General gas charging extern. fn gas(&mut self, args: RuntimeArgs) -> Result<()> { let amount: u32 = args.nth_checked(0)?; @@ -511,29 +511,7 @@ impl<'a> Runtime<'a> { self.return_u256_ptr(args.nth_checked(0)?, val) } - /// Creates a new contract - /// - /// Arguments: - /// * endowment - how much value (in Wei) transfer to the newly created contract - /// * code_ptr - pointer to the code data - /// * code_len - lenght of the code data - /// * result_ptr - pointer to write an address of the newly created contract - pub fn create(&mut self, args: RuntimeArgs) -> Result - { - // - // method signature: - // fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32; - // - trace!(target: "wasm", "runtime: CREATE"); - let endowment = self.u256_at(args.nth_checked(0)?)?; - trace!(target: "wasm", " val: {:?}", endowment); - let code_ptr: u32 = args.nth_checked(1)?; - trace!(target: "wasm", " code_ptr: {:?}", code_ptr); - let code_len: u32 = args.nth_checked(2)?; - trace!(target: "wasm", " code_len: {:?}", code_len); - let result_ptr: u32 = args.nth_checked(3)?; - trace!(target: "wasm", "result_ptr: {:?}", result_ptr); - + fn do_create(&mut self, endowment: U256, code_ptr: u32, code_len: u32, result_ptr: u32, scheme: vm::CreateContractAddress) -> Result { let code = self.memory.get(code_ptr, code_len as usize)?; self.adjusted_charge(|schedule| schedule.create_gas as u64)?; @@ -543,7 +521,7 @@ impl<'a> Runtime<'a> { * U256::from(self.ext.schedule().wasm().opcodes_mul) / U256::from(self.ext.schedule().wasm().opcodes_div); - match self.ext.create(&gas_left, &endowment, &code, vm::CreateContractAddress::FromSenderAndCodeHash) { + match self.ext.create(&gas_left, &endowment, &code, scheme) { vm::ContractCreateResult::Created(address, gas_left) => { self.memory.set(result_ptr, &*address)?; self.gas_counter = self.gas_limit - @@ -571,6 +549,59 @@ impl<'a> Runtime<'a> { } } + /// Creates a new contract + /// + /// Arguments: + /// * endowment - how much value (in Wei) transfer to the newly created contract + /// * code_ptr - pointer to the code data + /// * code_len - lenght of the code data + /// * result_ptr - pointer to write an address of the newly created contract + pub fn create(&mut self, args: RuntimeArgs) -> Result { + // + // method signature: + // fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32; + // + trace!(target: "wasm", "runtime: CREATE"); + let endowment = self.u256_at(args.nth_checked(0)?)?; + trace!(target: "wasm", " val: {:?}", endowment); + let code_ptr: u32 = args.nth_checked(1)?; + trace!(target: "wasm", " code_ptr: {:?}", code_ptr); + let code_len: u32 = args.nth_checked(2)?; + trace!(target: "wasm", " code_len: {:?}", code_len); + let result_ptr: u32 = args.nth_checked(3)?; + trace!(target: "wasm", "result_ptr: {:?}", result_ptr); + + self.do_create(endowment, code_ptr, code_len, result_ptr, vm::CreateContractAddress::FromSenderAndCodeHash) + } + + /// Creates a new contract using FromSenderSaltAndCodeHash scheme + /// + /// Arguments: + /// * endowment - how much value (in Wei) transfer to the newly created contract + /// * salt - salt to be used in contract creation address + /// * code_ptr - pointer to the code data + /// * code_len - lenght of the code data + /// * result_ptr - pointer to write an address of the newly created contract + pub fn create2(&mut self, args: RuntimeArgs) -> Result { + // + // method signature: + // fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32; + // + trace!(target: "wasm", "runtime: CREATE2"); + let endowment = self.u256_at(args.nth_checked(0)?)?; + trace!(target: "wasm", " val: {:?}", endowment); + let salt: H256 = self.u256_at(args.nth_checked(0)?)?.into(); + trace!(target: "wasm", " salt: {:?}", salt); + let code_ptr: u32 = args.nth_checked(1)?; + trace!(target: "wasm", " code_ptr: {:?}", code_ptr); + let code_len: u32 = args.nth_checked(2)?; + trace!(target: "wasm", " code_len: {:?}", code_len); + let result_ptr: u32 = args.nth_checked(3)?; + trace!(target: "wasm", "result_ptr: {:?}", result_ptr); + + self.do_create(endowment, code_ptr, code_len, result_ptr, vm::CreateContractAddress::FromSenderSaltAndCodeHash(salt)) + } + fn debug(&mut self, args: RuntimeArgs) -> Result<()> { trace!(target: "wasm", "Contract debug message: {}", { @@ -744,6 +775,7 @@ mod ext_impl { SENDER_FUNC => void!(self.sender(args)), ORIGIN_FUNC => void!(self.origin(args)), ELOG_FUNC => void!(self.elog(args)), + CREATE2_FUNC => some!(self.create2(args)), _ => panic!("env module doesn't provide function at index {}", index), } } From 280a0dc8e62d92a5186946391b05dd59603ab267 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 3 Aug 2018 17:54:22 +0800 Subject: [PATCH 2/9] Add KIP-4 config flags --- ethcore/src/spec/spec.rs | 12 +++++++++++- json/src/spec/params.rs | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index d79775f788a..45f9a6c9556 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -125,6 +125,8 @@ pub struct CommonParams { pub remove_dust_contracts: bool, /// Wasm activation blocknumber, if any disabled initially. pub wasm_activation_transition: BlockNumber, + /// Number of first block where KIP-4 rules begin. Only has effect if Wasm is activated. + pub kip4_transition: BlockNumber, /// Gas limit bound divisor (how much gas limit can change per block) pub gas_limit_bound_divisor: U256, /// Registrar contract address. @@ -187,7 +189,11 @@ impl CommonParams { }; } if block_number >= self.wasm_activation_transition { - schedule.wasm = Some(Default::default()); + let mut wasm = ::vm::WasmCosts::default(); + if block_number >= self.kip4_transition { + wasm.have_create2 = true; + } + schedule.wasm = Some(wasm); } } @@ -294,6 +300,10 @@ impl From for CommonParams { BlockNumber::max_value, Into::into ), + kip4_transition: p.kip4_transition.map_or_else( + BlockNumber::max_value, + Into::into + ), } } } diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index a37e4f23ba8..0fab68198ac 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -146,6 +146,9 @@ pub struct Params { /// Wasm activation block height, if not activated from start #[serde(rename="wasmActivationTransition")] pub wasm_activation_transition: Option, + /// KIP4 activiation block height. + #[serde(rename="kip4Transition")] + pub kip4_transition: Option, } #[cfg(test)] From b926c6ede4c76823f5e3689b1ef2544291538ba6 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 3 Aug 2018 17:57:23 +0800 Subject: [PATCH 3/9] typo: docs fix --- ethcore/wasm/src/runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index 01fc3c8231e..cc9316d3e78 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -585,7 +585,7 @@ impl<'a> Runtime<'a> { pub fn create2(&mut self, args: RuntimeArgs) -> Result { // // method signature: - // fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32; + // fn create2(endowment: *const u8, salt: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32; // trace!(target: "wasm", "runtime: CREATE2"); let endowment = self.u256_at(args.nth_checked(0)?)?; From 38cac51bfc3b5e7fdab5a2fbd93c422b31cb75d9 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 3 Aug 2018 20:57:42 +0800 Subject: [PATCH 4/9] Fix args offset --- ethcore/wasm/src/runtime.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index cc9316d3e78..347023dd97c 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -590,13 +590,13 @@ impl<'a> Runtime<'a> { trace!(target: "wasm", "runtime: CREATE2"); let endowment = self.u256_at(args.nth_checked(0)?)?; trace!(target: "wasm", " val: {:?}", endowment); - let salt: H256 = self.u256_at(args.nth_checked(0)?)?.into(); + let salt: H256 = self.u256_at(args.nth_checked(1)?)?.into(); trace!(target: "wasm", " salt: {:?}", salt); - let code_ptr: u32 = args.nth_checked(1)?; + let code_ptr: u32 = args.nth_checked(2)?; trace!(target: "wasm", " code_ptr: {:?}", code_ptr); - let code_len: u32 = args.nth_checked(2)?; + let code_len: u32 = args.nth_checked(3)?; trace!(target: "wasm", " code_len: {:?}", code_len); - let result_ptr: u32 = args.nth_checked(3)?; + let result_ptr: u32 = args.nth_checked(4)?; trace!(target: "wasm", "result_ptr: {:?}", result_ptr); self.do_create(endowment, code_ptr, code_len, result_ptr, vm::CreateContractAddress::FromSenderSaltAndCodeHash(salt)) From 3c8641820b8b917d4c936853c556e761cc45b59a Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 6 Aug 2018 17:33:56 +0800 Subject: [PATCH 5/9] Add tests for create2 --- ethcore/res/wasm-tests | 2 +- ethcore/vm/src/ext.rs | 2 +- ethcore/vm/src/tests.rs | 5 ++++- ethcore/wasm/src/tests.rs | 35 ++++++++++++++++++++++++++++------- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index 474110de59a..a2202e0ba94 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit 474110de59a0f632b20615256c913b144c49354c +Subproject commit a2202e0ba9434533cc7483e75a3c9b2c7781c34e diff --git a/ethcore/vm/src/ext.rs b/ethcore/vm/src/ext.rs index 3e6ee1e0265..c1ce1b79f0b 100644 --- a/ethcore/vm/src/ext.rs +++ b/ethcore/vm/src/ext.rs @@ -51,7 +51,7 @@ pub enum MessageCallResult { } /// Specifies how an address is calculated for a new contract. -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub enum CreateContractAddress { /// Address is calculated from sender and nonce. Pre EIP-86 (Metropolis) FromSenderAndNonce, diff --git a/ethcore/vm/src/tests.rs b/ethcore/vm/src/tests.rs index d83e6881a12..4930e4219ba 100644 --- a/ethcore/vm/src/tests.rs +++ b/ethcore/vm/src/tests.rs @@ -39,6 +39,7 @@ pub enum FakeCallType { #[derive(PartialEq, Eq, Hash, Debug)] pub struct FakeCall { pub call_type: FakeCallType, + pub create_scheme: Option, pub gas: U256, pub sender_address: Option
, pub receive_address: Option
, @@ -133,9 +134,10 @@ impl Ext for FakeExt { self.blockhashes.get(number).unwrap_or(&H256::new()).clone() } - fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult { + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult { self.calls.insert(FakeCall { call_type: FakeCallType::Create, + create_scheme: Some(address), gas: *gas, sender_address: None, receive_address: None, @@ -159,6 +161,7 @@ impl Ext for FakeExt { self.calls.insert(FakeCall { call_type: FakeCallType::Call, + create_scheme: None, gas: *gas, sender_address: Some(sender_address.clone()), receive_address: Some(receive_address.clone()), diff --git a/ethcore/wasm/src/tests.rs b/ethcore/wasm/src/tests.rs index 726b9ebabbb..1eab092462a 100644 --- a/ethcore/wasm/src/tests.rs +++ b/ethcore/wasm/src/tests.rs @@ -20,7 +20,7 @@ use byteorder::{LittleEndian, ByteOrder}; use ethereum_types::{H256, U256, Address}; use super::WasmInterpreter; -use vm::{self, Vm, GasLeft, ActionParams, ActionValue}; +use vm::{self, Vm, GasLeft, ActionParams, ActionValue, CreateContractAddress}; use vm::tests::{FakeCall, FakeExt, FakeCallType}; macro_rules! load_sample { @@ -281,14 +281,19 @@ fn create() { params.value = ActionValue::transfer(1_000_000_000); let mut ext = FakeExt::new().with_wasm(); + ext.schedule.wasm.as_mut().unwrap().have_create2 = true; let gas_left = { let mut interpreter = wasm_interpreter(); let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); match result { - GasLeft::Known(gas) => gas, - GasLeft::NeedsReturn { .. } => { - panic!("Create contract should not return anthing because ext always fails on creation"); + GasLeft::Known(_) => { + panic!("Create contract always return 40 bytes of the creation address, or in the case where it fails, return 40 bytes of zero."); + }, + GasLeft::NeedsReturn { gas_left, data, apply_state } => { + assert!(apply_state); + assert_eq!(data.as_ref(), [0u8; 40].as_ref()); // FakeExt never succeeds in create. + gas_left }, } }; @@ -297,15 +302,28 @@ fn create() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Create, - gas: U256::from(59_269), + create_scheme: Some(CreateContractAddress::FromSenderAndCodeHash), + gas: U256::from(52_018), + sender_address: None, + receive_address: None, + value: Some((1_000_000_000 / 2).into()), + data: vec![0u8, 2, 4, 8, 16, 32, 64, 128], + code_address: None, + } + )); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Create, + create_scheme: Some(CreateContractAddress::FromSenderSaltAndCodeHash(H256::default())), + gas: U256::from(10_746), sender_address: None, receive_address: None, - value: Some(1_000_000_000.into()), + value: Some((1_000_000_000 / 2).into()), data: vec![0u8, 2, 4, 8, 16, 32, 64, 128], code_address: None, } )); - assert_eq!(gas_left, U256::from(59_212)); + assert_eq!(gas_left, U256::from(10_680)); } #[test] @@ -340,6 +358,7 @@ fn call_msg() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Call, + create_scheme: None, gas: U256::from(33_000), sender_address: Some(receiver), receive_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])), @@ -382,6 +401,7 @@ fn call_code() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Call, + create_scheme: None, gas: U256::from(20_000), sender_address: Some(sender), receive_address: Some(receiver), @@ -429,6 +449,7 @@ fn call_static() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Call, + create_scheme: None, gas: U256::from(20_000), sender_address: Some(receiver), receive_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()), From 366899aa51203de89b30f976a2ab695379e0fb31 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 6 Aug 2018 17:52:34 +0800 Subject: [PATCH 6/9] tests: evm --- ethcore/evm/src/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index b62faf87d77..b8f0df3639d 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -746,6 +746,7 @@ fn test_calls(factory: super::Factory) { assert_set_contains(&ext.calls, &FakeCall { call_type: FakeCallType::Call, + create_scheme: None, gas: U256::from(2556), sender_address: Some(address.clone()), receive_address: Some(code_address.clone()), @@ -755,6 +756,7 @@ fn test_calls(factory: super::Factory) { }); assert_set_contains(&ext.calls, &FakeCall { call_type: FakeCallType::Call, + create_scheme: None, gas: U256::from(2556), sender_address: Some(address.clone()), receive_address: Some(address.clone()), From 1d631dff331cf2b4efc9d1ea8b55aa6e463dab0e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 6 Aug 2018 20:28:20 +0800 Subject: [PATCH 7/9] Update wasm-tests and fix all gas costs --- ethcore/res/wasm-tests | 2 +- ethcore/wasm/src/tests.rs | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index a2202e0ba94..d05e071b484 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit a2202e0ba9434533cc7483e75a3c9b2c7781c34e +Subproject commit d05e071b4842c6709dfc36c61e4229eefdad9aca diff --git a/ethcore/wasm/src/tests.rs b/ethcore/wasm/src/tests.rs index 1eab092462a..fd5852f9533 100644 --- a/ethcore/wasm/src/tests.rs +++ b/ethcore/wasm/src/tests.rs @@ -207,7 +207,7 @@ fn dispersion() { result, vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0] ); - assert_eq!(gas_left, U256::from(92_371)); + assert_eq!(gas_left, U256::from(92_369)); } #[test] @@ -267,7 +267,7 @@ fn suicide() { }; assert!(ext.suicides.contains(&refund)); - assert_eq!(gas_left, U256::from(93_348)); + assert_eq!(gas_left, U256::from(93_347)); } #[test] @@ -314,7 +314,7 @@ fn create() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Create, - create_scheme: Some(CreateContractAddress::FromSenderSaltAndCodeHash(H256::default())), + create_scheme: Some(CreateContractAddress::FromSenderSaltAndCodeHash(H256::from([5u8].as_ref()))), gas: U256::from(10_746), sender_address: None, receive_address: None, @@ -414,7 +414,7 @@ fn call_code() { // siphash result let res = LittleEndian::read_u32(&result[..]); assert_eq!(res, 4198595614); - assert_eq!(gas_left, U256::from(90_038)); + assert_eq!(gas_left, U256::from(90_037)); } #[test] @@ -463,7 +463,7 @@ fn call_static() { let res = LittleEndian::read_u32(&result[..]); assert_eq!(res, 317632590); - assert_eq!(gas_left, U256::from(90_043)); + assert_eq!(gas_left, U256::from(90_042)); } // Realloc test @@ -486,7 +486,7 @@ fn realloc() { } }; assert_eq!(result, vec![0u8; 2]); - assert_eq!(gas_left, U256::from(92_842)); + assert_eq!(gas_left, U256::from(92_839)); } #[test] @@ -508,7 +508,7 @@ fn alloc() { } }; assert_eq!(result, vec![5u8; 1024*400]); - assert_eq!(gas_left, U256::from(6_893_883)); + assert_eq!(gas_left, U256::from(6_893_881)); } // Tests that contract's ability to read from a storage @@ -562,7 +562,7 @@ fn keccak() { }; assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87")); - assert_eq!(gas_left, U256::from(84_134)); + assert_eq!(gas_left, U256::from(84_133)); } // math_* tests check the ability of wasm contract to perform big integer operations @@ -677,7 +677,7 @@ fn math_div() { U256::from_dec_str("1125000").unwrap(), (&result[..]).into() ); - assert_eq!(gas_left, U256::from(87_376)); + assert_eq!(gas_left, U256::from(87_375)); } #[test] @@ -705,7 +705,7 @@ fn storage_metering() { }; // 0 -> not 0 - assert_eq!(gas_left, U256::from(72_399)); + assert_eq!(gas_left, U256::from(72_397)); // #2 @@ -724,7 +724,7 @@ fn storage_metering() { }; // not 0 -> not 0 - assert_eq!(gas_left, U256::from(87_399)); + assert_eq!(gas_left, U256::from(87_397)); } // This test checks the ability of wasm contract to invoke @@ -812,7 +812,7 @@ fn externs() { "Gas limit requested and returned does not match" ); - assert_eq!(gas_left, U256::from(90_435)); + assert_eq!(gas_left, U256::from(90_429)); } #[test] @@ -838,7 +838,7 @@ fn embedded_keccak() { }; assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87")); - assert_eq!(gas_left, U256::from(84_134)); + assert_eq!(gas_left, U256::from(84_133)); } /// This test checks the correctness of log extern @@ -873,7 +873,7 @@ fn events() { assert_eq!(&log_entry.data, b"gnihtemos"); assert_eq!(&result, b"gnihtemos"); - assert_eq!(gas_left, U256::from(81_351)); + assert_eq!(gas_left, U256::from(81_347)); } #[test] From d78aad5f1efe5a9a94ff87c9a5ecd19d1c7d5b82 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 6 Aug 2018 21:32:14 +0800 Subject: [PATCH 8/9] Update wasm-tests --- ethcore/res/wasm-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index d05e071b484..c24257cf97b 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit d05e071b4842c6709dfc36c61e4229eefdad9aca +Subproject commit c24257cf97b73a19bdb560d412df86e414fb9232 From 8bd2c8bca3a4c5dd8efbe136f4102d87b84bf3dc Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 6 Aug 2018 22:19:51 +0800 Subject: [PATCH 9/9] Update wasm-tests and fix gas costs --- ethcore/res/wasm-tests | 2 +- ethcore/wasm/src/tests.rs | 38 +++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index c24257cf97b..986a6fb9467 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit c24257cf97b73a19bdb560d412df86e414fb9232 +Subproject commit 986a6fb94673ba270f8f7ef1fff521ba33d427c2 diff --git a/ethcore/wasm/src/tests.rs b/ethcore/wasm/src/tests.rs index fd5852f9533..e72cc15c81d 100644 --- a/ethcore/wasm/src/tests.rs +++ b/ethcore/wasm/src/tests.rs @@ -138,7 +138,7 @@ fn logger() { U256::from(1_000_000_000), "Logger sets 0x04 key to the trasferred value" ); - assert_eq!(gas_left, U256::from(16_181)); + assert_eq!(gas_left, U256::from(17_716)); } // This test checks if the contract can allocate memory and pass pointer to the result stream properly. @@ -173,7 +173,7 @@ fn identity() { sender, "Idenity test contract does not return the sender passed" ); - assert_eq!(gas_left, U256::from(96_883)); + assert_eq!(gas_left, U256::from(98_419)); } // Dispersion test sends byte array and expect the contract to 'disperse' the original elements with @@ -207,7 +207,7 @@ fn dispersion() { result, vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0] ); - assert_eq!(gas_left, U256::from(92_369)); + assert_eq!(gas_left, U256::from(92_377)); } #[test] @@ -267,7 +267,7 @@ fn suicide() { }; assert!(ext.suicides.contains(&refund)); - assert_eq!(gas_left, U256::from(93_347)); + assert_eq!(gas_left, U256::from(93_346)); } #[test] @@ -303,7 +303,7 @@ fn create() { &FakeCall { call_type: FakeCallType::Create, create_scheme: Some(CreateContractAddress::FromSenderAndCodeHash), - gas: U256::from(52_018), + gas: U256::from(52_017), sender_address: None, receive_address: None, value: Some((1_000_000_000 / 2).into()), @@ -315,7 +315,7 @@ fn create() { &FakeCall { call_type: FakeCallType::Create, create_scheme: Some(CreateContractAddress::FromSenderSaltAndCodeHash(H256::from([5u8].as_ref()))), - gas: U256::from(10_746), + gas: U256::from(10_740), sender_address: None, receive_address: None, value: Some((1_000_000_000 / 2).into()), @@ -323,7 +323,7 @@ fn create() { code_address: None, } )); - assert_eq!(gas_left, U256::from(10_680)); + assert_eq!(gas_left, U256::from(10_675)); } #[test] @@ -486,7 +486,7 @@ fn realloc() { } }; assert_eq!(result, vec![0u8; 2]); - assert_eq!(gas_left, U256::from(92_839)); + assert_eq!(gas_left, U256::from(92_848)); } #[test] @@ -536,7 +536,7 @@ fn storage_read() { }; assert_eq!(Address::from(&result[12..32]), address); - assert_eq!(gas_left, U256::from(96_833)); + assert_eq!(gas_left, U256::from(98_369)); } // Tests keccak calculation @@ -562,7 +562,7 @@ fn keccak() { }; assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87")); - assert_eq!(gas_left, U256::from(84_133)); + assert_eq!(gas_left, U256::from(85_949)); } // math_* tests check the ability of wasm contract to perform big integer operations @@ -591,7 +591,7 @@ fn math_add() { U256::from_dec_str("1888888888888888888888888888887").unwrap(), (&result[..]).into() ); - assert_eq!(gas_left, U256::from(92_086)); + assert_eq!(gas_left, U256::from(92_095)); } // multiplication @@ -613,7 +613,7 @@ fn math_mul() { U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(), (&result[..]).into() ); - assert_eq!(gas_left, U256::from(91_414)); + assert_eq!(gas_left, U256::from(91_423)); } // subtraction @@ -635,7 +635,7 @@ fn math_sub() { U256::from_dec_str("111111111111111111111111111111").unwrap(), (&result[..]).into() ); - assert_eq!(gas_left, U256::from(92_086)); + assert_eq!(gas_left, U256::from(92_095)); } // subtraction with overflow @@ -677,7 +677,7 @@ fn math_div() { U256::from_dec_str("1125000").unwrap(), (&result[..]).into() ); - assert_eq!(gas_left, U256::from(87_375)); + assert_eq!(gas_left, U256::from(87_379)); } #[test] @@ -705,7 +705,7 @@ fn storage_metering() { }; // 0 -> not 0 - assert_eq!(gas_left, U256::from(72_397)); + assert_eq!(gas_left, U256::from(72_395)); // #2 @@ -724,7 +724,7 @@ fn storage_metering() { }; // not 0 -> not 0 - assert_eq!(gas_left, U256::from(87_397)); + assert_eq!(gas_left, U256::from(87_395)); } // This test checks the ability of wasm contract to invoke @@ -812,7 +812,7 @@ fn externs() { "Gas limit requested and returned does not match" ); - assert_eq!(gas_left, U256::from(90_429)); + assert_eq!(gas_left, U256::from(90_428)); } #[test] @@ -838,7 +838,7 @@ fn embedded_keccak() { }; assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87")); - assert_eq!(gas_left, U256::from(84_133)); + assert_eq!(gas_left, U256::from(85_949)); } /// This test checks the correctness of log extern @@ -873,7 +873,7 @@ fn events() { assert_eq!(&log_entry.data, b"gnihtemos"); assert_eq!(&result, b"gnihtemos"); - assert_eq!(gas_left, U256::from(81_347)); + assert_eq!(gas_left, U256::from(83_158)); } #[test]