mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 18:37:59 +00:00
Dispatch Calls to other modules (#1473)
* WIP * Use system::Origin::Signed as an origin * Add a vm test for ext_dispatch_call * Take fee for dispatching a Call # Conflicts: # node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm * Clean & Rebuild # Conflicts: # node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm * Dispatch call test. * Rebuild the runtime. * Fix the length of the buffer. * Rebuild binaries.
This commit is contained in:
committed by
Gav Wood
parent
22b65c9cb0
commit
58cd6530be
@@ -25,17 +25,13 @@ use runtime_primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
use runtime_primitives::BuildStorage;
|
||||
use runtime_support::{StorageMap, StorageDoubleMap};
|
||||
use substrate_primitives::{Blake2Hasher};
|
||||
use system::{Phase, EventRecord};
|
||||
use system::{ensure_signed, Phase, EventRecord};
|
||||
use wabt;
|
||||
use {
|
||||
balances, runtime_io, system, ContractAddressFor, GenesisConfig, Module, RawEvent, StorageOf,
|
||||
Trait,
|
||||
balances, runtime_io, system, ComputeDispatchFee, ContractAddressFor, GenesisConfig, Module, RawEvent, StorageOf,
|
||||
Trait
|
||||
};
|
||||
|
||||
impl_outer_origin! {
|
||||
pub enum Origin for Test {}
|
||||
}
|
||||
|
||||
mod contract {
|
||||
// Re-export contents of the root. This basically
|
||||
// needs to give a name for the current crate.
|
||||
@@ -47,6 +43,15 @@ impl_outer_event! {
|
||||
balances<T>, contract<T>,
|
||||
}
|
||||
}
|
||||
impl_outer_origin! {
|
||||
pub enum Origin for Test { }
|
||||
}
|
||||
impl_outer_dispatch! {
|
||||
pub enum Call for Test where origin: Origin {
|
||||
balances::Balances,
|
||||
contract::Contract,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct Test;
|
||||
@@ -71,9 +76,11 @@ impl balances::Trait for Test {
|
||||
type Event = MetaEvent;
|
||||
}
|
||||
impl Trait for Test {
|
||||
type Call = Call;
|
||||
type Gas = u64;
|
||||
type DetermineContractAddress = DummyContractAddressFor;
|
||||
type Event = MetaEvent;
|
||||
type ComputeDispatchFee = DummyComputeDispatchFee;
|
||||
}
|
||||
|
||||
type Balances = balances::Module<Test>;
|
||||
@@ -87,6 +94,13 @@ impl ContractAddressFor<H256, u64> for DummyContractAddressFor {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyComputeDispatchFee;
|
||||
impl ComputeDispatchFee<Call, u64> for DummyComputeDispatchFee {
|
||||
fn compute_dispatch_fee(call: &Call) -> u64 {
|
||||
69
|
||||
}
|
||||
}
|
||||
|
||||
const ALICE: u64 = 1;
|
||||
const BOB: u64 = 2;
|
||||
const CHARLIE: u64 = 3;
|
||||
@@ -298,3 +312,111 @@ fn instantiate_and_call() {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const CODE_DISPATCH_CALL: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_dispatch_call
|
||||
(i32.const 8) ;; Pointer to the start of encoded call buffer
|
||||
(i32.const 11) ;; Length of the buffer
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
|
||||
(data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8")
|
||||
)
|
||||
"#;
|
||||
const HASH_DISPATCH_CALL: [u8; 32] = hex!("49dfdcaf9c1553be10634467e95b8e71a3bc15a4f8bf5563c0312b0902e0afb9");
|
||||
|
||||
#[test]
|
||||
fn dispatch_call() {
|
||||
// This test can fail due to the encoding changes. In case it becomes too annoying
|
||||
// let's rewrite so as we use this module controlled call or we serialize it in runtime.
|
||||
let encoded = codec::Encode::encode(&Call::Balances(balances::Call::transfer(CHARLIE, 50.into())));
|
||||
assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]);
|
||||
|
||||
let wasm = wabt::wat2wasm(CODE_DISPATCH_CALL).unwrap();
|
||||
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default().existential_deposit(50).build(),
|
||||
|| {
|
||||
Balances::set_free_balance(&ALICE, 1_000_000);
|
||||
Balances::increase_total_stake_by(1_000_000);
|
||||
|
||||
assert_ok!(Contract::put_code(
|
||||
Origin::signed(ALICE),
|
||||
100_000.into(),
|
||||
wasm,
|
||||
));
|
||||
|
||||
// Let's keep this assert even though it's redundant. If you ever need to update the
|
||||
// wasm source this test will fail and will show you the actual hash.
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::contract(RawEvent::CodeStored(HASH_DISPATCH_CALL.into())),
|
||||
},
|
||||
]);
|
||||
|
||||
assert_ok!(Contract::create(
|
||||
Origin::signed(ALICE),
|
||||
100.into(),
|
||||
100_000.into(),
|
||||
HASH_DISPATCH_CALL.into(),
|
||||
vec![],
|
||||
));
|
||||
|
||||
assert_ok!(Contract::call(
|
||||
Origin::signed(ALICE),
|
||||
BOB, // newly created account
|
||||
0.into(),
|
||||
100_000.into(),
|
||||
vec![],
|
||||
));
|
||||
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::contract(RawEvent::CodeStored(HASH_DISPATCH_CALL.into())),
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::balances(
|
||||
balances::RawEvent::NewAccount(BOB, 100)
|
||||
)
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB))
|
||||
},
|
||||
|
||||
// Dispatching the call.
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::balances(
|
||||
balances::RawEvent::NewAccount(CHARLIE, 50)
|
||||
)
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::balances(
|
||||
balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0)
|
||||
)
|
||||
},
|
||||
|
||||
// Event emited as a result of dispatch.
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: MetaEvent::contract(RawEvent::Dispatched(BOB, true))
|
||||
}
|
||||
]);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user