Skip to content

Commit

Permalink
feat: FVM no longer draws randomness for you (#1378)
Browse files Browse the repository at this point in the history
  • Loading branch information
arajasek authored and Stebalien committed Sep 21, 2023
1 parent c05e8fb commit 3f4757a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 19 additions & 4 deletions runtime/src/runtime/fvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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<Cid, ActorError> {
Expand Down
63 changes: 63 additions & 0 deletions runtime/src/runtime/randomness.rs
Original file line number Diff line number Diff line change
@@ -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::*;

Expand All @@ -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(),
)
);
}
}

0 comments on commit 3f4757a

Please sign in to comment.