From 437f70a70bcf58fef564034575c4fc1aa4cbf6b4 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 25 Aug 2023 13:13:24 -0400 Subject: [PATCH] feat: FVM no longer draws randomness for you (#1378) --- Cargo.lock | 1 + runtime/Cargo.toml | 1 + runtime/src/runtime/fvm.rs | 23 +++++++++-- runtime/src/runtime/randomness.rs | 63 +++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7827e88d65..bd0aa4894a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1749,6 +1749,7 @@ name = "fil_actors_runtime" version = "12.0.0" dependencies = [ "anyhow", + "base64 0.21.3", "blake2b_simd", "byteorder", "castaway", diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 2edb7badbe..cb0ec0f765 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -44,6 +44,7 @@ blake2b_simd = { workspace = true, optional = true } hex = { workspace = true, optional = true } pretty_env_logger = { workspace = true, optional = true } rand = { workspace = true, optional = true } +base64 = "0.21.2" [dependencies.libsecp256k1] workspace = true diff --git a/runtime/src/runtime/fvm.rs b/runtime/src/runtime/fvm.rs index 9b67b407ad..47ca30f61d 100644 --- a/runtime/src/runtime/fvm.rs +++ b/runtime/src/runtime/fvm.rs @@ -36,6 +36,7 @@ use std::cell::RefCell; use crate::runtime::actor_blockstore::ActorBlockstore; use crate::runtime::builtins::Type; +use crate::runtime::randomness::draw_randomness; use crate::runtime::{ ActorCode, ConsensusFault, DomainSeparationTag, MessageInfo, Policy, Primitives, RuntimePolicy, Verifier, @@ -231,14 +232,21 @@ where rand_epoch: ChainEpoch, entropy: &[u8], ) -> Result<[u8; RANDOMNESS_LENGTH], ActorError> { - fvm::rand::get_chain_randomness(personalization as i64, rand_epoch, entropy).map_err(|e| { + let digest = fvm::rand::get_chain_randomness(rand_epoch).map_err(|e| { match e { ErrorNumber::LimitExceeded => { actor_error!(illegal_argument; "randomness lookback exceeded: {}", e) } e => actor_error!(assertion_failed; "get chain randomness failed with an unexpected error: {}", e), } - }) + })?; + Ok(draw_randomness( + fvm::crypto::hash_blake2b, + &digest, + personalization, + rand_epoch, + entropy, + )) } fn get_randomness_from_beacon( @@ -247,14 +255,21 @@ where rand_epoch: ChainEpoch, entropy: &[u8], ) -> Result<[u8; RANDOMNESS_LENGTH], ActorError> { - fvm::rand::get_beacon_randomness(personalization as i64, rand_epoch, entropy).map_err(|e| { + let digest = fvm::rand::get_beacon_randomness(rand_epoch).map_err(|e| { match e { ErrorNumber::LimitExceeded => { actor_error!(illegal_argument; "randomness lookback exceeded: {}", e) } e => actor_error!(assertion_failed; "get beacon randomness failed with an unexpected error: {}", e), } - }) + })?; + Ok(draw_randomness( + fvm::crypto::hash_blake2b, + &digest, + personalization, + rand_epoch, + entropy, + )) } fn get_state_root(&self) -> Result { diff --git a/runtime/src/runtime/randomness.rs b/runtime/src/runtime/randomness.rs index b303c68e77..bb7d05d848 100644 --- a/runtime/src/runtime/randomness.rs +++ b/runtime/src/runtime/randomness.rs @@ -1,6 +1,8 @@ // Copyright 2019-2022 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT +use fvm_shared::clock::ChainEpoch; +use fvm_shared::randomness::RANDOMNESS_LENGTH; use num_derive::FromPrimitive; use serde_repr::*; @@ -19,3 +21,64 @@ pub enum DomainSeparationTag { PoStChainCommit = 9, EvmPrevRandao = 10, } + +#[allow(unused)] +pub fn draw_randomness( + hasher: impl FnOnce(&[u8]) -> [u8; 32], + rbase: &[u8; RANDOMNESS_LENGTH], + pers: DomainSeparationTag, + round: ChainEpoch, + entropy: &[u8], +) -> [u8; RANDOMNESS_LENGTH] { + let mut data = Vec::with_capacity(RANDOMNESS_LENGTH + 8 + 8 + entropy.len()); + + // Append the personalization value + let i64_bytes = (pers as i64).to_be_bytes(); + data.extend_from_slice(&i64_bytes); + + // Append the randomness + data.extend_from_slice(rbase); + + // Append the round + let i64_bytes = round.to_be_bytes(); + data.extend_from_slice(&i64_bytes); + + // Append the entropy + data.extend_from_slice(entropy); + + hasher(&data) + // + // fvm::crypto::hash_blake2b(&data) +} + +#[cfg(test)] +mod tests { + use crate::runtime::randomness::draw_randomness; + use crate::runtime::DomainSeparationTag; + use crate::test_utils::blake2b_256; + use base64::Engine; + + #[test] + fn draw_randomness_test() { + let expected_randomness = base64::engine::general_purpose::STANDARD + .decode("3MCqcLHKZ+pil4MqTS9wjsd+yPvTuTrq8PkGjEo3tYQ=") + .unwrap(); + + let digest = base64::engine::general_purpose::STANDARD + .decode("GOobxkrhS1hiFA1EYUKZM3xsyVfy5Xy3bQ0gLPnecYs=") + .unwrap(); + + let entropy = base64::engine::general_purpose::STANDARD.decode("RACZyzQ=").unwrap(); + + assert_eq!( + expected_randomness, + draw_randomness( + blake2b_256, + <&[u8; 32]>::try_from(digest.as_slice()).unwrap(), + DomainSeparationTag::SealRandomness, + 2797727, + entropy.as_slice(), + ) + ); + } +}