Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Filecoin.Filecoin.StateGetRandomnessFromBeacon API #3704

Merged
merged 12 commits into from
Nov 13, 2023
4 changes: 4 additions & 0 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ where
.with_method(STATE_GET_RECEIPT, state_get_receipt::<DB>)
.with_method(STATE_WAIT_MSG, state_wait_msg::<DB>)
.with_method(STATE_FETCH_ROOT, state_fetch_root::<DB>)
.with_method(
STATE_GET_RANDOMNESS_FROM_BEACON,
state_get_randomness_from_beacon::<DB>,
)
// Gas API
.with_method(GAS_ESTIMATE_FEE_CAP, gas_estimate_fee_cap::<DB>)
.with_method(GAS_ESTIMATE_GAS_LIMIT, gas_estimate_gas_limit::<DB>)
Expand Down
32 changes: 30 additions & 2 deletions src/rpc/state_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use crate::libp2p::NetworkMessage;
use crate::lotus_json::LotusJson;
use crate::rpc_api::data_types::{MarketDeal, MessageLookup, RPCState};
use crate::shim::{
address::Address, executor::Receipt, message::Message, state_tree::ActorState,
version::NetworkVersion,
address::Address, clock::ChainEpoch, executor::Receipt, message::Message,
state_tree::ActorState, version::NetworkVersion,
};
use crate::state_manager::chain_rand::ChainRand;
use crate::state_manager::{InvocResult, MarketBalance};
use crate::utils::db::car_stream::{CarBlock, CarWriter};
use ahash::{HashMap, HashMapExt};
Expand All @@ -28,6 +29,8 @@ use std::path::PathBuf;
use std::{sync::Arc, time::Duration};
use tokio::task::JoinSet;

type RandomnessParams = (i64, ChainEpoch, Vec<u8>, TipsetKeys);
sudo-shashank marked this conversation as resolved.
Show resolved Hide resolved

/// runs the given message and returns its result without any persisted changes.
pub(in crate::rpc) async fn state_call<DB: Blockstore + Send + Sync + 'static>(
data: Data<RPCState<DB>>,
Expand Down Expand Up @@ -349,3 +352,28 @@ pub(in crate::rpc) async fn state_fetch_root<DB: Blockstore + Sync + Send + 'sta
fn lock_pop<T>(mutex: &Mutex<Vec<T>>) -> Option<T> {
mutex.lock().pop()
}

/// Get randomness from beacon
pub(in crate::rpc) async fn state_get_randomness_from_beacon<
DB: Blockstore + Send + Sync + 'static,
>(
data: Data<RPCState<DB>>,
Params(LotusJson((personalization, rand_epoch, entropy, tsk))): Params<
LotusJson<RandomnessParams>,
>,
) -> Result<LotusJson<Vec<u8>>, JsonRpcError> {
let state_manager = &data.state_manager;
let tipset = state_manager.chain_store().load_required_tipset(&tsk)?;
let chain_config = state_manager.chain_config();
let chain_index = &data.chain_store.chain_index;
let beacon = state_manager.beacon_schedule();
let chain_rand = ChainRand::new(chain_config.clone(), tipset, chain_index.clone(), beacon);
let digest = chain_rand.get_beacon_randomness_v3(rand_epoch)?;
let value = crate::state_manager::chain_rand::draw_randomness_from_digest(
&digest,
personalization,
rand_epoch,
&entropy,
)?;
Ok(LotusJson(value.to_vec()))
}
1 change: 1 addition & 0 deletions src/rpc_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub static ACCESS_MAP: Lazy<HashMap<&str, Access>> = Lazy::new(|| {
access.insert(state_api::STATE_NETWORK_NAME, Access::Read);
access.insert(state_api::STATE_NETWORK_VERSION, Access::Read);
access.insert(state_api::STATE_FETCH_ROOT, Access::Read);
access.insert(state_api::STATE_GET_RANDOMNESS_FROM_BEACON, Access::Read);

// Gas API
access.insert(gas_api::GAS_ESTIMATE_GAS_LIMIT, Access::Read);
Expand Down
2 changes: 1 addition & 1 deletion src/rpc_client/state_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl ApiInfo {
) -> RpcRequest<Vec<u8>> {
RpcRequest::new(
STATE_GET_RANDOMNESS_FROM_BEACON,
(personalization as u32, rand_epoch, entropy, tsk),
(personalization as i64, rand_epoch, entropy, tsk),
)
}

Expand Down
17 changes: 17 additions & 0 deletions src/state_manager/chain_rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ pub fn draw_randomness(
Ok(ret)
}

/// Computes a pseudo random 32 byte `Vec` from digest
pub fn draw_randomness_from_digest(
digest: &[u8; 32],
pers: i64,
round: ChainEpoch,
entropy: &[u8],
) -> anyhow::Result<[u8; 32]> {
let mut state = Params::new().hash_length(32).to_state();
state.write_i64::<BigEndian>(pers)?;
state.write_all(digest)?;
state.write_i64::<BigEndian>(round)?;
state.write_all(entropy)?;
let mut ret = [0u8; 32];
ret.clone_from_slice(state.finalize().as_bytes());
Ok(ret)
}

/// Computes a 256-bit digest.
/// See <https://github.com/filecoin-project/ref-fvm/blob/master/fvm/CHANGELOG.md#360-2023-08-18>
pub fn digest(rbase: &[u8]) -> [u8; 32] {
Expand Down
Loading