mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 04:31:08 +00:00
WIP on chain heap (#639)
* move heap size on chain * fix the interface change * decode heap size * fix code comments * fix comment * update Cargo.lock * rename to heappages * add one heap pages variable in runtime
This commit is contained in:
Generated
+1
@@ -3002,6 +3002,7 @@ dependencies = [
|
|||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||||
|
"substrate-codec 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
|
|||||||
init_logger(log_pattern);
|
init_logger(log_pattern);
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
let executor = NativeExecutor::with_heap_pages(8);
|
let executor = NativeExecutor::new();
|
||||||
|
|
||||||
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
|
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
|
||||||
let genesis_config = GenesisConfig {
|
let genesis_config = GenesisConfig {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn executor() -> ::substrate_executor::NativeExecutor<Executor> {
|
fn executor() -> ::substrate_executor::NativeExecutor<Executor> {
|
||||||
::substrate_executor::NativeExecutor::with_heap_pages(8)
|
::substrate_executor::NativeExecutor::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -114,9 +114,9 @@ mod tests {
|
|||||||
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||||
];
|
];
|
||||||
|
|
||||||
let r = executor().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
let v = executor().call(&mut t, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
|
let v = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
|
||||||
let r = ApplyResult::decode(&mut &v[..]).unwrap();
|
let r = ApplyResult::decode(&mut &v[..]).unwrap();
|
||||||
assert_eq!(r, Err(ApplyError::CantPay));
|
assert_eq!(r, Err(ApplyError::CantPay));
|
||||||
}
|
}
|
||||||
@@ -134,9 +134,9 @@ mod tests {
|
|||||||
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||||
];
|
];
|
||||||
|
|
||||||
let r = executor().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
let v = executor().call(&mut t, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
|
let v = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
|
||||||
let r = ApplyResult::decode(&mut &v[..]).unwrap();
|
let r = ApplyResult::decode(&mut &v[..]).unwrap();
|
||||||
assert_eq!(r, Err(ApplyError::CantPay));
|
assert_eq!(r, Err(ApplyError::CantPay));
|
||||||
}
|
}
|
||||||
@@ -154,9 +154,9 @@ mod tests {
|
|||||||
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||||
];
|
];
|
||||||
|
|
||||||
let r = executor().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
let r = executor().call(&mut t, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
|
let r = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
@@ -178,9 +178,9 @@ mod tests {
|
|||||||
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||||
];
|
];
|
||||||
|
|
||||||
let r = executor().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
let r = executor().call(&mut t, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
|
let r = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
@@ -312,7 +312,7 @@ mod tests {
|
|||||||
fn full_native_block_import_works() {
|
fn full_native_block_import_works() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
executor().call(&mut t, COMPACT_CODE, "execute_block", &block1().0, true).0.unwrap();
|
executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1().0, true).0.unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(Balances::total_balance(&alice()), 41);
|
assert_eq!(Balances::total_balance(&alice()), 41);
|
||||||
@@ -329,7 +329,7 @@ mod tests {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
executor().call(&mut t, COMPACT_CODE, "execute_block", &block2().0, true).0.unwrap();
|
executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0, true).0.unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(Balances::total_balance(&alice()), 30);
|
assert_eq!(Balances::total_balance(&alice()), 30);
|
||||||
@@ -359,14 +359,14 @@ mod tests {
|
|||||||
fn full_wasm_block_import_works() {
|
fn full_wasm_block_import_works() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
WasmExecutor::new(8).call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
|
WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1().0).unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(Balances::total_balance(&alice()), 41);
|
assert_eq!(Balances::total_balance(&alice()), 41);
|
||||||
assert_eq!(Balances::total_balance(&bob()), 69);
|
assert_eq!(Balances::total_balance(&bob()), 69);
|
||||||
});
|
});
|
||||||
|
|
||||||
WasmExecutor::new(8).call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
|
WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0).unwrap();
|
||||||
|
|
||||||
runtime_io::with_externalities(&mut t, || {
|
runtime_io::with_externalities(&mut t, || {
|
||||||
assert_eq!(Balances::total_balance(&alice()), 30);
|
assert_eq!(Balances::total_balance(&alice()), 30);
|
||||||
@@ -378,7 +378,7 @@ mod tests {
|
|||||||
fn wasm_big_block_import_fails() {
|
fn wasm_big_block_import_fails() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
let r = WasmExecutor::new(8).call(&mut t, COMPACT_CODE, "execute_block", &block1big().0);
|
let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0);
|
||||||
assert!(!r.is_ok());
|
assert!(!r.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ mod tests {
|
|||||||
fn native_big_block_import_succeeds() {
|
fn native_big_block_import_succeeds() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
let r = Executor::with_heap_pages(8).call(&mut t, COMPACT_CODE, "execute_block", &block1big().0, true).0;
|
let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, true).0;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,7 +394,7 @@ mod tests {
|
|||||||
fn native_big_block_import_fails_on_fallback() {
|
fn native_big_block_import_fails_on_fallback() {
|
||||||
let mut t = new_test_ext();
|
let mut t = new_test_ext();
|
||||||
|
|
||||||
let r = Executor::with_heap_pages(8).call(&mut t, COMPACT_CODE, "execute_block", &block1big().0, false).0;
|
let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, false).0;
|
||||||
assert!(!r.is_ok());
|
assert!(!r.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,9 +412,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm");
|
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm");
|
||||||
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
|
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
|
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
|
||||||
let r = ApplyResult::decode(&mut &r[..]).unwrap();
|
let r = ApplyResult::decode(&mut &r[..]).unwrap();
|
||||||
assert_eq!(r, Err(ApplyError::CantPay));
|
assert_eq!(r, Err(ApplyError::CantPay));
|
||||||
}
|
}
|
||||||
@@ -433,9 +433,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm");
|
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm");
|
||||||
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
|
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
|
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
|
||||||
let r = ApplyResult::decode(&mut &r[..]).unwrap();
|
let r = ApplyResult::decode(&mut &r[..]).unwrap();
|
||||||
assert_eq!(r, Ok(ApplyOutcome::Success));
|
assert_eq!(r, Ok(ApplyOutcome::Success));
|
||||||
|
|
||||||
|
|||||||
Generated
+1
@@ -903,6 +903,7 @@ dependencies = [
|
|||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||||
|
"substrate-codec 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -125,10 +125,6 @@ args:
|
|||||||
long: execution
|
long: execution
|
||||||
value_name: STRATEGY
|
value_name: STRATEGY
|
||||||
help: The means of execution used when calling into the runtime. Can be either wasm, native or both.
|
help: The means of execution used when calling into the runtime. Can be either wasm, native or both.
|
||||||
- max-heap-pages:
|
|
||||||
long: max-heap-pages
|
|
||||||
value_name: COUNT
|
|
||||||
help: The maximum number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing.
|
|
||||||
subcommands:
|
subcommands:
|
||||||
- build-spec:
|
- build-spec:
|
||||||
about: Build a spec.json file, outputing to stdout
|
about: Build a spec.json file, outputing to stdout
|
||||||
|
|||||||
@@ -266,10 +266,6 @@ where
|
|||||||
service::Roles::FULL
|
service::Roles::FULL
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(v) = matches.value_of("max-heap-pages") {
|
|
||||||
config.max_heap_pages = v.parse().map_err(|_| "Invalid --max-heap-pages argument")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(s) = matches.value_of("execution") {
|
if let Some(s) = matches.value_of("execution") {
|
||||||
config.execution_strategy = match s {
|
config.execution_strategy = match s {
|
||||||
"both" => service::ExecutionStrategy::Both,
|
"both" => service::ExecutionStrategy::Both,
|
||||||
@@ -398,10 +394,6 @@ fn import_blocks<F, E>(matches: &clap::ArgMatches, spec: ChainSpec<FactoryGenesi
|
|||||||
let mut config = service::Configuration::default_with_spec(spec);
|
let mut config = service::Configuration::default_with_spec(spec);
|
||||||
config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into();
|
config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into();
|
||||||
|
|
||||||
if let Some(v) = matches.value_of("max-heap-pages") {
|
|
||||||
config.max_heap_pages = v.parse().map_err(|_| "Invalid --max-heap-pages argument")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(s) = matches.value_of("execution") {
|
if let Some(s) = matches.value_of("execution") {
|
||||||
config.execution_strategy = match s {
|
config.execution_strategy = match s {
|
||||||
"both" => service::ExecutionStrategy::Both,
|
"both" => service::ExecutionStrategy::Both,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use patricia_trie::NodeCodec;
|
|||||||
use primitives::{KeccakHasher, RlpCodec};
|
use primitives::{KeccakHasher, RlpCodec};
|
||||||
use hashdb::Hasher;
|
use hashdb::Hasher;
|
||||||
use rlp::Encodable;
|
use rlp::Encodable;
|
||||||
|
use codec::Decode;
|
||||||
|
|
||||||
use backend;
|
use backend;
|
||||||
use error;
|
use error;
|
||||||
@@ -145,8 +146,9 @@ where
|
|||||||
let mut externalities = Ext::new(&mut overlay, &state);
|
let mut externalities = Ext::new(&mut overlay, &state);
|
||||||
let code = externalities.storage(b":code").ok_or(error::ErrorKind::VersionInvalid)?
|
let code = externalities.storage(b":code").ok_or(error::ErrorKind::VersionInvalid)?
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
let heap_pages = externalities.storage(b":heappages").and_then(|v| u64::decode(&mut &v[..])).unwrap_or(8) as usize;
|
||||||
|
|
||||||
self.executor.runtime_version(&mut externalities, &code)
|
self.executor.runtime_version(&mut externalities, heap_pages, &code)
|
||||||
.ok_or(error::ErrorKind::VersionInvalid.into())
|
.ok_or(error::ErrorKind::VersionInvalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ mod tests {
|
|||||||
native_executor_instance!(Executor, test_client::runtime::api::dispatch, test_client::runtime::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
|
native_executor_instance!(Executor, test_client::runtime::api::dispatch, test_client::runtime::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
|
||||||
|
|
||||||
fn executor() -> ::executor::NativeExecutor<Executor> {
|
fn executor() -> ::executor::NativeExecutor<Executor> {
|
||||||
NativeExecutionDispatch::with_heap_pages(8)
|
NativeExecutionDispatch::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_block(backend: &InMemory<KeccakHasher, RlpCodec>, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transfer>) -> (Vec<u8>, Hash) {
|
fn construct_block(backend: &InMemory<KeccakHasher, RlpCodec>, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transfer>) -> (Vec<u8>, Hash) {
|
||||||
@@ -194,7 +194,7 @@ mod tests {
|
|||||||
let _ = execute(
|
let _ = execute(
|
||||||
&backend,
|
&backend,
|
||||||
&mut overlay,
|
&mut overlay,
|
||||||
&Executor::with_heap_pages(8),
|
&Executor::new(),
|
||||||
"execute_block",
|
"execute_block",
|
||||||
&b1data,
|
&b1data,
|
||||||
ExecutionStrategy::NativeWhenPossible,
|
ExecutionStrategy::NativeWhenPossible,
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ pub mod tests {
|
|||||||
let remote_read_proof = remote_client.read_proof(&remote_block_id, b":auth:len").unwrap();
|
let remote_read_proof = remote_client.read_proof(&remote_block_id, b":auth:len").unwrap();
|
||||||
|
|
||||||
// check remote read proof locally
|
// check remote read proof locally
|
||||||
let local_executor = test_client::LocalExecutor::with_heap_pages(8);
|
let local_executor = test_client::LocalExecutor::new();
|
||||||
let local_checker = new_fetch_checker::<_, KeccakHasher, RlpCodec>(local_executor);
|
let local_checker = new_fetch_checker::<_, KeccakHasher, RlpCodec>(local_executor);
|
||||||
let request = RemoteReadRequest {
|
let request = RemoteReadRequest {
|
||||||
block: remote_block_hash,
|
block: remote_block_hash,
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ mod tests {
|
|||||||
let remote_execution_proof = remote_client.execution_proof(&remote_block_id, "authorities", &[]).unwrap().1;
|
let remote_execution_proof = remote_client.execution_proof(&remote_block_id, "authorities", &[]).unwrap().1;
|
||||||
|
|
||||||
// check remote execution proof locally
|
// check remote execution proof locally
|
||||||
let local_executor = test_client::LocalExecutor::with_heap_pages(8);
|
let local_executor = test_client::LocalExecutor::new();
|
||||||
check_execution_proof::<_, _, _, RlpCodec>(&local_executor, &RemoteCallRequest {
|
check_execution_proof::<_, _, _, RlpCodec>(&local_executor, &RemoteCallRequest {
|
||||||
block: test_client::runtime::Hash::default(),
|
block: test_client::runtime::Hash::default(),
|
||||||
header: test_client::runtime::Header {
|
header: test_client::runtime::Header {
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ pub trait RuntimeInfo {
|
|||||||
fn runtime_version<E: Externalities<KeccakHasher>> (
|
fn runtime_version<E: Externalities<KeccakHasher>> (
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
code: &[u8]
|
code: &[u8]
|
||||||
) -> Option<RuntimeVersion>;
|
) -> Option<RuntimeVersion>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,12 +55,13 @@ fn fetch_cached_runtime_version<'a, E: Externalities<KeccakHasher>>(
|
|||||||
wasm_executor: &WasmExecutor,
|
wasm_executor: &WasmExecutor,
|
||||||
cache: &'a mut MutexGuard<CacheType>,
|
cache: &'a mut MutexGuard<CacheType>,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
code: &[u8]
|
code: &[u8]
|
||||||
) -> Result<(&'a WasmModule, &'a Option<RuntimeVersion>)> {
|
) -> Result<(&'a WasmModule, &'a Option<RuntimeVersion>)> {
|
||||||
let maybe_runtime_preproc = cache.entry(gen_cache_key(code))
|
let maybe_runtime_preproc = cache.entry(gen_cache_key(code))
|
||||||
.or_insert_with(|| match WasmModule::from_buffer(code) {
|
.or_insert_with(|| match WasmModule::from_buffer(code) {
|
||||||
Ok(module) => {
|
Ok(module) => {
|
||||||
let version = wasm_executor.call_in_wasm_module(ext, &module, "version", &[])
|
let version = wasm_executor.call_in_wasm_module(ext, heap_pages, &module, "version", &[])
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|v| RuntimeVersion::decode(&mut v.as_slice()));
|
.and_then(|v| RuntimeVersion::decode(&mut v.as_slice()));
|
||||||
RuntimePreproc::ValidCode(module, version)
|
RuntimePreproc::ValidCode(module, version)
|
||||||
@@ -108,9 +109,9 @@ pub trait NativeExecutionDispatch: Send + Sync {
|
|||||||
/// Get native runtime version.
|
/// Get native runtime version.
|
||||||
const VERSION: RuntimeVersion;
|
const VERSION: RuntimeVersion;
|
||||||
|
|
||||||
/// Construct corresponding `NativeExecutor` with given `heap_pages`.
|
/// Construct corresponding `NativeExecutor`
|
||||||
fn with_heap_pages(max_heap_pages: usize) -> NativeExecutor<Self> where Self: Sized {
|
fn new() -> NativeExecutor<Self> where Self: Sized {
|
||||||
NativeExecutor::with_heap_pages(max_heap_pages)
|
NativeExecutor::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,11 +126,11 @@ pub struct NativeExecutor<D: NativeExecutionDispatch> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: NativeExecutionDispatch> NativeExecutor<D> {
|
impl<D: NativeExecutionDispatch> NativeExecutor<D> {
|
||||||
/// Create new instance with specific number of pages for wasm fallback's heap.
|
/// Create new instance.
|
||||||
pub fn with_heap_pages(max_heap_pages: usize) -> Self {
|
pub fn new() -> Self {
|
||||||
NativeExecutor {
|
NativeExecutor {
|
||||||
_dummy: Default::default(),
|
_dummy: Default::default(),
|
||||||
fallback: WasmExecutor::new(max_heap_pages),
|
fallback: WasmExecutor::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,9 +150,10 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
|
|||||||
fn runtime_version<E: Externalities<KeccakHasher>>(
|
fn runtime_version<E: Externalities<KeccakHasher>>(
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
) -> Option<RuntimeVersion> {
|
) -> Option<RuntimeVersion> {
|
||||||
fetch_cached_runtime_version(&self.fallback, &mut RUNTIMES_CACHE.lock(), ext, code).ok()?.1.clone()
|
fetch_cached_runtime_version(&self.fallback, &mut RUNTIMES_CACHE.lock(), ext, heap_pages, code).ok()?.1.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,23 +163,24 @@ impl<D: NativeExecutionDispatch> CodeExecutor<KeccakHasher> for NativeExecutor<D
|
|||||||
fn call<E: Externalities<KeccakHasher>>(
|
fn call<E: Externalities<KeccakHasher>>(
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
method: &str,
|
method: &str,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
use_native: bool,
|
use_native: bool,
|
||||||
) -> (Result<Vec<u8>>, bool) {
|
) -> (Result<Vec<u8>>, bool) {
|
||||||
let mut c = RUNTIMES_CACHE.lock();
|
let mut c = RUNTIMES_CACHE.lock();
|
||||||
let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext, code) {
|
let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext, heap_pages, code) {
|
||||||
Ok((module, onchain_version)) => (module, onchain_version),
|
Ok((module, onchain_version)) => (module, onchain_version),
|
||||||
Err(_) => return (Err(ErrorKind::InvalidCode(code.into()).into()), false),
|
Err(_) => return (Err(ErrorKind::InvalidCode(code.into()).into()), false),
|
||||||
};
|
};
|
||||||
match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&D::VERSION))) {
|
match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&D::VERSION))) {
|
||||||
(_, false) => {
|
(_, false) => {
|
||||||
trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
|
trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
|
||||||
(self.fallback.call_in_wasm_module(ext, module, method, data), false)
|
(self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false)
|
||||||
}
|
}
|
||||||
(false, _) => {
|
(false, _) => {
|
||||||
(self.fallback.call_in_wasm_module(ext, module, method, data), false)
|
(self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
|
trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
|
||||||
@@ -213,8 +216,8 @@ macro_rules! native_executor_instance {
|
|||||||
.ok_or_else(|| $crate::error::ErrorKind::MethodNotFound(method.to_owned()).into())
|
.ok_or_else(|| $crate::error::ErrorKind::MethodNotFound(method.to_owned()).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_heap_pages(max_heap_pages: usize) -> $crate::NativeExecutor<$name> {
|
fn new() -> $crate::NativeExecutor<$name> {
|
||||||
$crate::NativeExecutor::with_heap_pages(max_heap_pages)
|
$crate::NativeExecutor::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -554,7 +554,7 @@ mod tests {
|
|||||||
"#).unwrap();
|
"#).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox", &code).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(),
|
||||||
vec![1],
|
vec![1],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -575,7 +575,7 @@ mod tests {
|
|||||||
"#).unwrap();
|
"#).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox", &code).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(),
|
||||||
vec![0],
|
vec![0],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -613,7 +613,7 @@ mod tests {
|
|||||||
"#).unwrap();
|
"#).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox", &code).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(),
|
||||||
vec![1],
|
vec![1],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -647,7 +647,7 @@ mod tests {
|
|||||||
"#).unwrap();
|
"#).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox_args", &code).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(),
|
||||||
vec![1],
|
vec![1],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -669,7 +669,7 @@ mod tests {
|
|||||||
"#).unwrap();
|
"#).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox_return_val", &code).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(),
|
||||||
vec![1],
|
vec![1],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,47 +496,36 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
|||||||
/// Wasm rust executor for contracts.
|
/// Wasm rust executor for contracts.
|
||||||
///
|
///
|
||||||
/// Executes the provided code in a sandboxed wasm runtime.
|
/// Executes the provided code in a sandboxed wasm runtime.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct WasmExecutor {
|
pub struct WasmExecutor {
|
||||||
/// The max number of pages to allocate for the heap.
|
|
||||||
pub max_heap_pages: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for WasmExecutor {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
WasmExecutor {
|
|
||||||
max_heap_pages: self.max_heap_pages,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WasmExecutor {
|
impl WasmExecutor {
|
||||||
|
|
||||||
/// Create a new instance.
|
/// Create a new instance.
|
||||||
pub fn new(max_heap_pages: usize) -> Self {
|
pub fn new() -> Self {
|
||||||
WasmExecutor {
|
WasmExecutor{}
|
||||||
max_heap_pages,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Call a given method in the given code.
|
/// Call a given method in the given code.
|
||||||
/// This should be used for tests only.
|
/// This should be used for tests only.
|
||||||
pub fn call<E: Externalities<KeccakHasher>>(
|
pub fn call<E: Externalities<KeccakHasher>>(
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
method: &str,
|
method: &str,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<Vec<u8>> {
|
) -> Result<Vec<u8>> {
|
||||||
let module = ::wasmi::Module::from_buffer(code).expect("all modules compiled with rustc are valid wasm code; qed");
|
let module = ::wasmi::Module::from_buffer(code).expect("all modules compiled with rustc are valid wasm code; qed");
|
||||||
self.call_in_wasm_module(ext, &module, method, data)
|
self.call_in_wasm_module(ext, heap_pages, &module, method, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call a given method in the given wasm-module runtime.
|
/// Call a given method in the given wasm-module runtime.
|
||||||
pub fn call_in_wasm_module<E: Externalities<KeccakHasher>>(
|
pub fn call_in_wasm_module<E: Externalities<KeccakHasher>>(
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
method: &str,
|
method: &str,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
@@ -564,7 +553,7 @@ impl WasmExecutor {
|
|||||||
.export_by_name("__indirect_function_table")
|
.export_by_name("__indirect_function_table")
|
||||||
.and_then(|e| e.as_table().cloned());
|
.and_then(|e| e.as_table().cloned());
|
||||||
|
|
||||||
let mut fec = FunctionExecutor::new(memory.clone(), self.max_heap_pages, table, ext)?;
|
let mut fec = FunctionExecutor::new(memory.clone(), heap_pages, table, ext)?;
|
||||||
|
|
||||||
// finish instantiation by running 'start' function (if any).
|
// finish instantiation by running 'start' function (if any).
|
||||||
let instance = intermediate_instance.run_start(&mut fec)?;
|
let instance = intermediate_instance.run_start(&mut fec)?;
|
||||||
@@ -585,7 +574,7 @@ impl WasmExecutor {
|
|||||||
let returned = match result {
|
let returned = match result {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
trace!(target: "wasm-executor", "Failed to execute code with {} pages", self.max_heap_pages);
|
trace!(target: "wasm-executor", "Failed to execute code with {} pages", heap_pages);
|
||||||
return Err(e.into())
|
return Err(e.into())
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -620,7 +609,7 @@ mod tests {
|
|||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
|
|
||||||
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_empty_return", &[]).unwrap();
|
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap();
|
||||||
assert_eq!(output, vec![0u8; 0]);
|
assert_eq!(output, vec![0u8; 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,10 +618,10 @@ mod tests {
|
|||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
|
|
||||||
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_panic", &[]);
|
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_panic", &[]);
|
||||||
assert!(output.is_err());
|
assert!(output.is_err());
|
||||||
|
|
||||||
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_conditional_panic", &[2]);
|
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]);
|
||||||
assert!(output.is_err());
|
assert!(output.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,7 +631,7 @@ mod tests {
|
|||||||
ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
|
ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
|
|
||||||
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_data_in", b"Hello world").unwrap();
|
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_data_in", b"Hello world").unwrap();
|
||||||
|
|
||||||
assert_eq!(output, b"all ok!".to_vec());
|
assert_eq!(output, b"all ok!".to_vec());
|
||||||
|
|
||||||
@@ -665,7 +654,7 @@ mod tests {
|
|||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
|
|
||||||
// This will clear all entries which prefix is "ab".
|
// This will clear all entries which prefix is "ab".
|
||||||
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_clear_prefix", b"ab").unwrap();
|
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_clear_prefix", b"ab").unwrap();
|
||||||
|
|
||||||
assert_eq!(output, b"all ok!".to_vec());
|
assert_eq!(output, b"all ok!".to_vec());
|
||||||
|
|
||||||
@@ -682,11 +671,11 @@ mod tests {
|
|||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_blake2_256", &[]).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", &[]).unwrap(),
|
||||||
blake2_256(&b""[..]).encode()
|
blake2_256(&b""[..]).encode()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(),
|
||||||
blake2_256(&b"Hello world!"[..]).encode()
|
blake2_256(&b"Hello world!"[..]).encode()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -696,11 +685,11 @@ mod tests {
|
|||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_256", &[]).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(),
|
||||||
hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a")
|
hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_256", b"Hello world!").unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(),
|
||||||
hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74")
|
hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -710,11 +699,11 @@ mod tests {
|
|||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_128", &[]).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", &[]).unwrap(),
|
||||||
hex!("99e9d85137db46ef4bbea33613baafd5")
|
hex!("99e9d85137db46ef4bbea33613baafd5")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_128", b"Hello world!").unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", b"Hello world!").unwrap(),
|
||||||
hex!("b27dfd7f223f177f2a13647b533599af")
|
hex!("b27dfd7f223f177f2a13647b533599af")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -730,7 +719,7 @@ mod tests {
|
|||||||
calldata.extend_from_slice(sig.as_ref());
|
calldata.extend_from_slice(sig.as_ref());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
|
||||||
vec![1]
|
vec![1]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -740,7 +729,7 @@ mod tests {
|
|||||||
calldata.extend_from_slice(other_sig.as_ref());
|
calldata.extend_from_slice(other_sig.as_ref());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
|
||||||
vec![0]
|
vec![0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -750,7 +739,7 @@ mod tests {
|
|||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_enumerated_trie_root", &[]).unwrap(),
|
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_enumerated_trie_root", &[]).unwrap(),
|
||||||
ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.encode()
|
ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.encode()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ pub struct Configuration<C, G: Serialize + DeserializeOwned + BuildStorage> {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
/// Execution strategy.
|
/// Execution strategy.
|
||||||
pub execution_strategy: ExecutionStrategy,
|
pub execution_strategy: ExecutionStrategy,
|
||||||
/// Maximum number of heap pages to allocate for Wasm execution.
|
|
||||||
pub max_heap_pages: usize,
|
|
||||||
/// RPC over HTTP binding address. `None` if disabled.
|
/// RPC over HTTP binding address. `None` if disabled.
|
||||||
pub rpc_http: Option<SocketAddr>,
|
pub rpc_http: Option<SocketAddr>,
|
||||||
/// RPC over Websockets binding address. `None` if disabled.
|
/// RPC over Websockets binding address. `None` if disabled.
|
||||||
@@ -88,7 +86,6 @@ impl<C: Default, G: Serialize + DeserializeOwned + BuildStorage> Configuration<C
|
|||||||
telemetry: Default::default(),
|
telemetry: Default::default(),
|
||||||
pruning: PruningMode::default(),
|
pruning: PruningMode::default(),
|
||||||
execution_strategy: ExecutionStrategy::Both,
|
execution_strategy: ExecutionStrategy::Both,
|
||||||
max_heap_pages: 1024,
|
|
||||||
rpc_http: None,
|
rpc_http: None,
|
||||||
rpc_ws: None,
|
rpc_ws: None,
|
||||||
telemetry_url: None,
|
telemetry_url: None,
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ pub struct Service<Components: components::Components> {
|
|||||||
pub fn new_client<Factory: components::ServiceFactory>(config: FactoryFullConfiguration<Factory>)
|
pub fn new_client<Factory: components::ServiceFactory>(config: FactoryFullConfiguration<Factory>)
|
||||||
-> Result<Arc<ComponentClient<components::FullComponents<Factory>>>, error::Error>
|
-> Result<Arc<ComponentClient<components::FullComponents<Factory>>>, error::Error>
|
||||||
{
|
{
|
||||||
let executor = NativeExecutor::with_heap_pages(config.max_heap_pages);
|
let executor = NativeExecutor::new();
|
||||||
let (client, _) = components::FullComponents::<Factory>::build_client(
|
let (client, _) = components::FullComponents::<Factory>::build_client(
|
||||||
&config,
|
&config,
|
||||||
executor,
|
executor,
|
||||||
@@ -122,7 +122,7 @@ impl<Components> Service<Components>
|
|||||||
let (signal, exit) = ::exit_future::signal();
|
let (signal, exit) = ::exit_future::signal();
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
let executor = NativeExecutor::with_heap_pages(config.max_heap_pages);
|
let executor = NativeExecutor::new();
|
||||||
|
|
||||||
let mut keystore = Keystore::open(config.keystore_path.as_str().into())?;
|
let mut keystore = Keystore::open(config.keystore_path.as_str().into())?;
|
||||||
for seed in &config.keys {
|
for seed in &config.keys {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ parking_lot = "0.4"
|
|||||||
heapsize = "0.4"
|
heapsize = "0.4"
|
||||||
|
|
||||||
substrate-primitives = { path = "../primitives", version = "0.1.0" }
|
substrate-primitives = { path = "../primitives", version = "0.1.0" }
|
||||||
|
substrate-codec = { path = "../codec", default_features = false }
|
||||||
|
|
||||||
hashdb = { git = "https://github.com/paritytech/parity-common" }
|
hashdb = { git = "https://github.com/paritytech/parity-common" }
|
||||||
memorydb = { git = "https://github.com/paritytech/parity-common" }
|
memorydb = { git = "https://github.com/paritytech/parity-common" }
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ extern crate rlp;
|
|||||||
extern crate heapsize;
|
extern crate heapsize;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate substrate_primitives as primitives;
|
extern crate substrate_primitives as primitives;
|
||||||
|
extern crate substrate_codec as codec;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -41,6 +42,7 @@ use hashdb::Hasher;
|
|||||||
use patricia_trie::NodeCodec;
|
use patricia_trie::NodeCodec;
|
||||||
use rlp::Encodable;
|
use rlp::Encodable;
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
|
use codec::Decode;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
mod ext;
|
mod ext;
|
||||||
@@ -206,6 +208,7 @@ pub trait CodeExecutor<H: Hasher>: Sized + Send + Sync {
|
|||||||
fn call<E: Externalities<H>>(
|
fn call<E: Externalities<H>>(
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
heap_pages: usize,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
method: &str,
|
method: &str,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
@@ -325,6 +328,9 @@ where
|
|||||||
.ok_or_else(|| Box::new(ExecutionError::CodeEntryDoesNotExist) as Box<Error>)?
|
.ok_or_else(|| Box::new(ExecutionError::CodeEntryDoesNotExist) as Box<Error>)?
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
|
let heap_pages = ext::Ext::new(overlay, backend).storage(b":heappages")
|
||||||
|
.and_then(|v| u64::decode(&mut &v[..])).unwrap_or(8) as usize;
|
||||||
|
|
||||||
let result = {
|
let result = {
|
||||||
let mut orig_prospective = overlay.prospective.clone();
|
let mut orig_prospective = overlay.prospective.clone();
|
||||||
|
|
||||||
@@ -334,6 +340,7 @@ where
|
|||||||
(
|
(
|
||||||
exec.call(
|
exec.call(
|
||||||
&mut externalities,
|
&mut externalities,
|
||||||
|
heap_pages,
|
||||||
&code,
|
&code,
|
||||||
method,
|
method,
|
||||||
call_data,
|
call_data,
|
||||||
@@ -358,6 +365,7 @@ where
|
|||||||
(
|
(
|
||||||
exec.call(
|
exec.call(
|
||||||
&mut externalities,
|
&mut externalities,
|
||||||
|
heap_pages,
|
||||||
&code,
|
&code,
|
||||||
method,
|
method,
|
||||||
call_data,
|
call_data,
|
||||||
@@ -488,6 +496,7 @@ mod tests {
|
|||||||
fn call<E: Externalities<H>>(
|
fn call<E: Externalities<H>>(
|
||||||
&self,
|
&self,
|
||||||
ext: &mut E,
|
ext: &mut E,
|
||||||
|
_heap_pages: usize,
|
||||||
_code: &[u8],
|
_code: &[u8],
|
||||||
_method: &str,
|
_method: &str,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub trait TestClient {
|
|||||||
|
|
||||||
impl TestClient for Client<Backend, Executor, runtime::Block> {
|
impl TestClient for Client<Backend, Executor, runtime::Block> {
|
||||||
fn new_for_tests() -> Self {
|
fn new_for_tests() -> Self {
|
||||||
client::new_in_mem(NativeExecutor::with_heap_pages(8), genesis_storage()).unwrap()
|
client::new_in_mem(NativeExecutor::new(), genesis_storage()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn justify_and_import(&self, origin: client::BlockOrigin, block: runtime::Block) -> client::error::Result<()> {
|
fn justify_and_import(&self, origin: client::BlockOrigin, block: runtime::Block) -> client::error::Result<()> {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ impl GenesisConfig {
|
|||||||
.map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec()))
|
.map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec()))
|
||||||
.chain(vec![
|
.chain(vec![
|
||||||
(b":code"[..].into(), wasm_runtime),
|
(b":code"[..].into(), wasm_runtime),
|
||||||
|
(b":heappages"[..].into(), vec![].and(&(16 as u64))),
|
||||||
(b":auth:len"[..].into(), vec![].and(&(self.authorities.len() as u32))),
|
(b":auth:len"[..].into(), vec![].and(&(self.authorities.len() as u32))),
|
||||||
].into_iter())
|
].into_iter())
|
||||||
.chain(self.authorities.iter()
|
.chain(self.authorities.iter()
|
||||||
|
|||||||
@@ -661,6 +661,7 @@ dependencies = [
|
|||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||||
|
"substrate-codec 0.1.0",
|
||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user