diff --git a/actors/evm/src/interpreter/precompiles/fvm.rs b/actors/evm/src/interpreter/precompiles/fvm.rs index dd9c52723..121ed40f8 100644 --- a/actors/evm/src/interpreter/precompiles/fvm.rs +++ b/actors/evm/src/interpreter/precompiles/fvm.rs @@ -220,3 +220,31 @@ pub(super) fn call_actor_shared( Ok(output) } + +/// Params: +/// +/// | Param | Value | +/// |------------------|---------------------------| +/// | randomness_epoch | U256 - low i64 | +/// | entropy_length | U256 - low u32 | +/// | entropy | input\[32..] (right padded)| +/// +/// any bytes in between values are ignored +/// +/// Returns empty array if invalid randomness type +/// Errors if unable to fetch randomness +pub(super) fn get_randomness( + system: &mut System, + input: &[u8], + _: PrecompileContext, +) -> PrecompileResult { + + let mut input_params = ValueReader::new(input); + + let randomness_epoch = input_params.read_value()?; + let entropy_length: u32 = input_params.read_value()?; + let entropy = input_params.read_padded(entropy_length.try_into().unwrap_or(0)); + + let randomness = system.rt.get_randomness_from_beacon(fil_actors_runtime::runtime::DomainSeparationTag::EvmRandPrecompile, randomness_epoch, &entropy); + randomness.map(|r| r.to_vec()).map_err(|_| PrecompileError::InvalidInput) +} \ No newline at end of file diff --git a/actors/evm/src/interpreter/precompiles/mod.rs b/actors/evm/src/interpreter/precompiles/mod.rs index 5faf7f68d..ddc95d603 100644 --- a/actors/evm/src/interpreter/precompiles/mod.rs +++ b/actors/evm/src/interpreter/precompiles/mod.rs @@ -13,7 +13,7 @@ mod evm; mod fvm; use evm::{blake2f, ec_add, ec_mul, ec_pairing, ec_recover, identity, modexp, ripemd160, sha256}; -use fvm::{call_actor, call_actor_id, lookup_delegated_address, resolve_address}; +use fvm::{call_actor, call_actor_id, lookup_delegated_address, resolve_address, get_randomness}; type PrecompileFn = fn(&mut System, &[u8], PrecompileContext) -> PrecompileResult; pub type PrecompileResult = Result, PrecompileError>; @@ -41,12 +41,13 @@ pub struct Precompiles(PhantomData); impl Precompiles { /// FEVM specific precompiles (0xfe prefix) - const NATIVE_PRECOMPILES: PrecompileTable = PrecompileTable([ + const NATIVE_PRECOMPILES: PrecompileTable = PrecompileTable([ Some(resolve_address::), // 0xfe00..01 Some(lookup_delegated_address::), // 0xfe00..02 Some(call_actor::), // 0xfe00..03 None, // 0xfe00..04 DISABLED Some(call_actor_id::), // 0xfe00..05 + Some(get_randomness::), // 0xfe00..06 ]); /// EVM specific precompiles diff --git a/runtime/src/runtime/randomness.rs b/runtime/src/runtime/randomness.rs index bb7d05d84..8283ad814 100644 --- a/runtime/src/runtime/randomness.rs +++ b/runtime/src/runtime/randomness.rs @@ -20,6 +20,7 @@ pub enum DomainSeparationTag { MarketDealCronSeed = 8, PoStChainCommit = 9, EvmPrevRandao = 10, + EvmRandPrecompile = 11, } #[allow(unused)]