mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 08:51:09 +00:00
Remove native call (#12201)
* Remove native call With the recent introduction of staging runtime apis the native call wasn't supported anymore. This removes the entire support for this as it is not used anymore. * FMT * Fix benchmarks * FIX ui tests
This commit is contained in:
@@ -31,7 +31,6 @@ use sc_executor::{Externalities, NativeElseWasmExecutor, RuntimeVersionOf, WasmE
|
||||
use sp_core::{
|
||||
storage::well_known_keys,
|
||||
traits::{CodeExecutor, RuntimeCode},
|
||||
NativeOrEncoded, NeverNativeValue,
|
||||
};
|
||||
use sp_runtime::traits::BlakeTwo256;
|
||||
use sp_state_machine::TestExternalities as CoreTestExternalities;
|
||||
@@ -112,46 +111,24 @@ fn construct_block<E: Externalities>(
|
||||
|
||||
// execute the block to get the real header.
|
||||
executor
|
||||
.call::<NeverNativeValue, fn() -> _>(
|
||||
ext,
|
||||
&runtime_code,
|
||||
"Core_initialize_block",
|
||||
&header.encode(),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.call(ext, &runtime_code, "Core_initialize_block", &header.encode(), true)
|
||||
.0
|
||||
.unwrap();
|
||||
|
||||
for i in extrinsics.iter() {
|
||||
executor
|
||||
.call::<NeverNativeValue, fn() -> _>(
|
||||
ext,
|
||||
&runtime_code,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&i.encode(),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.call(ext, &runtime_code, "BlockBuilder_apply_extrinsic", &i.encode(), true)
|
||||
.0
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let header = match executor
|
||||
.call::<NeverNativeValue, fn() -> _>(
|
||||
ext,
|
||||
&runtime_code,
|
||||
"BlockBuilder_finalize_block",
|
||||
&[0u8; 0],
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap()
|
||||
{
|
||||
NativeOrEncoded::Native(_) => unreachable!(),
|
||||
NativeOrEncoded::Encoded(h) => Header::decode(&mut &h[..]).unwrap(),
|
||||
};
|
||||
let header = Header::decode(
|
||||
&mut &executor
|
||||
.call(ext, &runtime_code, "BlockBuilder_finalize_block", &[0u8; 0], true)
|
||||
.0
|
||||
.unwrap()[..],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let hash = header.blake2_256();
|
||||
(Block { header, extrinsics }.encode(), hash.into())
|
||||
@@ -218,13 +195,12 @@ fn bench_execute_block(c: &mut Criterion) {
|
||||
|test_ext| {
|
||||
for block in blocks.iter() {
|
||||
executor
|
||||
.call::<NeverNativeValue, fn() -> _>(
|
||||
.call(
|
||||
&mut test_ext.ext(),
|
||||
&runtime_code,
|
||||
"Core_execute_block",
|
||||
&block.0,
|
||||
use_native,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
|
||||
@@ -21,7 +21,7 @@ use frame_support::{
|
||||
weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Weight},
|
||||
};
|
||||
use frame_system::{self, AccountInfo, EventRecord, Phase};
|
||||
use sp_core::{storage::well_known_keys, traits::Externalities, NeverNativeValue};
|
||||
use sp_core::{storage::well_known_keys, traits::Externalities};
|
||||
use sp_runtime::{
|
||||
traits::Hash as HashT, transaction_validity::InvalidTransaction, ApplyExtrinsicResult,
|
||||
};
|
||||
@@ -187,25 +187,14 @@ fn panic_execution_with_foreign_code_gives_error() {
|
||||
t.insert(<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(), 69_u128.encode());
|
||||
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r =
|
||||
executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), true)
|
||||
.0;
|
||||
assert!(r.is_ok());
|
||||
let v = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt()),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
let r = ApplyExtrinsicResult::decode(&mut &v.as_encoded()[..]).unwrap();
|
||||
let v = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true)
|
||||
.0
|
||||
.unwrap();
|
||||
let r = ApplyExtrinsicResult::decode(&mut &v[..]).unwrap();
|
||||
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
|
||||
}
|
||||
|
||||
@@ -219,25 +208,14 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() {
|
||||
t.insert(<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(), 69_u128.encode());
|
||||
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r =
|
||||
executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), true)
|
||||
.0;
|
||||
assert!(r.is_ok());
|
||||
let v = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt()),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
let r = ApplyExtrinsicResult::decode(&mut &v.as_encoded()[..]).unwrap();
|
||||
let v = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true)
|
||||
.0
|
||||
.unwrap();
|
||||
let r = ApplyExtrinsicResult::decode(&mut &v[..]).unwrap();
|
||||
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
|
||||
}
|
||||
|
||||
@@ -266,26 +244,14 @@ fn successful_execution_with_native_equivalent_code_gives_ok() {
|
||||
);
|
||||
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r =
|
||||
executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), true)
|
||||
.0;
|
||||
assert!(r.is_ok());
|
||||
|
||||
let fees = t.execute_with(|| transfer_fee(&xt()));
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt()),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0;
|
||||
assert!(r.is_ok());
|
||||
|
||||
t.execute_with(|| {
|
||||
@@ -319,26 +285,14 @@ fn successful_execution_with_foreign_code_gives_ok() {
|
||||
);
|
||||
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r =
|
||||
executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), true)
|
||||
.0;
|
||||
assert!(r.is_ok());
|
||||
|
||||
let fees = t.execute_with(|| transfer_fee(&xt()));
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt()),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0;
|
||||
assert!(r.is_ok());
|
||||
|
||||
t.execute_with(|| {
|
||||
@@ -361,15 +315,7 @@ fn full_native_block_import_works() {
|
||||
.get_dispatch_info()
|
||||
.weight;
|
||||
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block1.0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block1.0, true).0.unwrap();
|
||||
|
||||
t.execute_with(|| {
|
||||
assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
|
||||
@@ -441,15 +387,7 @@ fn full_native_block_import_works() {
|
||||
|
||||
fees = t.execute_with(|| transfer_fee(&xt()));
|
||||
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block2.0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block2.0, true).0.unwrap();
|
||||
|
||||
t.execute_with(|| {
|
||||
assert_eq!(
|
||||
@@ -579,15 +517,7 @@ fn full_wasm_block_import_works() {
|
||||
let mut alice_last_known_balance: Balance = Default::default();
|
||||
let mut fees = t.execute_with(|| transfer_fee(&xt()));
|
||||
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block1.0,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block1.0, false).0.unwrap();
|
||||
|
||||
t.execute_with(|| {
|
||||
assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
|
||||
@@ -597,15 +527,7 @@ fn full_wasm_block_import_works() {
|
||||
|
||||
fees = t.execute_with(|| transfer_fee(&xt()));
|
||||
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block2.0,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block2.0, false).0.unwrap();
|
||||
|
||||
t.execute_with(|| {
|
||||
assert_eq!(
|
||||
@@ -757,9 +679,7 @@ fn deploying_wasm_contract_should_work() {
|
||||
|
||||
let mut t = new_test_ext(compact_code_unwrap());
|
||||
|
||||
executor_call::<NeverNativeValue, fn() -> _>(&mut t, "Core_execute_block", &b.0, false, None)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &b.0, false).0.unwrap();
|
||||
|
||||
t.execute_with(|| {
|
||||
// Verify that the contract does exist by querying some of its storage items
|
||||
@@ -778,14 +698,8 @@ fn wasm_big_block_import_fails() {
|
||||
|
||||
set_heap_pages(&mut t.ext(), 4);
|
||||
|
||||
let result = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block_with_size(42, 0, 120_000).0,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let result =
|
||||
executor_call(&mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, false).0;
|
||||
assert!(result.is_err()); // Err(Wasmi(Trap(Trap { kind: Host(AllocatorOutOfSpace) })))
|
||||
}
|
||||
|
||||
@@ -793,15 +707,9 @@ fn wasm_big_block_import_fails() {
|
||||
fn native_big_block_import_succeeds() {
|
||||
let mut t = new_test_ext(compact_code_unwrap());
|
||||
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block_with_size(42, 0, 120_000).0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, true)
|
||||
.0
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -812,15 +720,11 @@ fn native_big_block_import_fails_on_fallback() {
|
||||
// block.
|
||||
set_heap_pages(&mut t.ext(), 8);
|
||||
|
||||
assert!(executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block_with_size(42, 0, 120_000).0,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.is_err());
|
||||
assert!(
|
||||
executor_call(&mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, false,)
|
||||
.0
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -837,25 +741,17 @@ fn panic_execution_gives_error() {
|
||||
t.insert(<pallet_balances::TotalIssuance<Runtime>>::hashed_key().to_vec(), 0_u128.encode());
|
||||
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
let r = executor_call(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
assert!(r.is_ok());
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt()),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap()
|
||||
.into_encoded();
|
||||
let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), false)
|
||||
.0
|
||||
.unwrap();
|
||||
let r = ApplyExtrinsicResult::decode(&mut &r[..]).unwrap();
|
||||
assert_eq!(r, Err(InvalidTransaction::Payment.into()));
|
||||
}
|
||||
@@ -885,12 +781,11 @@ fn successful_execution_gives_ok() {
|
||||
);
|
||||
t.insert(<frame_system::BlockHash<Runtime>>::hashed_key_for(0), vec![0u8; 32]);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
let r = executor_call(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
assert!(r.is_ok());
|
||||
@@ -900,16 +795,9 @@ fn successful_execution_gives_ok() {
|
||||
|
||||
let fees = t.execute_with(|| transfer_fee(&xt()));
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt()),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap()
|
||||
.into_encoded();
|
||||
let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), false)
|
||||
.0
|
||||
.unwrap();
|
||||
ApplyExtrinsicResult::decode(&mut &r[..])
|
||||
.unwrap()
|
||||
.expect("Extrinsic could not be applied")
|
||||
|
||||
@@ -27,7 +27,6 @@ use sp_core::{
|
||||
crypto::KeyTypeId,
|
||||
sr25519::Signature,
|
||||
traits::{CodeExecutor, RuntimeCode},
|
||||
NativeOrEncoded, NeverNativeValue,
|
||||
};
|
||||
use sp_runtime::{
|
||||
traits::{BlakeTwo256, Header as HeaderT},
|
||||
@@ -99,17 +98,12 @@ pub fn executor() -> NativeElseWasmExecutor<ExecutorDispatch> {
|
||||
NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8, 2)
|
||||
}
|
||||
|
||||
pub fn executor_call<
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> std::result::Result<R, Box<dyn std::error::Error + Send + Sync>>
|
||||
+ std::panic::UnwindSafe,
|
||||
>(
|
||||
pub fn executor_call(
|
||||
t: &mut TestExternalities<BlakeTwo256>,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
use_native: bool,
|
||||
native_call: Option<NC>,
|
||||
) -> (Result<NativeOrEncoded<R>>, bool) {
|
||||
) -> (Result<Vec<u8>>, bool) {
|
||||
let mut t = t.ext();
|
||||
|
||||
let code = t.storage(sp_core::storage::well_known_keys::CODE).unwrap();
|
||||
@@ -120,7 +114,7 @@ pub fn executor_call<
|
||||
heap_pages: heap_pages.and_then(|hp| Decode::decode(&mut &hp[..]).ok()),
|
||||
};
|
||||
sp_tracing::try_init_simple();
|
||||
executor().call::<R, NC>(&mut t, &runtime_code, method, data, use_native, native_call)
|
||||
executor().call(&mut t, &runtime_code, method, data, use_native)
|
||||
}
|
||||
|
||||
pub fn new_test_ext(code: &[u8]) -> TestExternalities<BlakeTwo256> {
|
||||
@@ -171,29 +165,15 @@ pub fn construct_block(
|
||||
};
|
||||
|
||||
// execute the block to get the real header.
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
env,
|
||||
"Core_initialize_block",
|
||||
&header.encode(),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(env, "Core_initialize_block", &header.encode(), true).0.unwrap();
|
||||
|
||||
for extrinsic in extrinsics.iter() {
|
||||
// Try to apply the `extrinsic`. It should be valid, in the sense that it passes
|
||||
// all pre-inclusion checks.
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
env,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&extrinsic.encode(),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.expect("application of an extrinsic failed")
|
||||
.into_encoded();
|
||||
let r = executor_call(env, "BlockBuilder_apply_extrinsic", &extrinsic.encode(), true)
|
||||
.0
|
||||
.expect("application of an extrinsic failed");
|
||||
|
||||
match ApplyExtrinsicResult::decode(&mut &r[..])
|
||||
.expect("apply result deserialization failed")
|
||||
{
|
||||
@@ -202,19 +182,10 @@ pub fn construct_block(
|
||||
}
|
||||
}
|
||||
|
||||
let header = match executor_call::<NeverNativeValue, fn() -> _>(
|
||||
env,
|
||||
"BlockBuilder_finalize_block",
|
||||
&[0u8; 0],
|
||||
true,
|
||||
None,
|
||||
let header = Header::decode(
|
||||
&mut &executor_call(env, "BlockBuilder_finalize_block", &[0u8; 0], true).0.unwrap()[..],
|
||||
)
|
||||
.0
|
||||
.unwrap()
|
||||
{
|
||||
NativeOrEncoded::Native(_) => unreachable!(),
|
||||
NativeOrEncoded::Encoded(h) => Header::decode(&mut &h[..]).unwrap(),
|
||||
};
|
||||
.unwrap();
|
||||
|
||||
let hash = header.blake2_256();
|
||||
(Block { header, extrinsics }.encode(), hash.into())
|
||||
|
||||
@@ -26,7 +26,6 @@ use kitchensink_runtime::{
|
||||
};
|
||||
use node_primitives::Balance;
|
||||
use node_testing::keyring::*;
|
||||
use sp_core::NeverNativeValue;
|
||||
use sp_runtime::{traits::One, Perbill};
|
||||
|
||||
pub mod common;
|
||||
@@ -94,15 +93,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
|
||||
);
|
||||
|
||||
// execute a big block.
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block1.0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block1.0, true).0.unwrap();
|
||||
|
||||
// weight multiplier is increased for next block.
|
||||
t.execute_with(|| {
|
||||
@@ -113,15 +104,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
|
||||
});
|
||||
|
||||
// execute a big block.
|
||||
executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block2.0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0
|
||||
.unwrap();
|
||||
executor_call(&mut t, "Core_execute_block", &block2.0, true).0.unwrap();
|
||||
|
||||
// weight multiplier is increased for next block.
|
||||
t.execute_with(|| {
|
||||
@@ -166,24 +149,12 @@ fn transaction_fee_is_correct() {
|
||||
function: Call::Balances(default_transfer_call()),
|
||||
});
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_initialize_block",
|
||||
&vec![].and(&from_block_number(1u32)),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r =
|
||||
executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), true)
|
||||
.0;
|
||||
|
||||
assert!(r.is_ok());
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"BlockBuilder_apply_extrinsic",
|
||||
&vec![].and(&xt.clone()),
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt.clone()), true).0;
|
||||
assert!(r.is_ok());
|
||||
|
||||
t.execute_with(|| {
|
||||
@@ -274,14 +245,7 @@ fn block_weight_capacity_report() {
|
||||
len / 1024 / 1024,
|
||||
);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block.0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r = executor_call(&mut t, "Core_execute_block", &block.0, true).0;
|
||||
|
||||
println!(" || Result = {:?}", r);
|
||||
assert!(r.is_ok());
|
||||
@@ -342,14 +306,7 @@ fn block_length_capacity_report() {
|
||||
len / 1024 / 1024,
|
||||
);
|
||||
|
||||
let r = executor_call::<NeverNativeValue, fn() -> _>(
|
||||
&mut t,
|
||||
"Core_execute_block",
|
||||
&block.0,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let r = executor_call(&mut t, "Core_execute_block", &block.0, true).0;
|
||||
|
||||
println!(" || Result = {:?}", r);
|
||||
assert!(r.is_ok());
|
||||
|
||||
@@ -18,13 +18,11 @@
|
||||
|
||||
//! A method call executor interface.
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use sc_executor::{RuntimeVersion, RuntimeVersionOf};
|
||||
use sp_core::NativeOrEncoded;
|
||||
use sp_externalities::Extensions;
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
use sp_state_machine::{ExecutionManager, ExecutionStrategy, OverlayedChanges, StorageProof};
|
||||
use std::{cell::RefCell, panic::UnwindSafe, result};
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::execution_extensions::ExecutionExtensions;
|
||||
use sp_api::{ProofRecorder, StorageTransactionCache};
|
||||
@@ -68,11 +66,9 @@ pub trait CallExecutor<B: BlockT>: RuntimeVersionOf {
|
||||
/// of the execution context.
|
||||
fn contextual_call<
|
||||
EM: Fn(
|
||||
Result<NativeOrEncoded<R>, Self::Error>,
|
||||
Result<NativeOrEncoded<R>, Self::Error>,
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
Result<Vec<u8>, Self::Error>,
|
||||
Result<Vec<u8>, Self::Error>,
|
||||
) -> Result<Vec<u8>, Self::Error>,
|
||||
>(
|
||||
&self,
|
||||
at: &BlockId<B>,
|
||||
@@ -85,10 +81,9 @@ pub trait CallExecutor<B: BlockT>: RuntimeVersionOf {
|
||||
>,
|
||||
>,
|
||||
execution_manager: ExecutionManager<EM>,
|
||||
native_call: Option<NC>,
|
||||
proof_recorder: &Option<ProofRecorder<B>>,
|
||||
extensions: Option<Extensions>,
|
||||
) -> sp_blockchain::Result<NativeOrEncoded<R>>
|
||||
) -> sp_blockchain::Result<Vec<u8>>
|
||||
where
|
||||
ExecutionManager<EM>: Clone;
|
||||
|
||||
|
||||
@@ -201,11 +201,11 @@ impl<Block: traits::Block> ExecutionExtensions<Block> {
|
||||
///
|
||||
/// Based on the execution context and capabilities it produces
|
||||
/// the right manager and extensions object to support desired set of APIs.
|
||||
pub fn manager_and_extensions<E: std::fmt::Debug, R: codec::Codec>(
|
||||
pub fn manager_and_extensions<E: std::fmt::Debug>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
context: ExecutionContext,
|
||||
) -> (ExecutionManager<DefaultHandler<R, E>>, Extensions) {
|
||||
) -> (ExecutionManager<DefaultHandler<E>>, Extensions) {
|
||||
let manager = match context {
|
||||
ExecutionContext::BlockConstruction => self.strategies.block_construction.get_manager(),
|
||||
ExecutionContext::Syncing => self.strategies.syncing.get_manager(),
|
||||
|
||||
@@ -27,22 +27,18 @@ use std::{
|
||||
marker::PhantomData,
|
||||
panic::{AssertUnwindSafe, UnwindSafe},
|
||||
path::PathBuf,
|
||||
result,
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
mpsc, Arc,
|
||||
},
|
||||
};
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use codec::Encode;
|
||||
use sc_executor_common::{
|
||||
runtime_blob::RuntimeBlob,
|
||||
wasm_runtime::{AllocationStats, InvokeMethod, WasmInstance, WasmModule},
|
||||
};
|
||||
use sp_core::{
|
||||
traits::{CodeExecutor, Externalities, RuntimeCode, RuntimeSpawn, RuntimeSpawnExt},
|
||||
NativeOrEncoded,
|
||||
};
|
||||
use sp_core::traits::{CodeExecutor, Externalities, RuntimeCode, RuntimeSpawn, RuntimeSpawnExt};
|
||||
use sp_externalities::ExternalitiesExt as _;
|
||||
use sp_tasks::new_async_externalities;
|
||||
use sp_version::{GetNativeVersion, NativeVersion, RuntimeVersion};
|
||||
@@ -339,18 +335,14 @@ where
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn call<
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
fn call(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
runtime_code: &RuntimeCode,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
_use_native: bool,
|
||||
_native_call: Option<NC>,
|
||||
) -> (Result<NativeOrEncoded<R>>, bool) {
|
||||
) -> (Result<Vec<u8>>, bool) {
|
||||
tracing::trace!(
|
||||
target: "executor",
|
||||
%method,
|
||||
@@ -363,7 +355,7 @@ where
|
||||
|module, mut instance, _onchain_version, mut ext| {
|
||||
with_externalities_safe(&mut **ext, move || {
|
||||
preregister_builtin_ext(module.clone());
|
||||
instance.call_export(method, data).map(NativeOrEncoded::Encoded)
|
||||
instance.call_export(method, data)
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -594,18 +586,14 @@ fn preregister_builtin_ext(module: Arc<dyn WasmModule>) {
|
||||
impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeElseWasmExecutor<D> {
|
||||
type Error = Error;
|
||||
|
||||
fn call<
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
fn call(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
runtime_code: &RuntimeCode,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
use_native: bool,
|
||||
native_call: Option<NC>,
|
||||
) -> (Result<NativeOrEncoded<R>>, bool) {
|
||||
) -> (Result<Vec<u8>>, bool) {
|
||||
tracing::trace!(
|
||||
target: "executor",
|
||||
function = %method,
|
||||
@@ -623,49 +611,31 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeElseWasmExecut
|
||||
let can_call_with =
|
||||
onchain_version.can_call_with(&self.native_version.runtime_version);
|
||||
|
||||
match (use_native, can_call_with, native_call) {
|
||||
(_, false, _) | (false, _, _) => {
|
||||
if !can_call_with {
|
||||
tracing::trace!(
|
||||
target: "executor",
|
||||
native = %self.native_version.runtime_version,
|
||||
chain = %onchain_version,
|
||||
"Request for native execution failed",
|
||||
);
|
||||
}
|
||||
if use_native && can_call_with {
|
||||
tracing::trace!(
|
||||
target: "executor",
|
||||
native = %self.native_version.runtime_version,
|
||||
chain = %onchain_version,
|
||||
"Request for native execution succeeded",
|
||||
);
|
||||
|
||||
with_externalities_safe(&mut **ext, move || {
|
||||
preregister_builtin_ext(module.clone());
|
||||
instance.call_export(method, data).map(NativeOrEncoded::Encoded)
|
||||
})
|
||||
},
|
||||
(true, true, Some(call)) => {
|
||||
used_native = true;
|
||||
Ok(with_externalities_safe(&mut **ext, move || D::dispatch(method, data))?
|
||||
.ok_or_else(|| Error::MethodNotFound(method.to_owned())))
|
||||
} else {
|
||||
if !can_call_with {
|
||||
tracing::trace!(
|
||||
target: "executor",
|
||||
native = %self.native_version.runtime_version,
|
||||
chain = %onchain_version,
|
||||
"Request for native execution with native call succeeded"
|
||||
"Request for native execution failed",
|
||||
);
|
||||
}
|
||||
|
||||
used_native = true;
|
||||
let res = with_externalities_safe(&mut **ext, move || (call)())
|
||||
.and_then(|r| r.map(NativeOrEncoded::Native).map_err(Error::ApiError));
|
||||
|
||||
Ok(res)
|
||||
},
|
||||
_ => {
|
||||
tracing::trace!(
|
||||
target: "executor",
|
||||
native = %self.native_version.runtime_version,
|
||||
chain = %onchain_version,
|
||||
"Request for native execution succeeded",
|
||||
);
|
||||
|
||||
used_native = true;
|
||||
Ok(with_externalities_safe(&mut **ext, move || D::dispatch(method, data))?
|
||||
.map(NativeOrEncoded::Encoded)
|
||||
.ok_or_else(|| Error::MethodNotFound(method.to_owned())))
|
||||
},
|
||||
with_externalities_safe(&mut **ext, move || {
|
||||
preregister_builtin_ext(module.clone());
|
||||
instance.call_export(method, data)
|
||||
})
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -17,21 +17,17 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::{client::ClientConfig, wasm_override::WasmOverride, wasm_substitutes::WasmSubstitutes};
|
||||
use codec::{Decode, Encode};
|
||||
use sc_client_api::{backend, call_executor::CallExecutor, HeaderBackend};
|
||||
use sc_executor::{RuntimeVersion, RuntimeVersionOf};
|
||||
use sp_api::{ProofRecorder, StorageTransactionCache};
|
||||
use sp_core::{
|
||||
traits::{CodeExecutor, RuntimeCode, SpawnNamed},
|
||||
NativeOrEncoded, NeverNativeValue,
|
||||
};
|
||||
use sp_core::traits::{CodeExecutor, RuntimeCode, SpawnNamed};
|
||||
use sp_externalities::Extensions;
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
use sp_state_machine::{
|
||||
backend::AsTrieBackend, ExecutionManager, ExecutionStrategy, Ext, OverlayedChanges,
|
||||
StateMachine, StorageProof,
|
||||
};
|
||||
use std::{cell::RefCell, panic::UnwindSafe, result, sync::Arc};
|
||||
use std::{cell::RefCell, sync::Arc};
|
||||
|
||||
/// Call executor that executes methods locally, querying all required
|
||||
/// data from local backend.
|
||||
@@ -162,7 +158,7 @@ where
|
||||
sp_blockchain::Error::UnknownBlock(format!("Could not find block hash for {:?}", at))
|
||||
})?;
|
||||
|
||||
let return_data = StateMachine::new(
|
||||
let mut sm = StateMachine::new(
|
||||
&state,
|
||||
&mut changes,
|
||||
&self.executor,
|
||||
@@ -172,22 +168,17 @@ where
|
||||
&runtime_code,
|
||||
self.spawn_handle.clone(),
|
||||
)
|
||||
.set_parent_hash(at_hash)
|
||||
.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
strategy.get_manager(),
|
||||
None,
|
||||
)?;
|
||||
.set_parent_hash(at_hash);
|
||||
|
||||
Ok(return_data.into_encoded())
|
||||
sm.execute_using_consensus_failure_handler(strategy.get_manager())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn contextual_call<
|
||||
EM: Fn(
|
||||
Result<NativeOrEncoded<R>, Self::Error>,
|
||||
Result<NativeOrEncoded<R>, Self::Error>,
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
Result<Vec<u8>, Self::Error>,
|
||||
Result<Vec<u8>, Self::Error>,
|
||||
) -> Result<Vec<u8>, Self::Error>,
|
||||
>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
@@ -196,10 +187,9 @@ where
|
||||
changes: &RefCell<OverlayedChanges>,
|
||||
storage_transaction_cache: Option<&RefCell<StorageTransactionCache<Block, B::State>>>,
|
||||
execution_manager: ExecutionManager<EM>,
|
||||
native_call: Option<NC>,
|
||||
recorder: &Option<ProofRecorder<Block>>,
|
||||
extensions: Option<Extensions>,
|
||||
) -> Result<NativeOrEncoded<R>, sp_blockchain::Error>
|
||||
) -> Result<Vec<u8>, sp_blockchain::Error>
|
||||
where
|
||||
ExecutionManager<EM>: Clone,
|
||||
{
|
||||
@@ -242,10 +232,7 @@ where
|
||||
)
|
||||
.with_storage_transaction_cache(storage_transaction_cache.as_deref_mut())
|
||||
.set_parent_hash(at_hash);
|
||||
state_machine.execute_using_consensus_failure_handler(
|
||||
execution_manager,
|
||||
native_call.map(|n| || (n)().map_err(|e| Box::new(e) as Box<_>)),
|
||||
)
|
||||
state_machine.execute_using_consensus_failure_handler(execution_manager)
|
||||
},
|
||||
None => {
|
||||
let mut state_machine = StateMachine::new(
|
||||
@@ -260,10 +247,7 @@ where
|
||||
)
|
||||
.with_storage_transaction_cache(storage_transaction_cache.as_deref_mut())
|
||||
.set_parent_hash(at_hash);
|
||||
state_machine.execute_using_consensus_failure_handler(
|
||||
execution_manager,
|
||||
native_call.map(|n| || (n)().map_err(|e| Box::new(e) as Box<_>)),
|
||||
)
|
||||
state_machine.execute_using_consensus_failure_handler(execution_manager)
|
||||
},
|
||||
}
|
||||
.map_err(Into::into)
|
||||
|
||||
@@ -22,7 +22,6 @@ use super::{
|
||||
block_rules::{BlockRules, LookupResult as BlockLookupResult},
|
||||
genesis,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use log::{info, trace, warn};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use prometheus_endpoint::Registry;
|
||||
@@ -59,12 +58,9 @@ use sp_blockchain::{
|
||||
use sp_consensus::{BlockOrigin, BlockStatus, Error as ConsensusError};
|
||||
|
||||
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender};
|
||||
use sp_core::{
|
||||
storage::{
|
||||
well_known_keys, ChildInfo, ChildType, PrefixedStorageKey, Storage, StorageChild,
|
||||
StorageData, StorageKey,
|
||||
},
|
||||
NativeOrEncoded,
|
||||
use sp_core::storage::{
|
||||
well_known_keys, ChildInfo, ChildType, PrefixedStorageKey, Storage, StorageChild, StorageData,
|
||||
StorageKey,
|
||||
};
|
||||
#[cfg(feature = "test-helpers")]
|
||||
use sp_keystore::SyncCryptoStorePtr;
|
||||
@@ -85,9 +81,7 @@ use sp_trie::{CompactProof, StorageProof};
|
||||
use std::{
|
||||
collections::{hash_map::DefaultHasher, HashMap, HashSet},
|
||||
marker::PhantomData,
|
||||
panic::UnwindSafe,
|
||||
path::PathBuf,
|
||||
result,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
@@ -1659,27 +1653,23 @@ where
|
||||
{
|
||||
type StateBackend = B::State;
|
||||
|
||||
fn call_api_at<
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
>(
|
||||
fn call_api_at(
|
||||
&self,
|
||||
params: CallApiAtParams<Block, NC, B::State>,
|
||||
) -> Result<NativeOrEncoded<R>, sp_api::ApiError> {
|
||||
params: CallApiAtParams<Block, B::State>,
|
||||
) -> Result<Vec<u8>, sp_api::ApiError> {
|
||||
let at = params.at;
|
||||
|
||||
let (manager, extensions) =
|
||||
self.execution_extensions.manager_and_extensions(at, params.context);
|
||||
|
||||
self.executor
|
||||
.contextual_call::<fn(_, _) -> _, _, _>(
|
||||
.contextual_call(
|
||||
at,
|
||||
params.function,
|
||||
¶ms.arguments,
|
||||
params.overlayed_changes,
|
||||
Some(params.storage_transaction_cache),
|
||||
manager,
|
||||
params.native_call,
|
||||
params.recorder,
|
||||
Some(extensions),
|
||||
)
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
|
||||
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
|
||||
<&[(T,)] as EncodeLike<LinkedList<LikeT>>>
|
||||
<&[T] as EncodeLike<Vec<U>>>
|
||||
and 279 others
|
||||
and 278 others
|
||||
= note: required because of the requirements on the impl of `FullEncode` for `Bar`
|
||||
= note: required because of the requirements on the impl of `FullCodec` for `Bar`
|
||||
= note: required because of the requirements on the impl of `PartialStorageInfoTrait` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>`
|
||||
@@ -103,7 +103,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
|
||||
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
|
||||
<&[(T,)] as EncodeLike<LinkedList<LikeT>>>
|
||||
<&[T] as EncodeLike<Vec<U>>>
|
||||
and 279 others
|
||||
and 278 others
|
||||
= note: required because of the requirements on the impl of `FullEncode` for `Bar`
|
||||
= note: required because of the requirements on the impl of `FullCodec` for `Bar`
|
||||
= note: required because of the requirements on the impl of `StorageEntryMetadataBuilder` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>`
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
|
||||
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
|
||||
<&[(T,)] as EncodeLike<LinkedList<LikeT>>>
|
||||
<&[T] as EncodeLike<Vec<U>>>
|
||||
and 279 others
|
||||
and 278 others
|
||||
= note: required because of the requirements on the impl of `FullEncode` for `Bar`
|
||||
= note: required because of the requirements on the impl of `FullCodec` for `Bar`
|
||||
= note: required because of the requirements on the impl of `PartialStorageInfoTrait` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>`
|
||||
@@ -103,7 +103,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
|
||||
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
|
||||
<&[(T,)] as EncodeLike<LinkedList<LikeT>>>
|
||||
<&[T] as EncodeLike<Vec<U>>>
|
||||
and 279 others
|
||||
and 278 others
|
||||
= note: required because of the requirements on the impl of `FullEncode` for `Bar`
|
||||
= note: required because of the requirements on the impl of `FullCodec` for `Bar`
|
||||
= note: required because of the requirements on the impl of `StorageEntryMetadataBuilder` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>`
|
||||
|
||||
@@ -449,28 +449,30 @@ impl<'a> ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
}
|
||||
|
||||
let res = (|| {
|
||||
let version = #crate_::CallApiAt::<__SR_API_BLOCK__>::runtime_version_at(self.call, at)?;
|
||||
let version = #crate_::CallApiAt::<__SR_API_BLOCK__>::runtime_version_at(
|
||||
self.call,
|
||||
at,
|
||||
)?;
|
||||
|
||||
let params = #crate_::CallApiAtParams::<_, fn() -> _, _> {
|
||||
at,
|
||||
function: (*fn_name)(version),
|
||||
native_call: None,
|
||||
arguments: params,
|
||||
overlayed_changes: &self.changes,
|
||||
storage_transaction_cache: &self.storage_transaction_cache,
|
||||
context,
|
||||
recorder: &self.recorder,
|
||||
};
|
||||
let params = #crate_::CallApiAtParams {
|
||||
at,
|
||||
function: (*fn_name)(version),
|
||||
arguments: params,
|
||||
overlayed_changes: &self.changes,
|
||||
storage_transaction_cache: &self.storage_transaction_cache,
|
||||
context,
|
||||
recorder: &self.recorder,
|
||||
};
|
||||
|
||||
#crate_::CallApiAt::<__SR_API_BLOCK__>::call_api_at::<#crate_::NeverNativeValue, _>(
|
||||
self.call,
|
||||
params,
|
||||
)
|
||||
})();
|
||||
#crate_::CallApiAt::<__SR_API_BLOCK__>::call_api_at(
|
||||
self.call,
|
||||
params,
|
||||
)
|
||||
})();
|
||||
|
||||
self.commit_or_rollback(std::result::Result::is_ok(&res));
|
||||
|
||||
res.map(#crate_::NativeOrEncoded::into_encoded)
|
||||
res
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -83,8 +83,6 @@ use sp_core::OpaqueMetadata;
|
||||
pub use sp_core::{offchain, ExecutionContext};
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_core::{NativeOrEncoded, NeverNativeValue};
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_runtime::StateVersion;
|
||||
#[doc(hidden)]
|
||||
pub use sp_runtime::{
|
||||
@@ -102,14 +100,12 @@ pub use sp_state_machine::{
|
||||
backend::AsTrieBackend, Backend as StateBackend, InMemoryBackend, OverlayedChanges,
|
||||
StorageProof, TrieBackend, TrieBackendBuilder,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use sp_std::result;
|
||||
#[doc(hidden)]
|
||||
pub use sp_std::{mem, slice};
|
||||
#[doc(hidden)]
|
||||
pub use sp_version::{create_apis_vec, ApiId, ApisVec, RuntimeVersion};
|
||||
#[cfg(feature = "std")]
|
||||
use std::{cell::RefCell, panic::UnwindSafe};
|
||||
use std::cell::RefCell;
|
||||
|
||||
/// Maximum nesting level for extrinsics.
|
||||
pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
|
||||
@@ -590,16 +586,11 @@ pub trait ApiExt<Block: BlockT> {
|
||||
|
||||
/// Parameters for [`CallApiAt::call_api_at`].
|
||||
#[cfg(feature = "std")]
|
||||
pub struct CallApiAtParams<'a, Block: BlockT, NC, Backend: StateBackend<HashFor<Block>>> {
|
||||
pub struct CallApiAtParams<'a, Block: BlockT, Backend: StateBackend<HashFor<Block>>> {
|
||||
/// The block id that determines the state that should be setup when calling the function.
|
||||
pub at: &'a BlockId<Block>,
|
||||
/// The name of the function that should be called.
|
||||
pub function: &'static str,
|
||||
/// An optional native call that calls the `function`. This is an optimization to call into a
|
||||
/// native runtime without requiring to encode/decode the parameters. The native runtime can
|
||||
/// still be called when this value is `None`, we then just fallback to encoding/decoding the
|
||||
/// parameters.
|
||||
pub native_call: Option<NC>,
|
||||
/// The encoded arguments of the function.
|
||||
pub arguments: Vec<u8>,
|
||||
/// The overlayed changes that are on top of the state.
|
||||
@@ -620,13 +611,10 @@ pub trait CallApiAt<Block: BlockT> {
|
||||
|
||||
/// Calls the given api function with the given encoded arguments at the given block and returns
|
||||
/// the encoded result.
|
||||
fn call_api_at<
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, ApiError> + UnwindSafe,
|
||||
>(
|
||||
fn call_api_at(
|
||||
&self,
|
||||
params: CallApiAtParams<Block, NC, Self::StateBackend>,
|
||||
) -> Result<NativeOrEncoded<R>, ApiError>;
|
||||
params: CallApiAtParams<Block, Self::StateBackend>,
|
||||
) -> Result<Vec<u8>, ApiError>;
|
||||
|
||||
/// Returns the runtime version at the given block.
|
||||
fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, ApiError>;
|
||||
|
||||
@@ -40,8 +40,6 @@ pub use serde;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sp_runtime_interface::pass_by::{PassByEnum, PassByInner};
|
||||
use sp_std::{ops::Deref, prelude::*};
|
||||
#[cfg(feature = "std")]
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub use sp_debug_derive::RuntimeDebug;
|
||||
|
||||
@@ -209,85 +207,6 @@ impl OpaquePeerId {
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that is either a native or an encoded value.
|
||||
#[cfg(feature = "std")]
|
||||
pub enum NativeOrEncoded<R> {
|
||||
/// The native representation.
|
||||
Native(R),
|
||||
/// The encoded representation.
|
||||
Encoded(Vec<u8>),
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<R> From<R> for NativeOrEncoded<R> {
|
||||
fn from(val: R) -> Self {
|
||||
Self::Native(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<R: codec::Encode> sp_std::fmt::Debug for NativeOrEncoded<R> {
|
||||
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
|
||||
hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<R: codec::Encode> NativeOrEncoded<R> {
|
||||
/// Return the value as the encoded format.
|
||||
pub fn as_encoded(&self) -> Cow<'_, [u8]> {
|
||||
match self {
|
||||
NativeOrEncoded::Encoded(e) => Cow::Borrowed(e.as_slice()),
|
||||
NativeOrEncoded::Native(n) => Cow::Owned(n.encode()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value as the encoded format.
|
||||
pub fn into_encoded(self) -> Vec<u8> {
|
||||
match self {
|
||||
NativeOrEncoded::Encoded(e) => e,
|
||||
NativeOrEncoded::Native(n) => n.encode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<R: PartialEq + codec::Decode> PartialEq for NativeOrEncoded<R> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(NativeOrEncoded::Native(l), NativeOrEncoded::Native(r)) => l == r,
|
||||
(NativeOrEncoded::Native(n), NativeOrEncoded::Encoded(e)) |
|
||||
(NativeOrEncoded::Encoded(e), NativeOrEncoded::Native(n)) =>
|
||||
Some(n) == codec::Decode::decode(&mut &e[..]).ok().as_ref(),
|
||||
(NativeOrEncoded::Encoded(l), NativeOrEncoded::Encoded(r)) => l == r,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A value that is never in a native representation.
|
||||
/// This is type is useful in conjunction with `NativeOrEncoded`.
|
||||
#[cfg(feature = "std")]
|
||||
#[derive(PartialEq)]
|
||||
pub enum NeverNativeValue {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl codec::Encode for NeverNativeValue {
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
// The enum is not constructable, so this function should never be callable!
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl codec::EncodeLike for NeverNativeValue {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl codec::Decode for NeverNativeValue {
|
||||
fn decode<I: codec::Input>(_: &mut I) -> Result<Self, codec::Error> {
|
||||
Err("`NeverNativeValue` should never be decoded".into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide a simple 4 byte identifier for a type.
|
||||
pub trait TypeId {
|
||||
/// Simple 4 byte identifier.
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fmt::{Debug, Display},
|
||||
panic::UnwindSafe,
|
||||
};
|
||||
|
||||
pub use sp_externalities::{Externalities, ExternalitiesExt};
|
||||
@@ -32,18 +31,14 @@ pub trait CodeExecutor: Sized + Send + Sync + ReadRuntimeVersion + Clone + 'stat
|
||||
|
||||
/// Call a given method in the runtime. Returns a tuple of the result (either the output data
|
||||
/// or an execution error) together with a `bool`, which is true if native execution was used.
|
||||
fn call<
|
||||
R: codec::Codec + PartialEq,
|
||||
NC: FnOnce() -> Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
fn call(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
runtime_code: &RuntimeCode,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
use_native: bool,
|
||||
native_call: Option<NC>,
|
||||
) -> (Result<crate::NativeOrEncoded<R>, Self::Error>, bool);
|
||||
) -> (Result<Vec<u8>, Self::Error>, bool);
|
||||
}
|
||||
|
||||
/// Something that can fetch the runtime `:code`.
|
||||
|
||||
@@ -157,31 +157,28 @@ mod execution {
|
||||
use crate::backend::AsTrieBackend;
|
||||
|
||||
use super::*;
|
||||
use codec::{Codec, Decode, Encode};
|
||||
use codec::Codec;
|
||||
use hash_db::Hasher;
|
||||
use smallvec::SmallVec;
|
||||
use sp_core::{
|
||||
hexdisplay::HexDisplay,
|
||||
storage::{ChildInfo, ChildType, PrefixedStorageKey},
|
||||
traits::{CodeExecutor, ReadRuntimeVersionExt, RuntimeCode, SpawnNamed},
|
||||
NativeOrEncoded, NeverNativeValue,
|
||||
};
|
||||
use sp_externalities::Extensions;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt,
|
||||
panic::UnwindSafe,
|
||||
result,
|
||||
};
|
||||
|
||||
const PROOF_CLOSE_TRANSACTION: &str = "\
|
||||
Closing a transaction that was started in this function. Client initiated transactions
|
||||
are protected from being closed by the runtime. qed";
|
||||
|
||||
pub(crate) type CallResult<R, E> = Result<NativeOrEncoded<R>, E>;
|
||||
pub(crate) type CallResult<E> = Result<Vec<u8>, E>;
|
||||
|
||||
/// Default handler of the execution manager.
|
||||
pub type DefaultHandler<R, E> = fn(CallResult<R, E>, CallResult<R, E>) -> CallResult<R, E>;
|
||||
pub type DefaultHandler<E> = fn(CallResult<E>, CallResult<E>) -> CallResult<E>;
|
||||
|
||||
/// Trie backend with in-memory storage.
|
||||
pub type InMemoryBackend<H> = TrieBackend<MemoryDB<H>, H>;
|
||||
@@ -243,9 +240,7 @@ mod execution {
|
||||
|
||||
impl ExecutionStrategy {
|
||||
/// Gets the corresponding manager for the execution strategy.
|
||||
pub fn get_manager<E: fmt::Debug, R: Decode + Encode>(
|
||||
self,
|
||||
) -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
pub fn get_manager<E: fmt::Debug>(self) -> ExecutionManager<DefaultHandler<E>> {
|
||||
match self {
|
||||
ExecutionStrategy::AlwaysWasm =>
|
||||
ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted),
|
||||
@@ -265,19 +260,19 @@ mod execution {
|
||||
}
|
||||
|
||||
/// Evaluate to ExecutionManager::NativeElseWasm, without having to figure out the type.
|
||||
pub fn native_else_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
pub fn native_else_wasm<E>() -> ExecutionManager<DefaultHandler<E>> {
|
||||
ExecutionManager::NativeElseWasm
|
||||
}
|
||||
|
||||
/// Evaluate to ExecutionManager::AlwaysWasm with trusted backend, without having to figure out
|
||||
/// the type.
|
||||
fn always_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
fn always_wasm<E>() -> ExecutionManager<DefaultHandler<E>> {
|
||||
ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted)
|
||||
}
|
||||
|
||||
/// Evaluate ExecutionManager::AlwaysWasm with untrusted backend, without having to figure out
|
||||
/// the type.
|
||||
fn always_untrusted_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
fn always_untrusted_wasm<E>() -> ExecutionManager<DefaultHandler<E>> {
|
||||
ExecutionManager::AlwaysWasm(BackendTrustLevel::Untrusted)
|
||||
}
|
||||
|
||||
@@ -379,23 +374,10 @@ mod execution {
|
||||
pub fn execute(&mut self, strategy: ExecutionStrategy) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
// We are not giving a native call and thus we are sure that the result can never be a
|
||||
// native value.
|
||||
self.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
strategy.get_manager(),
|
||||
None,
|
||||
)
|
||||
.map(NativeOrEncoded::into_encoded)
|
||||
self.execute_using_consensus_failure_handler(strategy.get_manager())
|
||||
}
|
||||
|
||||
fn execute_aux<R, NC>(
|
||||
&mut self,
|
||||
use_native: bool,
|
||||
native_call: Option<NC>,
|
||||
) -> (CallResult<R, Exec::Error>, bool)
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>>
|
||||
+ UnwindSafe,
|
||||
{
|
||||
fn execute_aux(&mut self, use_native: bool) -> (CallResult<Exec::Error>, bool) {
|
||||
let mut cache = StorageTransactionCache::default();
|
||||
|
||||
let cache = match self.storage_transaction_cache.as_mut() {
|
||||
@@ -426,7 +408,6 @@ mod execution {
|
||||
self.method,
|
||||
self.call_data,
|
||||
use_native,
|
||||
native_call,
|
||||
);
|
||||
|
||||
self.overlay
|
||||
@@ -444,26 +425,20 @@ mod execution {
|
||||
(result, was_native)
|
||||
}
|
||||
|
||||
fn execute_call_with_both_strategy<Handler, R, NC>(
|
||||
fn execute_call_with_both_strategy<Handler>(
|
||||
&mut self,
|
||||
mut native_call: Option<NC>,
|
||||
on_consensus_failure: Handler,
|
||||
) -> CallResult<R, Exec::Error>
|
||||
) -> CallResult<Exec::Error>
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>>
|
||||
+ UnwindSafe,
|
||||
Handler: FnOnce(
|
||||
CallResult<R, Exec::Error>,
|
||||
CallResult<R, Exec::Error>,
|
||||
) -> CallResult<R, Exec::Error>,
|
||||
Handler:
|
||||
FnOnce(CallResult<Exec::Error>, CallResult<Exec::Error>) -> CallResult<Exec::Error>,
|
||||
{
|
||||
self.overlay.start_transaction();
|
||||
let (result, was_native) = self.execute_aux(true, native_call.take());
|
||||
let (result, was_native) = self.execute_aux(true);
|
||||
|
||||
if was_native {
|
||||
self.overlay.rollback_transaction().expect(PROOF_CLOSE_TRANSACTION);
|
||||
let (wasm_result, _) = self.execute_aux(false, native_call);
|
||||
let (wasm_result, _) = self.execute_aux(false);
|
||||
|
||||
if (result.is_ok() &&
|
||||
wasm_result.is_ok() && result.as_ref().ok() == wasm_result.as_ref().ok()) ||
|
||||
@@ -479,25 +454,16 @@ mod execution {
|
||||
}
|
||||
}
|
||||
|
||||
fn execute_call_with_native_else_wasm_strategy<R, NC>(
|
||||
&mut self,
|
||||
mut native_call: Option<NC>,
|
||||
) -> CallResult<R, Exec::Error>
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>>
|
||||
+ UnwindSafe,
|
||||
{
|
||||
fn execute_call_with_native_else_wasm_strategy(&mut self) -> CallResult<Exec::Error> {
|
||||
self.overlay.start_transaction();
|
||||
let (result, was_native) = self.execute_aux(true, native_call.take());
|
||||
let (result, was_native) = self.execute_aux(true);
|
||||
|
||||
if !was_native || result.is_ok() {
|
||||
self.overlay.commit_transaction().expect(PROOF_CLOSE_TRANSACTION);
|
||||
result
|
||||
} else {
|
||||
self.overlay.rollback_transaction().expect(PROOF_CLOSE_TRANSACTION);
|
||||
let (wasm_result, _) = self.execute_aux(false, native_call);
|
||||
wasm_result
|
||||
self.execute_aux(false).0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,35 +476,29 @@ mod execution {
|
||||
///
|
||||
/// Returns the result of the executed function either in native representation `R` or
|
||||
/// in SCALE encoded representation.
|
||||
pub fn execute_using_consensus_failure_handler<Handler, R, NC>(
|
||||
pub fn execute_using_consensus_failure_handler<Handler>(
|
||||
&mut self,
|
||||
manager: ExecutionManager<Handler>,
|
||||
mut native_call: Option<NC>,
|
||||
) -> Result<NativeOrEncoded<R>, Box<dyn Error>>
|
||||
) -> Result<Vec<u8>, Box<dyn Error>>
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>>
|
||||
+ UnwindSafe,
|
||||
Handler: FnOnce(
|
||||
CallResult<R, Exec::Error>,
|
||||
CallResult<R, Exec::Error>,
|
||||
) -> CallResult<R, Exec::Error>,
|
||||
Handler:
|
||||
FnOnce(CallResult<Exec::Error>, CallResult<Exec::Error>) -> CallResult<Exec::Error>,
|
||||
{
|
||||
let result = {
|
||||
match manager {
|
||||
ExecutionManager::Both(on_consensus_failure) => self
|
||||
.execute_call_with_both_strategy(native_call.take(), on_consensus_failure),
|
||||
ExecutionManager::Both(on_consensus_failure) =>
|
||||
self.execute_call_with_both_strategy(on_consensus_failure),
|
||||
ExecutionManager::NativeElseWasm =>
|
||||
self.execute_call_with_native_else_wasm_strategy(native_call.take()),
|
||||
self.execute_call_with_native_else_wasm_strategy(),
|
||||
ExecutionManager::AlwaysWasm(trust_level) => {
|
||||
let _abort_guard = match trust_level {
|
||||
BackendTrustLevel::Trusted => None,
|
||||
BackendTrustLevel::Untrusted =>
|
||||
Some(sp_panic_handler::AbortGuard::never_abort()),
|
||||
};
|
||||
self.execute_aux(false, native_call).0
|
||||
self.execute_aux(false).0
|
||||
},
|
||||
ExecutionManager::NativeWhenPossible => self.execute_aux(true, native_call).0,
|
||||
ExecutionManager::NativeWhenPossible => self.execute_aux(true).0,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -603,29 +563,23 @@ mod execution {
|
||||
let proving_backend =
|
||||
TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
|
||||
|
||||
let result = {
|
||||
let mut sm = StateMachine::<_, H, Exec>::new(
|
||||
&proving_backend,
|
||||
overlay,
|
||||
exec,
|
||||
method,
|
||||
call_data,
|
||||
Extensions::default(),
|
||||
runtime_code,
|
||||
spawn_handle,
|
||||
);
|
||||
|
||||
sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
always_wasm(),
|
||||
None,
|
||||
)?
|
||||
};
|
||||
let result = StateMachine::<_, H, Exec>::new(
|
||||
&proving_backend,
|
||||
overlay,
|
||||
exec,
|
||||
method,
|
||||
call_data,
|
||||
Extensions::default(),
|
||||
runtime_code,
|
||||
spawn_handle,
|
||||
)
|
||||
.execute_using_consensus_failure_handler::<_>(always_wasm())?;
|
||||
|
||||
let proof = proving_backend
|
||||
.extract_proof()
|
||||
.expect("A recorder was set and thus, a storage proof can be extracted; qed");
|
||||
|
||||
Ok((result.into_encoded(), proof))
|
||||
Ok((result, proof))
|
||||
}
|
||||
|
||||
/// Check execution proof, generated by `prove_execution` call.
|
||||
@@ -673,7 +627,7 @@ mod execution {
|
||||
Exec: CodeExecutor + Clone + 'static,
|
||||
Spawn: SpawnNamed + Send + 'static,
|
||||
{
|
||||
let mut sm = StateMachine::<_, H, Exec>::new(
|
||||
StateMachine::<_, H, Exec>::new(
|
||||
trie_backend,
|
||||
overlay,
|
||||
exec,
|
||||
@@ -682,13 +636,8 @@ mod execution {
|
||||
Extensions::default(),
|
||||
runtime_code,
|
||||
spawn_handle,
|
||||
);
|
||||
|
||||
sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
always_untrusted_wasm(),
|
||||
None,
|
||||
)
|
||||
.map(NativeOrEncoded::into_encoded)
|
||||
.execute_using_consensus_failure_handler(always_untrusted_wasm())
|
||||
}
|
||||
|
||||
/// Generate storage read proof.
|
||||
@@ -1362,21 +1311,16 @@ mod tests {
|
||||
use super::{backend::AsTrieBackend, ext::Ext, *};
|
||||
use crate::{execution::CallResult, in_memory_backend::new_in_mem_hash_key};
|
||||
use assert_matches::assert_matches;
|
||||
use codec::{Decode, Encode};
|
||||
use codec::Encode;
|
||||
use sp_core::{
|
||||
map,
|
||||
storage::{ChildInfo, StateVersion},
|
||||
testing::TaskExecutor,
|
||||
traits::{CodeExecutor, Externalities, RuntimeCode},
|
||||
NativeOrEncoded, NeverNativeValue,
|
||||
};
|
||||
use sp_runtime::traits::BlakeTwo256;
|
||||
use sp_trie::trie_types::{TrieDBMutBuilderV0, TrieDBMutBuilderV1};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
panic::UnwindSafe,
|
||||
result,
|
||||
};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct DummyCodeExecutor {
|
||||
@@ -1388,28 +1332,20 @@ mod tests {
|
||||
impl CodeExecutor for DummyCodeExecutor {
|
||||
type Error = u8;
|
||||
|
||||
fn call<
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
fn call(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
_: &RuntimeCode,
|
||||
_method: &str,
|
||||
_data: &[u8],
|
||||
use_native: bool,
|
||||
native_call: Option<NC>,
|
||||
) -> (CallResult<R, Self::Error>, bool) {
|
||||
) -> (CallResult<Self::Error>, bool) {
|
||||
let using_native = use_native && self.native_available;
|
||||
match (using_native, self.native_succeeds, self.fallback_succeeds, native_call) {
|
||||
(true, true, _, Some(call)) => {
|
||||
let res = sp_externalities::set_and_run_with_externalities(ext, call);
|
||||
(res.map(NativeOrEncoded::Native).map_err(|_| 0), true)
|
||||
},
|
||||
(true, true, _, None) | (false, _, true, None) => (
|
||||
Ok(NativeOrEncoded::Encoded(vec![
|
||||
match (using_native, self.native_succeeds, self.fallback_succeeds) {
|
||||
(true, true, _) | (false, _, true) => (
|
||||
Ok(vec![
|
||||
ext.storage(b"value1").unwrap()[0] + ext.storage(b"value2").unwrap()[0],
|
||||
])),
|
||||
]),
|
||||
using_native,
|
||||
),
|
||||
_ => (Err(0), using_native),
|
||||
@@ -1510,13 +1446,10 @@ mod tests {
|
||||
);
|
||||
|
||||
assert!(state_machine
|
||||
.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
ExecutionManager::Both(|we, _ne| {
|
||||
consensus_failed = true;
|
||||
we
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.execute_using_consensus_failure_handler(ExecutionManager::Both(|we, _ne| {
|
||||
consensus_failed = true;
|
||||
we
|
||||
}),)
|
||||
.is_err());
|
||||
assert!(consensus_failed);
|
||||
}
|
||||
@@ -2260,51 +2193,4 @@ mod tests {
|
||||
overlay.commit_transaction().unwrap();
|
||||
assert_eq!(overlay.storage(b"ccc"), Some(None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn runtime_registered_extensions_are_removed_after_execution() {
|
||||
let state_version = StateVersion::default();
|
||||
use sp_externalities::ExternalitiesExt;
|
||||
sp_externalities::decl_extension! {
|
||||
struct DummyExt(u32);
|
||||
}
|
||||
|
||||
let backend = trie_backend::tests::test_trie(state_version, None, None);
|
||||
let mut overlayed_changes = Default::default();
|
||||
let wasm_code = RuntimeCode::empty();
|
||||
|
||||
let mut state_machine = StateMachine::new(
|
||||
&backend,
|
||||
&mut overlayed_changes,
|
||||
&DummyCodeExecutor {
|
||||
native_available: true,
|
||||
native_succeeds: true,
|
||||
fallback_succeeds: false,
|
||||
},
|
||||
"test",
|
||||
&[],
|
||||
Default::default(),
|
||||
&wasm_code,
|
||||
TaskExecutor::new(),
|
||||
);
|
||||
|
||||
let run_state_machine = |state_machine: &mut StateMachine<_, _, _>| {
|
||||
state_machine
|
||||
.execute_using_consensus_failure_handler::<fn(_, _) -> _, _, _>(
|
||||
ExecutionManager::NativeWhenPossible,
|
||||
Some(|| {
|
||||
sp_externalities::with_externalities(|mut ext| {
|
||||
ext.register_extension(DummyExt(2)).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
};
|
||||
|
||||
run_state_machine(&mut state_machine);
|
||||
run_state_machine(&mut state_machine);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +322,6 @@ mod tests {
|
||||
use sp_core::{
|
||||
map,
|
||||
traits::{CodeExecutor, RuntimeCode},
|
||||
NeverNativeValue,
|
||||
};
|
||||
use sp_io::{hashing::twox_128, TestExternalities};
|
||||
use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring};
|
||||
@@ -406,14 +405,7 @@ mod tests {
|
||||
};
|
||||
|
||||
executor()
|
||||
.call::<NeverNativeValue, fn() -> _>(
|
||||
&mut ext,
|
||||
&runtime_code,
|
||||
"Core_execute_block",
|
||||
&b.encode(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.call(&mut ext, &runtime_code, "Core_execute_block", &b.encode(), false)
|
||||
.0
|
||||
.unwrap();
|
||||
})
|
||||
@@ -515,14 +507,7 @@ mod tests {
|
||||
};
|
||||
|
||||
executor()
|
||||
.call::<NeverNativeValue, fn() -> _>(
|
||||
&mut ext,
|
||||
&runtime_code,
|
||||
"Core_execute_block",
|
||||
&b.encode(),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.call(&mut ext, &runtime_code, "Core_execute_block", &b.encode(), false)
|
||||
.0
|
||||
.unwrap();
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user