mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 12:51:05 +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
@@ -21,11 +21,11 @@ use exec::{Ext, BalanceOf, VmExecResult, OutputBuf, EmptyOutputBuf, CallReceipt,
|
||||
use rstd::prelude::*;
|
||||
use rstd::mem;
|
||||
use codec::{Decode, Encode};
|
||||
use gas::{GasMeter, Token, GasMeterResult};
|
||||
use gas::{GasMeter, Token, GasMeterResult, approx_gas_for_balance};
|
||||
use runtime_primitives::traits::{As, CheckedMul, Bounded};
|
||||
use sandbox;
|
||||
use system;
|
||||
use {Trait, CodeHash};
|
||||
use {Trait, CodeHash, ComputeDispatchFee};
|
||||
|
||||
/// Enumerates all possible *special* trap conditions.
|
||||
///
|
||||
@@ -96,7 +96,7 @@ pub(crate) fn to_execution_result<E: Ext>(
|
||||
|
||||
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum RuntimeToken {
|
||||
pub enum RuntimeToken<Gas> {
|
||||
/// Explicit call to the `gas` function. Charge the gas meter
|
||||
/// with the value provided.
|
||||
Explicit(u32),
|
||||
@@ -107,9 +107,11 @@ pub enum RuntimeToken {
|
||||
/// The given number of bytes is read from the sandbox memory and
|
||||
/// is returned as the return data buffer of the call.
|
||||
ReturnData(u32),
|
||||
/// Dispatch fee calculated by `T::ComputeDispatchFee`.
|
||||
ComputedDispatchFee(Gas),
|
||||
}
|
||||
|
||||
impl<T: Trait> Token<T> for RuntimeToken {
|
||||
impl<T: Trait> Token<T> for RuntimeToken<T::Gas> {
|
||||
type Metadata = Schedule<T::Gas>;
|
||||
|
||||
fn calculate_amount(&self, metadata: &Schedule<T::Gas>) -> T::Gas {
|
||||
@@ -125,6 +127,7 @@ impl<T: Trait> Token<T> for RuntimeToken {
|
||||
ReturnData(byte_count) => metadata
|
||||
.return_data_per_byte_cost
|
||||
.checked_mul(&<T::Gas as As<u32>>::sa(byte_count)),
|
||||
ComputedDispatchFee(gas) => Some(gas),
|
||||
};
|
||||
|
||||
value.unwrap_or_else(|| Bounded::max_value())
|
||||
@@ -482,6 +485,30 @@ define_env!(Env, <E: Ext>,
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Decodes the given buffer as a `T::Call` and adds it to the list
|
||||
// of to-be-dispatched calls.
|
||||
//
|
||||
// All calls made it to the top-level context will be dispatched before
|
||||
// finishing the execution of the calling extrinsic.
|
||||
ext_dispatch_call(ctx, call_ptr: u32, call_len: u32) => {
|
||||
let call = {
|
||||
let call_buf = read_sandbox_memory(ctx, call_ptr, call_len)?;
|
||||
<<<E as Ext>::T as Trait>::Call>::decode(&mut &call_buf[..])
|
||||
.ok_or_else(|| sandbox::HostError)?
|
||||
};
|
||||
|
||||
// Charge gas for dispatching this call.
|
||||
let fee = {
|
||||
let balance_fee = <<E as Ext>::T as Trait>::ComputeDispatchFee::compute_dispatch_fee(&call);
|
||||
approx_gas_for_balance::<<E as Ext>::T>(ctx.gas_meter.gas_price(), balance_fee)
|
||||
};
|
||||
charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::ComputedDispatchFee(fee))?;
|
||||
|
||||
ctx.ext.note_dispatch_call(call);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Returns the size of the input buffer.
|
||||
ext_input_size(ctx) -> u32 => {
|
||||
Ok(ctx.input_data.len() as u32)
|
||||
|
||||
Reference in New Issue
Block a user