Skip to content

Commit

Permalink
chore(rpc): new state manager api to simplify actor state loading log…
Browse files Browse the repository at this point in the history
…ic (#4560)
  • Loading branch information
hanabi1224 authored Jul 18, 2024
1 parent 776b99f commit 9d9b0af
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 11 deletions.
15 changes: 4 additions & 11 deletions src/rpc/methods/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,7 @@ impl RpcMethod<1> for StateVerifiedRegistryRootKey {
(ApiTipsetKey(tsk),): Self::Params,
) -> Result<Self::Ok, ServerError> {
let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?;
let actor = ctx
.state_manager
.get_required_actor(&Address::VERIFIED_REGISTRY_ACTOR, *ts.parent_state())?;
let state = verifreg::State::load(ctx.store(), actor.code, actor.state)?;
let state: verifreg::State = ctx.state_manager.get_actor_state(&ts)?;
Ok(state.root_key())
}
}
Expand Down Expand Up @@ -421,10 +418,7 @@ impl RpcMethod<1> for StateMarketDeals {
(ApiTipsetKey(tsk),): Self::Params,
) -> Result<Self::Ok, ServerError> {
let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?;
let actor = ctx
.state_manager
.get_required_actor(&Address::MARKET_ACTOR, *ts.parent_state())?;
let market_state = market::State::load(ctx.store(), actor.code, actor.state)?;
let market_state: market::State = ctx.state_manager.get_actor_state(&ts)?;

let da = market_state.proposals(ctx.store())?;
let sa = market_state.states(ctx.store())?;
Expand Down Expand Up @@ -489,10 +483,9 @@ impl RpcMethod<2> for StateMinerActiveSectors {
) -> Result<Self::Ok, ServerError> {
let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?;
let policy = &ctx.chain_config().policy;
let actor = ctx
let miner_state: miner::State = ctx
.state_manager
.get_required_actor(&address, *ts.parent_state())?;
let miner_state = miner::State::load(ctx.store(), actor.code, actor.state)?;
.get_actor_state_from_address(&ts, &address)?;
// Collect active sectors from each partition in each deadline.
let mut active_sectors = vec![];
miner_state.for_each_deadline(policy, ctx.store(), |_dlidx, deadline| {
Expand Down
39 changes: 39 additions & 0 deletions src/shim/actors/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::shim::{address::Address, state_tree::ActorState};
use fvm_ipld_blockstore::Blockstore;

pub trait LoadActorStateFromBlockstore: Sized {
const ACTOR: Option<Address> = None;

fn load(store: &impl Blockstore, actor: &ActorState) -> anyhow::Result<Self>;
}

mod load_actor_state_trait_impl {
use super::*;

macro_rules! impl_for {
($actor:ident $(, $addr:expr)?) => {
impl LoadActorStateFromBlockstore for fil_actor_interface::$actor::State {
$(const ACTOR: Option<Address> = Some($addr);)?
fn load(store: &impl Blockstore, actor: &ActorState) -> anyhow::Result<Self> {
Self::load(store, actor.code, actor.state)
}
}
};
}

impl_for!(account);
impl_for!(cron, Address::CRON_ACTOR);
impl_for!(datacap, Address::DATACAP_TOKEN_ACTOR);
impl_for!(evm);
impl_for!(init, Address::INIT_ACTOR);
impl_for!(market, Address::MARKET_ACTOR);
impl_for!(miner);
impl_for!(multisig);
impl_for!(power, Address::POWER_ACTOR);
impl_for!(reward, Address::REWARD_ACTOR);
impl_for!(system, Address::SYSTEM_ACTOR);
impl_for!(verifreg, Address::VERIFIED_REGISTRY_ACTOR);
}
3 changes: 3 additions & 0 deletions src/shim/actors/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

pub mod common;
pub mod market;
pub mod miner;
pub mod multisig;
pub mod verifreg;

pub use common::*;
26 changes: 26 additions & 0 deletions src/state_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::rpc::state::{ApiInvocResult, InvocResult, MessageGasCost};
use crate::rpc::types::{MiningBaseInfo, SectorOnChainInfo};
use crate::shim::actors::miner::MinerStateExt as _;
use crate::shim::actors::verifreg::VerifiedRegistryStateExt;
use crate::shim::actors::LoadActorStateFromBlockstore;
use crate::shim::{
address::{Address, Payload, Protocol},
clock::ChainEpoch,
Expand Down Expand Up @@ -274,6 +275,31 @@ where
state.get_actor(addr)
}

/// Gets actor state from implicit actor address
pub fn get_actor_state<S: LoadActorStateFromBlockstore>(
&self,
ts: &Tipset,
) -> anyhow::Result<S> {
let address = S::ACTOR.with_context(|| {
format!(
"No accociated actor address for {}, use `get_actor_state_from_address` instead.",
std::any::type_name::<S>()
)
})?;
let actor = self.get_required_actor(&address, *ts.parent_state())?;
S::load(self.blockstore(), &actor)
}

/// Gets actor state from explicit actor address
pub fn get_actor_state_from_address<S: LoadActorStateFromBlockstore>(
&self,
ts: &Tipset,
actor_address: &Address,
) -> anyhow::Result<S> {
let actor = self.get_required_actor(actor_address, *ts.parent_state())?;
S::load(self.blockstore(), &actor)
}

/// Gets required actor from given [`Cid`].
pub fn get_required_actor(&self, addr: &Address, state_cid: Cid) -> anyhow::Result<ActorState> {
let state = self.get_state_tree(&state_cid)?;
Expand Down

0 comments on commit 9d9b0af

Please sign in to comment.