Expose block number in seal_random (#8329)

* Allow contract callable functions to specify the module

* Add new version of `seal_random`

* Fix overlong lines

* Fix benchmarking code

* Update README.md

* Replace Module by Pallet
This commit is contained in:
Alexander Theißen
2021-03-23 14:48:36 +01:00
committed by GitHub
parent f9b6c869a3
commit 1f911ddb61
7 changed files with 213 additions and 95 deletions
+85 -6
View File
@@ -192,8 +192,8 @@ where
let mut imports = sp_sandbox::EnvironmentDefinitionBuilder::new();
imports.add_memory(self::prepare::IMPORT_MODULE_MEMORY, "memory", memory.clone());
runtime::Env::impls(&mut |name, func_ptr| {
imports.add_host_func(self::prepare::IMPORT_MODULE_FN, name, func_ptr);
runtime::Env::impls(&mut |module, name, func_ptr| {
imports.add_host_func(module, name, func_ptr);
});
let mut runtime = Runtime::new(
@@ -246,7 +246,7 @@ mod tests {
use super::*;
use crate::{
CodeHash, BalanceOf, Error, Pallet as Contracts,
exec::{Ext, StorageKey, AccountIdOf, Executable, RentParams},
exec::{Ext, StorageKey, AccountIdOf, Executable, SeedOf, BlockNumberOf, RentParams},
gas::GasMeter,
tests::{Test, Call, ALICE, BOB},
};
@@ -414,8 +414,8 @@ mod tests {
fn tombstone_deposit(&self) -> u64 {
16
}
fn random(&self, subject: &[u8]) -> H256 {
H256::from_slice(subject)
fn random(&self, subject: &[u8]) -> (SeedOf<Self::T>, BlockNumberOf<Self::T>) {
(H256::from_slice(subject), 42)
}
fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>) {
self.events.push((topics, data))
@@ -515,7 +515,7 @@ mod tests {
fn tombstone_deposit(&self) -> u64 {
(**self).tombstone_deposit()
}
fn random(&self, subject: &[u8]) -> H256 {
fn random(&self, subject: &[u8]) -> (SeedOf<Self::T>, BlockNumberOf<Self::T>) {
(**self).random(subject)
}
fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>) {
@@ -1531,6 +1531,85 @@ mod tests {
);
}
const CODE_RANDOM_V1: &str = r#"
(module
(import "seal1" "seal_random" (func $seal_random (param i32 i32 i32 i32)))
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
(import "env" "memory" (memory 1 1))
;; [0,128) is reserved for the result of PRNG.
;; the subject used for the PRNG. [128,160)
(data (i32.const 128)
"\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F"
"\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F"
)
;; size of our buffer is 128 bytes
(data (i32.const 160) "\80")
(func $assert (param i32)
(block $ok
(br_if $ok
(get_local 0)
)
(unreachable)
)
)
(func (export "call")
;; This stores the block random seed in the buffer
(call $seal_random
(i32.const 128) ;; Pointer in memory to the start of the subject buffer
(i32.const 32) ;; The subject buffer's length
(i32.const 0) ;; Pointer to the output buffer
(i32.const 160) ;; Pointer to the output buffer length
)
;; assert len == 32
(call $assert
(i32.eq
(i32.load (i32.const 160))
(i32.const 40)
)
)
;; return the random data
(call $seal_return
(i32.const 0)
(i32.const 0)
(i32.const 40)
)
)
(func (export "deploy"))
)
"#;
#[test]
fn random_v1() {
let mut gas_meter = GasMeter::new(GAS_LIMIT);
let output = execute(
CODE_RANDOM_V1,
vec![],
MockExt::default(),
&mut gas_meter,
).unwrap();
// The mock ext just returns the same data that was passed as the subject.
assert_eq!(
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: (
hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"),
42u64,
).encode(),
},
);
}
const CODE_DEPOSIT_EVENT: &str = r#"
(module
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))