From 63c15c9803c36973cb8b1320b2ab5c76c8d2466e Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin <sergei@parity.io> Date: Sun, 1 Sep 2019 02:19:31 +0200 Subject: [PATCH] Minimum balance (#3519) --- substrate/srml/contracts/src/exec.rs | 7 +++ substrate/srml/contracts/src/wasm/mod.rs | 66 ++++++++++++++++++++ substrate/srml/contracts/src/wasm/runtime.rs | 10 +++ 3 files changed, 83 insertions(+) diff --git a/substrate/srml/contracts/src/exec.rs b/substrate/srml/contracts/src/exec.rs index 818a689f99d..586ee3746b8 100644 --- a/substrate/srml/contracts/src/exec.rs +++ b/substrate/srml/contracts/src/exec.rs @@ -154,6 +154,9 @@ pub trait Ext { /// Returns a reference to the timestamp of the current block fn now(&self) -> &MomentOf<Self::T>; + /// Returns the minimum balance that is required for creating an account. + fn minimum_balance(&self) -> BalanceOf<Self::T>; + /// Returns a random number for the current block with the given subject. fn random(&self, subject: &[u8]) -> SeedOf<Self::T>; @@ -766,6 +769,10 @@ where &self.timestamp } + fn minimum_balance(&self) -> BalanceOf<T> { + self.ctx.config.existential_deposit + } + fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) { self.ctx.deferred.push(DeferredAction::DepositEvent { topics, diff --git a/substrate/srml/contracts/src/wasm/mod.rs b/substrate/srml/contracts/src/wasm/mod.rs index 99578fee274..c623313824b 100644 --- a/substrate/srml/contracts/src/wasm/mod.rs +++ b/substrate/srml/contracts/src/wasm/mod.rs @@ -282,6 +282,10 @@ mod tests { &1111 } + fn minimum_balance(&self) -> u64 { + 666 + } + fn random(&self, subject: &[u8]) -> H256 { H256::from_slice(subject) } @@ -364,6 +368,9 @@ mod tests { fn now(&self) -> &u64 { (**self).now() } + fn minimum_balance(&self) -> u64 { + (**self).minimum_balance() + } fn random(&self, subject: &[u8]) -> H256 { (**self).random(subject) } @@ -1176,6 +1183,65 @@ mod tests { ).unwrap(); } + const CODE_MINIMUM_BALANCE: &str = r#" +(module + (import "env" "ext_minimum_balance" (func $ext_minimum_balance)) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (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") + (call $ext_minimum_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_read + (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 666. + (call $assert + (i64.eq + (i64.load + (i32.const 8) + ) + (i64.const 666) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn minimum_balance() { + let mut gas_meter = GasMeter::with_limit(50_000, 1); + let _ = execute( + CODE_MINIMUM_BALANCE, + vec![], + MockExt::default(), + &mut gas_meter, + ).unwrap(); + } + const CODE_RANDOM: &str = r#" (module (import "env" "ext_random" (func $ext_random (param i32 i32))) diff --git a/substrate/srml/contracts/src/wasm/runtime.rs b/substrate/srml/contracts/src/wasm/runtime.rs index c6ef1bb3f56..4baece3d918 100644 --- a/substrate/srml/contracts/src/wasm/runtime.rs +++ b/substrate/srml/contracts/src/wasm/runtime.rs @@ -611,6 +611,16 @@ define_env!(Env, <E: Ext>, Ok(()) }, + // Stores the minimum balance (a.k.a. existential deposit) into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are + // overwritten. + ext_minimum_balance(ctx) => { + ctx.scratch_buf.clear(); + ctx.ext.minimum_balance().encode_to(&mut ctx.scratch_buf); + Ok(()) + }, + // Decodes the given buffer as a `T::Call` and adds it to the list // of to-be-dispatched calls. // -- GitLab