Add hint in ActionParams for splitting code/data (#6957)
* Action params and embedded params handling * fix namespaces
This commit is contained in:
		
							parent
							
								
									0a69d5ac4c
								
							
						
					
					
						commit
						f72858ee0a
					
				
							
								
								
									
										10
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -7,7 +7,7 @@ dependencies = [
 | 
			
		||||
 "ethcore-logger 1.9.0",
 | 
			
		||||
 "ethcore-util 1.9.0",
 | 
			
		||||
 "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "parity-wasm 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "vm 0.1.0",
 | 
			
		||||
 "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
 | 
			
		||||
]
 | 
			
		||||
@ -2267,7 +2267,7 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "parity-wasm"
 | 
			
		||||
version = "0.14.5"
 | 
			
		||||
version = "0.15.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
@ -3425,7 +3425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "wasm-utils"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
source = "git+https://github.com/paritytech/wasm-utils#6a39db802eb6b67a0c4e5cf50741f965e217335a"
 | 
			
		||||
source = "git+https://github.com/paritytech/wasm-utils#3d59f7ca0661317bc66894a26b2a5a319fa5d229"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
@ -3433,7 +3433,7 @@ dependencies = [
 | 
			
		||||
 "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "parity-wasm 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -3647,7 +3647,7 @@ dependencies = [
 | 
			
		||||
"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
 | 
			
		||||
"checksum parity-ui-old-precompiled 1.8.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)" = "<none>"
 | 
			
		||||
"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/paritytech/js-precompiled.git)" = "<none>"
 | 
			
		||||
"checksum parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4502e18417d96bd8e72fca9ea4cc18f4d80288ff565582d10aefe86f18b4fc3"
 | 
			
		||||
"checksum parity-wasm 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "95f6243c2d6fadf903b5edfd0011817efc20522ce5f360abf4648c24ea87581a"
 | 
			
		||||
"checksum parity-wordlist 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81451bfab101d186f8fc4a0aa13cb5539b31b02c4ed96425a0842e2a413daba6"
 | 
			
		||||
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
 | 
			
		||||
"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595"
 | 
			
		||||
 | 
			
		||||
@ -309,6 +309,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
 | 
			
		||||
					code: Some(Arc::new(t.data.clone())),
 | 
			
		||||
					data: None,
 | 
			
		||||
					call_type: CallType::None,
 | 
			
		||||
					params_type: vm::ParamsType::Embedded,
 | 
			
		||||
				};
 | 
			
		||||
				let mut out = if output_from_create { Some(vec![]) } else { None };
 | 
			
		||||
				(self.create(params, &mut substate, &mut out, &mut tracer, &mut vm_tracer), out.unwrap_or_else(Vec::new))
 | 
			
		||||
@ -326,6 +327,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
 | 
			
		||||
					code_hash: Some(self.state.code_hash(address)?),
 | 
			
		||||
					data: Some(t.data.clone()),
 | 
			
		||||
					call_type: CallType::Call,
 | 
			
		||||
					params_type: vm::ParamsType::Separate,
 | 
			
		||||
				};
 | 
			
		||||
				let mut out = vec![];
 | 
			
		||||
				(self.call(params, &mut substate, BytesRef::Flexible(&mut out), &mut tracer, &mut vm_tracer), out)
 | 
			
		||||
 | 
			
		||||
@ -171,6 +171,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
 | 
			
		||||
				code_hash: Some(code_hash),
 | 
			
		||||
				data: Some(H256::from(number).to_vec()),
 | 
			
		||||
				call_type: CallType::Call,
 | 
			
		||||
				params_type: vm::ParamsType::Separate,
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			let mut output = H256::new();
 | 
			
		||||
@ -219,6 +220,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
 | 
			
		||||
			code_hash: code_hash,
 | 
			
		||||
			data: None,
 | 
			
		||||
			call_type: CallType::None,
 | 
			
		||||
			params_type: vm::ParamsType::Embedded,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if !self.static_flag {
 | 
			
		||||
@ -276,6 +278,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
 | 
			
		||||
			code_hash: Some(code_hash),
 | 
			
		||||
			data: Some(data.to_vec()),
 | 
			
		||||
			call_type: call_type,
 | 
			
		||||
			params_type: vm::ParamsType::Separate,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if let Some(value) = value {
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ use tx_filter::TransactionFilter;
 | 
			
		||||
use bigint::prelude::U256;
 | 
			
		||||
use bytes::BytesRef;
 | 
			
		||||
use util::Address;
 | 
			
		||||
use vm::{CallType, ActionParams, ActionValue};
 | 
			
		||||
use vm::{CallType, ActionParams, ActionValue, ParamsType};
 | 
			
		||||
use vm::{EnvInfo, Schedule, CreateContractAddress};
 | 
			
		||||
 | 
			
		||||
/// Parity tries to round block.gas_limit to multiple of this constant
 | 
			
		||||
@ -149,6 +149,7 @@ impl EthereumMachine {
 | 
			
		||||
			code_hash: Some(state.code_hash(&contract_address)?),
 | 
			
		||||
			data: data,
 | 
			
		||||
			call_type: CallType::Call,
 | 
			
		||||
			params_type: ParamsType::Separate,
 | 
			
		||||
		};
 | 
			
		||||
		let mut ex = Executive::new(&mut state, &env_info, self);
 | 
			
		||||
		let mut substate = Substate::new();
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ use parking_lot::RwLock;
 | 
			
		||||
use rlp::{Rlp, RlpStream};
 | 
			
		||||
use rustc_hex::FromHex;
 | 
			
		||||
use util::*;
 | 
			
		||||
use vm::{EnvInfo, CallType, ActionValue, ActionParams};
 | 
			
		||||
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
 | 
			
		||||
 | 
			
		||||
use super::genesis::Genesis;
 | 
			
		||||
use super::seal::Generic as GenericSeal;
 | 
			
		||||
@ -504,6 +504,7 @@ impl Spec {
 | 
			
		||||
					code: Some(Arc::new(constructor.clone())),
 | 
			
		||||
					data: None,
 | 
			
		||||
					call_type: CallType::None,
 | 
			
		||||
					params_type: ParamsType::Embedded,
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				let mut substate = Substate::new();
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use hash::keccak;
 | 
			
		||||
use vm::{EnvInfo, ActionParams, ActionValue, CallType};
 | 
			
		||||
use vm::{EnvInfo, ActionParams, ActionValue, CallType, ParamsType};
 | 
			
		||||
use evm::{Factory, VMType};
 | 
			
		||||
use executive::Executive;
 | 
			
		||||
use state::Substate;
 | 
			
		||||
@ -45,6 +45,7 @@ fn test_blockhash_eip210(factory: Factory) {
 | 
			
		||||
			code_hash: Some(blockhash_contract_code_hash),
 | 
			
		||||
			data: Some(H256::from(i - 1).to_vec()),
 | 
			
		||||
			call_type: CallType::Call,
 | 
			
		||||
			params_type: ParamsType::Separate,
 | 
			
		||||
		};
 | 
			
		||||
		let mut ex = Executive::new(&mut state, &env_info, &machine);
 | 
			
		||||
		let mut substate = Substate::new();
 | 
			
		||||
@ -67,6 +68,7 @@ fn test_blockhash_eip210(factory: Factory) {
 | 
			
		||||
		code_hash: Some(get_prev_hash_code_hash),
 | 
			
		||||
		data: None,
 | 
			
		||||
		call_type: CallType::Call,
 | 
			
		||||
		params_type: ParamsType::Separate,
 | 
			
		||||
	};
 | 
			
		||||
	let mut ex = Executive::new(&mut state, &env_info, &machine);
 | 
			
		||||
	let mut substate = Substate::new();
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,15 @@ pub enum ActionValue {
 | 
			
		||||
	Apparent(U256)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Type of the way parameters encoded
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub enum ParamsType {
 | 
			
		||||
	/// Parameters are included in code
 | 
			
		||||
	Embedded,
 | 
			
		||||
	/// Parameters are passed in data section
 | 
			
		||||
	Separate,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ActionValue {
 | 
			
		||||
	/// Returns action value as U256.
 | 
			
		||||
	pub fn value(&self) -> U256 {
 | 
			
		||||
@ -81,7 +90,8 @@ pub struct ActionParams {
 | 
			
		||||
	pub data: Option<Bytes>,
 | 
			
		||||
	/// Type of call
 | 
			
		||||
	pub call_type: CallType,
 | 
			
		||||
 | 
			
		||||
	/// Param types encoding
 | 
			
		||||
	pub params_type: ParamsType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for ActionParams {
 | 
			
		||||
@ -99,6 +109,7 @@ impl Default for ActionParams {
 | 
			
		||||
			code: None,
 | 
			
		||||
			data: None,
 | 
			
		||||
			call_type: CallType::None,
 | 
			
		||||
			params_type: ParamsType::Separate,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -118,6 +129,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
 | 
			
		||||
			gas_price: t.gas_price.into(),
 | 
			
		||||
			value: ActionValue::Transfer(t.value.into()),
 | 
			
		||||
			call_type: match address.is_zero() { true => CallType::None, false => CallType::Call },	// TODO @debris is this correct?
 | 
			
		||||
			params_type: ParamsType::Separate,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ mod error;
 | 
			
		||||
 | 
			
		||||
pub mod tests;
 | 
			
		||||
 | 
			
		||||
pub use action_params::{ActionParams, ActionValue};
 | 
			
		||||
pub use action_params::{ActionParams, ActionValue, ParamsType};
 | 
			
		||||
pub use call_type::CallType;
 | 
			
		||||
pub use env_info::{EnvInfo, LastHashes};
 | 
			
		||||
pub use schedule::{Schedule, CleanDustMode};
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ byteorder = "1.0"
 | 
			
		||||
ethcore-util = { path = "../../util" }
 | 
			
		||||
ethcore-bigint = { path = "../../util/bigint" }
 | 
			
		||||
log = "0.3"
 | 
			
		||||
parity-wasm = "0.14"
 | 
			
		||||
parity-wasm = "0.15"
 | 
			
		||||
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
 | 
			
		||||
vm = { path = "../vm" }
 | 
			
		||||
ethcore-logger = { path = "../../logger" }
 | 
			
		||||
 | 
			
		||||
@ -115,7 +115,18 @@ impl vm::Vm for WasmInterpreter {
 | 
			
		||||
			&self.program,
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		let mut cursor = ::std::io::Cursor::new(&*code);
 | 
			
		||||
		let (mut cursor, data_position) = match params.params_type {
 | 
			
		||||
			vm::ParamsType::Embedded => {
 | 
			
		||||
				let module_size = parity_wasm::peek_size(&*code);
 | 
			
		||||
				(
 | 
			
		||||
					::std::io::Cursor::new(&code[..module_size]),
 | 
			
		||||
					module_size
 | 
			
		||||
				)
 | 
			
		||||
			},
 | 
			
		||||
			vm::ParamsType::Separate => {
 | 
			
		||||
				(::std::io::Cursor::new(&code[..]), 0)
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		let contract_module = wasm_utils::inject_gas_counter(
 | 
			
		||||
			elements::Module::deserialize(
 | 
			
		||||
@ -134,8 +145,19 @@ impl vm::Vm for WasmInterpreter {
 | 
			
		||||
		let static_segment_cost = data_section_length * runtime.ext().schedule().wasm.static_region as u64;
 | 
			
		||||
		runtime.charge(|_| static_segment_cost).map_err(Error)?;
 | 
			
		||||
 | 
			
		||||
		let d_ptr = runtime.write_descriptor(¶ms.data.unwrap_or_default())
 | 
			
		||||
			.map_err(Error)?;
 | 
			
		||||
		let d_ptr = {
 | 
			
		||||
			match params.params_type {
 | 
			
		||||
				vm::ParamsType::Embedded => {
 | 
			
		||||
					runtime.write_descriptor(
 | 
			
		||||
						if data_position < code.len() { &code[data_position..] } else { &[] }
 | 
			
		||||
					).map_err(Error)?
 | 
			
		||||
				},
 | 
			
		||||
				vm::ParamsType::Separate => {
 | 
			
		||||
					runtime.write_descriptor(¶ms.data.unwrap_or_default())
 | 
			
		||||
						.map_err(Error)?
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			let execution_params = runtime.execution_params()
 | 
			
		||||
 | 
			
		||||
@ -677,3 +677,30 @@ fn externs() {
 | 
			
		||||
 | 
			
		||||
	assert_eq!(gas_left, U256::from(91_857));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn embedded_keccak() {
 | 
			
		||||
 | 
			
		||||
	::ethcore_logger::init_log();
 | 
			
		||||
	let mut code = load_sample!("keccak.wasm");
 | 
			
		||||
	code.extend_from_slice(b"something");
 | 
			
		||||
 | 
			
		||||
	let mut params = ActionParams::default();
 | 
			
		||||
	params.gas = U256::from(100_000);
 | 
			
		||||
	params.code = Some(Arc::new(code));
 | 
			
		||||
	params.params_type = vm::ParamsType::Embedded;
 | 
			
		||||
 | 
			
		||||
	let mut ext = FakeExt::new();
 | 
			
		||||
 | 
			
		||||
	let (gas_left, result) = {
 | 
			
		||||
		let mut interpreter = wasm_interpreter();
 | 
			
		||||
		let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
 | 
			
		||||
		match result {
 | 
			
		||||
			GasLeft::Known(_) => { panic!("keccak should return payload"); },
 | 
			
		||||
			GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
 | 
			
		||||
	assert_eq!(gas_left, U256::from(80_452));
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user