From 758f59b95822eeadb106193ef595309aed719a34 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Fri, 24 Aug 2018 17:26:21 +0300 Subject: [PATCH] Specify how much gas to allot for a create --- substrate/runtime/contract/src/tests.rs | 8 +++++--- substrate/runtime/contract/src/vm/env_def/mod.rs | 10 +++++++--- substrate/runtime/contract/src/vm/mod.rs | 9 +++++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/substrate/runtime/contract/src/tests.rs b/substrate/runtime/contract/src/tests.rs index a362dc250d728..9b65c7bdb7ca7 100644 --- a/substrate/runtime/contract/src/tests.rs +++ b/substrate/runtime/contract/src/tests.rs @@ -343,18 +343,20 @@ fn code_create(constructor: &[u8]) -> String { ;; ext_create( ;; code_ptr: u32, ;; code_len: u32, + ;; gas: u64, ;; value_ptr: u32, ;; value_len: u32, ;; input_data_ptr: u32, ;; input_data_len: u32, ;; ) -> u32 - (import "env" "ext_create" (func $ext_create (param i32 i32 i32 i32 i32 i32) (result i32))) + (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop (call $ext_create (i32.const 12) ;; Pointer to `code` (i32.const {code_len}) ;; Length of `code` + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 4) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer (i32.const 0) ;; Pointer to input data buffer address @@ -398,12 +400,12 @@ fn contract_create() { ); // 11 - value sent with the transaction - // 2 * 138 - gas spent by the deployer contract (138) multiplied by gas price (2) + // 2 * 139 - gas spent by the deployer contract (139) multiplied by gas price (2) // 2 * 135 - base gas fee for call (top level) // 2 * 175 - base gas fee for create (by contract) // ((21 / 2) * 2) - price per account creation let expected_gas_after_create = - 100_000_000 - 11 - (2 * 138) - (2 * 135) - (2 * 175) - ((21 / 2) * 2); + 100_000_000 - 11 - (2 * 139) - (2 * 135) - (2 * 175) - ((21 / 2) * 2); assert_eq!(Staking::free_balance(&0), expected_gas_after_create); assert_eq!(Staking::free_balance(&1), 8); assert_eq!(Staking::free_balance(&derived_address), 3); diff --git a/substrate/runtime/contract/src/vm/env_def/mod.rs b/substrate/runtime/contract/src/vm/env_def/mod.rs index 23f0cd092ddf2..eb6c16ca8a07e 100644 --- a/substrate/runtime/contract/src/vm/env_def/mod.rs +++ b/substrate/runtime/contract/src/vm/env_def/mod.rs @@ -222,10 +222,11 @@ define_env!(init_env, , } }, - // ext_create(code_ptr: u32, code_len: u32, value_ptr: u32, value_len: u32, input_data_ptr: u32, input_data_len: u32) -> u32 + // ext_create(code_ptr: u32, code_len: u32, gas: u64, value_ptr: u32, value_len: u32, input_data_ptr: u32, input_data_len: u32) -> u32 ext_create( ctx, code_ptr: u32, code_len: u32, + gas: u64, value_ptr: u32, value_len: u32, input_data_ptr: u32, @@ -245,8 +246,11 @@ define_env!(init_env, , input_data.resize(input_data_len as usize, 0u8); ctx.memory().get(input_data_ptr, &mut input_data)?; - // TODO: Let user to choose how much gas to allocate for the execution. - let nested_gas_limit = ctx.gas_meter.gas_left(); + let nested_gas_limit = if gas == 0 { + ctx.gas_meter.gas_left() + } else { + <<::T as Trait>::Gas as As>::sa(gas) + }; let ext = &mut ctx.ext; let create_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| { match nested_meter { diff --git a/substrate/runtime/contract/src/vm/mod.rs b/substrate/runtime/contract/src/vm/mod.rs index 34b30608ffa62..f7dd9934bb24f 100644 --- a/substrate/runtime/contract/src/vm/mod.rs +++ b/substrate/runtime/contract/src/vm/mod.rs @@ -276,6 +276,7 @@ mod tests { code: Vec, endowment: u64, data: Vec, + gas_left: u64, } #[derive(Debug, PartialEq, Eq)] struct TransferEntry { @@ -304,13 +305,14 @@ mod tests { &mut self, code: &[u8], endowment: u64, - _gas_meter: &mut GasMeter, + gas_meter: &mut GasMeter, data: &[u8], ) -> Result, ()> { self.creates.push(CreateEntry { code: code.to_vec(), endowment, data: data.to_vec(), + gas_left: gas_meter.gas_left(), }); let address = self.next_account_id; self.next_account_id += 1; @@ -405,18 +407,20 @@ mod tests { ;; ext_create( ;; code_ptr: u32, ;; code_len: u32, + ;; gas: u64, ;; value_ptr: u32, ;; value_len: u32, ;; input_data_ptr: u32, ;; input_data_len: u32, ;; ) -> u32 - (import "env" "ext_create" (func $ext_create (param i32 i32 i32 i32 i32 i32) (result i32))) + (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop (call $ext_create (i32.const 12) ;; Pointer to `code` (i32.const 8) ;; Length of `code` + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 4) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer (i32.const 20) ;; Pointer to input data buffer address @@ -454,6 +458,7 @@ mod tests { data: vec![ 1, 2, 3, 4, ], + gas_left: 49990, }] ); }