mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-08 17:08:00 +00:00
Some trivial externalities added (#1450)
* Add gas_left, gas_price and balance externalities * Add a value_transferred externality
This commit is contained in:
committed by
Gav Wood
parent
1ccb590d18
commit
0ad2a5fb96
@@ -82,6 +82,14 @@ pub trait Ext {
|
||||
|
||||
/// Returns a reference to the account id of the current contract.
|
||||
fn address(&self) -> &AccountIdOf<Self::T>;
|
||||
|
||||
/// Returns the balance of the current contract.
|
||||
///
|
||||
/// The `value_transferred` is already added.
|
||||
fn balance(&self) -> BalanceOf<Self::T>;
|
||||
|
||||
/// Returns the value transfered along with this call or as endowment.
|
||||
fn value_transferred(&self) -> BalanceOf<Self::T>;
|
||||
}
|
||||
|
||||
/// Loader is a companion of the `Vm` trait. It loads an appropriate abstract
|
||||
@@ -292,6 +300,7 @@ where
|
||||
&mut CallContext {
|
||||
ctx: &mut nested,
|
||||
caller: self.self_account.clone(),
|
||||
value_transferred: value,
|
||||
},
|
||||
input_data,
|
||||
empty_output_buf,
|
||||
@@ -361,6 +370,7 @@ where
|
||||
&mut CallContext {
|
||||
ctx: &mut nested,
|
||||
caller: self.self_account.clone(),
|
||||
value_transferred: endowment,
|
||||
},
|
||||
input_data,
|
||||
EmptyOutputBuf::new(),
|
||||
@@ -509,6 +519,7 @@ fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
|
||||
struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm<T> + 'b, L: Loader<T>> {
|
||||
ctx: &'a mut ExecutionContext<'b, T, V, L>,
|
||||
caller: T::AccountId,
|
||||
value_transferred: T::Balance,
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a, T, E, V, L> Ext for CallContext<'a, 'b, T, V, L>
|
||||
@@ -558,6 +569,14 @@ where
|
||||
fn caller(&self) -> &T::AccountId {
|
||||
&self.caller
|
||||
}
|
||||
|
||||
fn balance(&self) -> T::Balance {
|
||||
self.ctx.overlay.get_balance(&self.ctx.self_account)
|
||||
}
|
||||
|
||||
fn value_transferred(&self) -> T::Balance {
|
||||
self.value_transferred
|
||||
}
|
||||
}
|
||||
|
||||
/// These tests exercise the executive layer.
|
||||
|
||||
@@ -254,6 +254,12 @@ mod tests {
|
||||
fn address(&self) -> &u64 {
|
||||
&69
|
||||
}
|
||||
fn balance(&self) -> u64 {
|
||||
228
|
||||
}
|
||||
fn value_transferred(&self) -> u64 {
|
||||
1337
|
||||
}
|
||||
}
|
||||
|
||||
fn execute<E: Ext>(
|
||||
@@ -686,6 +692,257 @@ mod tests {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const CODE_BALANCE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_balance" (func $ext_balance))
|
||||
(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))
|
||||
(import "env" "ext_scratch_copy" (func $ext_scratch_copy (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(get_local 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the balance in the scratch buffer
|
||||
(call $ext_balance)
|
||||
|
||||
;; assert $ext_scratch_size == 8
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $ext_scratch_size)
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; copy contents of the scratch buffer into the contract's memory.
|
||||
(call $ext_scratch_copy
|
||||
(i32.const 8) ;; Pointer in memory to the place where to copy.
|
||||
(i32.const 0) ;; Offset from the start of the scratch buffer.
|
||||
(i32.const 8) ;; Count of bytes to copy.
|
||||
)
|
||||
|
||||
;; assert that contents of the buffer is equal to the i64 value of 228.
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
(i64.const 228)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn balance() {
|
||||
let mut mock_ext = MockExt::default();
|
||||
let mut gas_meter = GasMeter::with_limit(50_000, 1);
|
||||
execute(
|
||||
CODE_BALANCE,
|
||||
&[],
|
||||
&mut Vec::new(),
|
||||
&mut mock_ext,
|
||||
&mut gas_meter,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const CODE_GAS_PRICE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_gas_price" (func $ext_gas_price))
|
||||
(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))
|
||||
(import "env" "ext_scratch_copy" (func $ext_scratch_copy (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(get_local 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the gas price in the scratch buffer
|
||||
(call $ext_gas_price)
|
||||
|
||||
;; assert $ext_scratch_size == 8
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $ext_scratch_size)
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; copy contents of the scratch buffer into the contract's memory.
|
||||
(call $ext_scratch_copy
|
||||
(i32.const 8) ;; Pointer in memory to the place where to copy.
|
||||
(i32.const 0) ;; Offset from the start of the scratch buffer.
|
||||
(i32.const 8) ;; Count of bytes to copy.
|
||||
)
|
||||
|
||||
;; assert that contents of the buffer is equal to the i64 value of 1312.
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
(i64.const 1312)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn gas_price() {
|
||||
let mut mock_ext = MockExt::default();
|
||||
let mut gas_meter = GasMeter::with_limit(50_000, 1312);
|
||||
execute(
|
||||
CODE_GAS_PRICE,
|
||||
&[],
|
||||
&mut Vec::new(),
|
||||
&mut mock_ext,
|
||||
&mut gas_meter,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const CODE_GAS_LEFT: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_gas_left" (func $ext_gas_left))
|
||||
(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))
|
||||
(import "env" "ext_scratch_copy" (func $ext_scratch_copy (param i32 i32 i32)))
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(get_local 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the gas left in the scratch buffer
|
||||
(call $ext_gas_left)
|
||||
|
||||
;; assert $ext_scratch_size == 8
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $ext_scratch_size)
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; copy contents of the scratch buffer into the contract's memory.
|
||||
(call $ext_scratch_copy
|
||||
(i32.const 8) ;; Pointer in memory to the place where to copy.
|
||||
(i32.const 0) ;; Offset from the start of the scratch buffer.
|
||||
(i32.const 8) ;; Count of bytes to copy.
|
||||
)
|
||||
|
||||
(call $ext_return
|
||||
(i32.const 8)
|
||||
(i32.const 8)
|
||||
)
|
||||
|
||||
(unreachable)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn gas_left() {
|
||||
let mut mock_ext = MockExt::default();
|
||||
let mut gas_meter = GasMeter::with_limit(50_000, 1312);
|
||||
execute(
|
||||
CODE_GAS_LEFT,
|
||||
&[],
|
||||
&mut Vec::new(),
|
||||
&mut mock_ext,
|
||||
&mut gas_meter,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const CODE_VALUE_TRANSFERRED: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_value_transferred" (func $ext_value_transferred))
|
||||
(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))
|
||||
(import "env" "ext_scratch_copy" (func $ext_scratch_copy (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(get_local 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the value transferred in the scratch buffer
|
||||
(call $ext_value_transferred)
|
||||
|
||||
;; assert $ext_scratch_size == 8
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $ext_scratch_size)
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; copy contents of the scratch buffer into the contract's memory.
|
||||
(call $ext_scratch_copy
|
||||
(i32.const 8) ;; Pointer in memory to the place where to copy.
|
||||
(i32.const 0) ;; Offset from the start of the scratch buffer.
|
||||
(i32.const 8) ;; Count of bytes to copy.
|
||||
)
|
||||
|
||||
;; assert that contents of the buffer is equal to the i64 value of 1337.
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
(i64.const 1337)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn value_transferred() {
|
||||
let mut mock_ext = MockExt::default();
|
||||
let mut gas_meter = GasMeter::with_limit(50_000, 1);
|
||||
execute(
|
||||
CODE_VALUE_TRANSFERRED,
|
||||
&[],
|
||||
&mut Vec::new(),
|
||||
&mut mock_ext,
|
||||
&mut gas_meter,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
||||
const CODE_RETURN_FROM_START_FN: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32)))
|
||||
@@ -709,6 +966,7 @@ mod tests {
|
||||
)
|
||||
"#;
|
||||
|
||||
|
||||
#[test]
|
||||
fn return_from_start_fn() {
|
||||
let mut mock_ext = MockExt::default();
|
||||
|
||||
@@ -447,6 +447,38 @@ define_env!(Env, <E: Ext>,
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Stores the gas price for the current transaction into the scratch buffer.
|
||||
//
|
||||
// The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten.
|
||||
ext_gas_price(ctx) => {
|
||||
ctx.scratch_buf = ctx.gas_meter.gas_price().encode();
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Stores the amount of gas left into the scratch buffer.
|
||||
//
|
||||
// The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten.
|
||||
ext_gas_left(ctx) => {
|
||||
ctx.scratch_buf = ctx.gas_meter.gas_left().encode();
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Stores the balance of the current account into the scratch buffer.
|
||||
//
|
||||
// The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten.
|
||||
ext_balance(ctx) => {
|
||||
ctx.scratch_buf = ctx.ext.balance().encode();
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Stores the value transferred along with this call or as endowment into the scratch buffer.
|
||||
//
|
||||
// The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten.
|
||||
ext_value_transferred(ctx) => {
|
||||
ctx.scratch_buf = ctx.ext.value_transferred().encode();
|
||||
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