Some trivial externalities added (#1450)

* Add gas_left, gas_price and balance externalities

* Add a value_transferred externality
This commit is contained in:
Sergei Pepyakin
2019-01-19 12:33:28 +01:00
committed by Gav Wood
parent 1ccb590d18
commit 0ad2a5fb96
3 changed files with 309 additions and 0 deletions
+258
View File
@@ -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)