diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index f931c2e7056..3656a8ce21d 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -483,7 +483,8 @@ where }) } -/// Returns a random hash seed. +/// Returns a random hash seed and the block number since which it was determinable +/// by chain observers. /// /// # Note /// @@ -493,7 +494,15 @@ where /// # Errors /// /// If the returned value cannot be properly decoded. -pub fn random(subject: &[u8]) -> Result +/// +/// # Important +/// +/// The returned seed should only be used to distinguish commitments made before +/// the returned block number. If the block number is too early (i.e. commitments were +/// made afterwards), then ensure no further commitments may be made and repeatedly +/// call this on later blocks until the block number returned is later than the latest +/// commitment. +pub fn random(subject: &[u8]) -> Result<(T::Hash, T::BlockNumber)> where T: Environment, { diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 53fb356165c..1ba69a4e76b 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -339,7 +339,7 @@ pub trait TypedEnvBackend: EnvBackend { /// # Note /// /// For more details visit: [`random`][`crate::random`] - fn random(&mut self, subject: &[u8]) -> Result + fn random(&mut self, subject: &[u8]) -> Result<(T::Hash, T::BlockNumber)> where T: Environment; } diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index cb6e98502f3..1cc650795c8 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -449,13 +449,11 @@ impl TypedEnvBackend for EnvInstance { self.transfer_impl::(&destination, value) } - fn random(&mut self, subject: &[u8]) -> Result + fn random(&mut self, subject: &[u8]) -> Result<(T::Hash, T::BlockNumber)> where T: Environment, { - self.current_block() - .expect(UNITIALIZED_EXEC_CONTEXT) - .random::(subject) - .map_err(Into::into) + let block = self.current_block().expect(UNITIALIZED_EXEC_CONTEXT); + Ok((block.random::(subject)?, block.number::()?)) } } diff --git a/crates/env/src/engine/on_chain/ext.rs b/crates/env/src/engine/on_chain/ext.rs index af02e3eab16..5458d9e5591 100644 --- a/crates/env/src/engine/on_chain/ext.rs +++ b/crates/env/src/engine/on_chain/ext.rs @@ -308,12 +308,6 @@ mod sys { pub fn seal_set_rent_allowance(value_ptr: Ptr32<[u8]>, value_len: u32); - pub fn seal_random( - subject_ptr: Ptr32<[u8]>, - subject_len: u32, - output_ptr: Ptr32Mut<[u8]>, - output_len_ptr: Ptr32Mut, - ); pub fn seal_println(str_ptr: Ptr32<[u8]>, str_len: u32); pub fn seal_hash_keccak_256( @@ -337,6 +331,16 @@ mod sys { output_ptr: Ptr32Mut<[u8]>, ); } + + #[link(wasm_import_module = "seal1")] + extern "C" { + pub fn seal_random( + subject_ptr: Ptr32<[u8]>, + subject_len: u32, + output_ptr: Ptr32Mut<[u8]>, + output_len_ptr: Ptr32Mut, + ); + } } fn extract_from_slice(output: &mut &mut [u8], new_len: usize) { diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index dd3b62a38a1..48282af1cc3 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -460,7 +460,7 @@ impl TypedEnvBackend for EnvInstance { scale::Decode::decode(&mut &output[..]).map_err(Into::into) } - fn random(&mut self, subject: &[u8]) -> Result + fn random(&mut self, subject: &[u8]) -> Result<(T::Hash, T::BlockNumber)> where T: Environment, { diff --git a/crates/lang/src/env_access.rs b/crates/lang/src/env_access.rs index faf316f9a71..f305c8a7670 100644 --- a/crates/lang/src/env_access.rs +++ b/crates/lang/src/env_access.rs @@ -303,7 +303,7 @@ where /// # Note /// /// For more details visit: [`ink_env::random`] - pub fn random(self, subject: &[u8]) -> T::Hash { + pub fn random(self, subject: &[u8]) -> (T::Hash, T::BlockNumber) { ink_env::random::(subject).expect("couldn't decode randomized hash") }