Skip to content

Commit

Permalink
refactor: migrate MinerGetBaseInfo, StateCall to trait RpcMethod (#4244)
Browse files Browse the repository at this point in the history
  • Loading branch information
aatifsyed authored Apr 19, 2024
1 parent a1afda9 commit 50f36f6
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 107 deletions.
4 changes: 2 additions & 2 deletions src/rpc/auth_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ static ACCESS_MAP: Lazy<HashMap<&str, Access>> = Lazy::new(|| {
access.insert(wallet::WalletDelete::NAME, Access::Write);

// State API
access.insert(state::STATE_CALL, Access::Read);
access.insert(state::MinerGetBaseInfo::NAME, Access::Read);
access.insert(state::StateCall::NAME, Access::Read);
access.insert(state::STATE_REPLAY, Access::Read);
access.insert(state::STATE_GET_ACTOR, Access::Read);
access.insert(state::STATE_MARKET_BALANCE, Access::Read);
access.insert(state::STATE_MARKET_DEALS, Access::Read);
access.insert(state::STATE_MINER_INFO, Access::Read);
access.insert(state::MINER_GET_BASE_INFO, Access::Read);
access.insert(state::STATE_MINER_ACTIVE_SECTORS, Access::Read);
access.insert(state::STATE_MINER_FAULTS, Access::Read);
access.insert(state::STATE_MINER_RECOVERIES, Access::Read);
Expand Down
79 changes: 48 additions & 31 deletions src/rpc/methods/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::blocks::Tipset;
use crate::cid_collections::CidHashSet;
use crate::libp2p::NetworkMessage;
use crate::lotus_json::LotusJson;
use crate::shim::message::Message;
use crate::shim::state_tree::StateTree;
use crate::shim::{
address::Address, clock::ChainEpoch, deal::DealID, econ::TokenAmount, executor::Receipt,
Expand Down Expand Up @@ -50,25 +51,25 @@ use tokio::task::JoinSet;

macro_rules! for_each_method {
($callback:ident) => {
$callback!(crate::rpc::state::MinerGetBaseInfo);
$callback!(crate::rpc::state::StateCall);
$callback!(crate::rpc::state::StateGetBeaconEntry);
$callback!(crate::rpc::state::StateSectorPreCommitInfo);
$callback!(crate::rpc::state::StateSectorGetInfo);
$callback!(crate::rpc::state::StateListMessages);
$callback!(crate::rpc::state::StateSectorGetInfo);
$callback!(crate::rpc::state::StateSectorPreCommitInfo);
};
}
pub(crate) use for_each_method;

type RandomnessParams = (i64, ChainEpoch, Vec<u8>, ApiTipsetKey);

pub const STATE_CALL: &str = "Filecoin.StateCall";
pub const STATE_REPLAY: &str = "Filecoin.StateReplay";
pub const STATE_NETWORK_NAME: &str = "Filecoin.StateNetworkName";
pub const STATE_NETWORK_VERSION: &str = "Filecoin.StateNetworkVersion";
pub const STATE_GET_ACTOR: &str = "Filecoin.StateGetActor";
pub const STATE_MARKET_BALANCE: &str = "Filecoin.StateMarketBalance";
pub const STATE_MARKET_DEALS: &str = "Filecoin.StateMarketDeals";
pub const STATE_MINER_INFO: &str = "Filecoin.StateMinerInfo";
pub const MINER_GET_BASE_INFO: &str = "Filecoin.MinerGetBaseInfo";
pub const STATE_MINER_FAULTS: &str = "Filecoin.StateMinerFaults";
pub const STATE_MINER_RECOVERIES: &str = "Filecoin.StateMinerRecoveries";
pub const STATE_MINER_POWER: &str = "Filecoin.StateMinerPower";
Expand Down Expand Up @@ -100,37 +101,53 @@ pub const MSIG_GET_PENDING: &str = "Filecoin.MsigGetPending";
pub const STATE_MINER_SECTORS: &str = "Filecoin.StateMinerSectors";
pub const STATE_MINER_PARTITIONS: &str = "Filecoin.StateMinerPartitions";

pub async fn miner_get_base_info<DB: Blockstore + Send + Sync + 'static>(
params: Params<'_>,
data: Ctx<DB>,
) -> anyhow::Result<LotusJson<Option<MiningBaseInfo>>, ServerError> {
let LotusJson((address, epoch, ApiTipsetKey(tsk))) = params.parse()?;
pub enum MinerGetBaseInfo {}
impl RpcMethod<3> for MinerGetBaseInfo {
const NAME: &'static str = "Filecoin.MinerGetBaseInfo";
const PARAM_NAMES: [&'static str; 3] = ["address", "epoch", "tsk"];
const API_VERSION: ApiVersion = ApiVersion::V0;

let ts = data
.state_manager
.chain_store()
.load_required_tipset_or_heaviest(&tsk)?;
type Params = (LotusJson<Address>, i64, LotusJson<ApiTipsetKey>);
type Ok = Option<MiningBaseInfo>;

data.state_manager
.miner_get_base_info(data.state_manager.beacon_schedule(), ts, address, epoch)
.await
.map(|info| Ok(LotusJson(info)))?
async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(LotusJson(address), epoch, LotusJson(ApiTipsetKey(tsk))): Self::Params,
) -> Result<Self::Ok, ServerError> {
let ts = ctx
.state_manager
.chain_store()
.load_required_tipset_or_heaviest(&tsk)?;

Ok(ctx
.state_manager
.miner_get_base_info(ctx.state_manager.beacon_schedule(), ts, address, epoch)
.await?)
}
}
/// runs the given message and returns its result without any persisted changes.
pub async fn state_call<DB: Blockstore + Send + Sync + 'static>(
params: Params<'_>,
data: Ctx<DB>,
) -> Result<ApiInvocResult, ServerError> {
let LotusJson((message, ApiTipsetKey(key))) = params.parse()?;

let state_manager = &data.state_manager;
let tipset = data
.state_manager
.chain_store()
.load_required_tipset_or_heaviest(&key)?;
// Handle expensive fork error?
// TODO(elmattic): https://github.com/ChainSafe/forest/issues/3733
Ok(state_manager.call(&message, Some(tipset))?)
pub enum StateCall {}
impl RpcMethod<2> for StateCall {
const NAME: &'static str = "Filecoin.StateCall";
const PARAM_NAMES: [&'static str; 2] = ["message", "tsk"];
const API_VERSION: ApiVersion = ApiVersion::V0;

type Params = (LotusJson<Message>, LotusJson<ApiTipsetKey>);
type Ok = ApiInvocResult;

async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(LotusJson(message), LotusJson(ApiTipsetKey(tsk))): Self::Params,
) -> Result<Self::Ok, ServerError> {
let state_manager = &ctx.state_manager;
let tipset = ctx
.state_manager
.chain_store()
.load_required_tipset_or_heaviest(&tsk)?;
// Handle expensive fork error?
// TODO(elmattic): https://github.com/ChainSafe/forest/issues/3733
Ok(state_manager.call(&message, Some(tipset))?)
}
}

/// returns the result of executing the indicated message, assuming it was
Expand Down
80 changes: 61 additions & 19 deletions src/rpc/methods/state/types.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::lotus_json::lotus_json_with_self;

use crate::shim::{address::Address, econ::TokenAmount, executor::Receipt, message::Message};
use crate::beacon::BeaconEntry;
use crate::lotus_json::{lotus_json_with_self, LotusJson};
use crate::shim::{
address::Address,
econ::TokenAmount,
error::ExitCode,
executor::Receipt,
message::Message,
sector::{SectorInfo, StoragePower},
state_tree::{ActorID, ActorState},
};
use cid::Cid;

use fvm_ipld_encoding::RawBytes;

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)]

#[derive(Serialize, Deserialize, Clone, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct ApiInvocResult {
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Message>")]
pub msg: Message,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Cid>")]
pub msg_cid: Cid,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Option<Receipt>>")]
pub msg_rct: Option<Receipt>,
pub error: String,
pub duration: u64,
#[serde(with = "crate::lotus_json")]
pub gas_cost: MessageGasCost,
#[serde(with = "crate::lotus_json")]
pub execution_trace: Option<ExecutionTrace>,
}

Expand All @@ -44,57 +49,64 @@ impl PartialEq for ApiInvocResult {
}
}

#[derive(Default, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Default, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct MessageGasCost {
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Option<Cid>>")]
pub message: Option<Cid>,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub gas_used: TokenAmount,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub base_fee_burn: TokenAmount,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub over_estimation_burn: TokenAmount,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub miner_penalty: TokenAmount,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub miner_tip: TokenAmount,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub refund: TokenAmount,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub total_cost: TokenAmount,
}

lotus_json_with_self!(MessageGasCost);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct ExecutionTrace {
#[serde(with = "crate::lotus_json")]
pub msg: MessageTrace,
#[serde(with = "crate::lotus_json")]
pub msg_rct: ReturnTrace,
#[serde(with = "crate::lotus_json")]
pub invoked_actor: Option<ActorTrace>,
#[serde(with = "crate::lotus_json")]
pub gas_charges: Vec<GasTrace>,
#[serde(with = "crate::lotus_json")]
pub subcalls: Vec<ExecutionTrace>,
}

lotus_json_with_self!(ExecutionTrace);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct MessageTrace {
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Address>")]
pub from: Address,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Address>")]
pub to: Address,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<TokenAmount>")]
pub value: TokenAmount,
pub method: u64,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<RawBytes>")]
pub params: RawBytes,
pub params_codec: u64,
pub gas_limit: Option<u64>,
Expand All @@ -103,28 +115,30 @@ pub struct MessageTrace {

lotus_json_with_self!(MessageTrace);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct ActorTrace {
pub id: ActorID,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<ActorState>")]
pub state: ActorState,
}

lotus_json_with_self!(ActorTrace);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct ReturnTrace {
pub exit_code: ExitCode,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<RawBytes>")]
pub r#return: RawBytes,
pub return_codec: u64,
}

lotus_json_with_self!(ReturnTrace);

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct GasTrace {
pub name: String,
Expand All @@ -149,3 +163,31 @@ impl PartialEq for GasTrace {
&& self.storage_gas == other.storage_gas
}
}

#[derive(Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct MiningBaseInfo {
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<StoragePower>")]
pub miner_power: StoragePower,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<StoragePower>")]
pub network_power: StoragePower,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Vec<SectorInfo>>")]
pub sectors: Vec<SectorInfo>,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Address>")]
pub worker_key: Address,
#[schemars(with = "u64")]
pub sector_size: fvm_shared2::sector::SectorSize,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<BeaconEntry>")]
pub prev_beacon_entry: BeaconEntry,
#[serde(with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Vec<BeaconEntry>>")]
pub beacon_entries: Vec<BeaconEntry>,
pub eligible_for_mining: bool,
}

lotus_json_with_self!(MiningBaseInfo);
2 changes: 0 additions & 2 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ where
use gas::*;

// State API
module.register_async_method(STATE_CALL, state_call::<DB>)?;
module.register_async_method(STATE_REPLAY, state_replay::<DB>)?;
module.register_async_method(STATE_NETWORK_NAME, |_, state| {
state_network_name::<DB>(state)
Expand All @@ -280,7 +279,6 @@ where
module.register_async_method(STATE_MARKET_BALANCE, state_market_balance::<DB>)?;
module.register_async_method(STATE_MARKET_DEALS, state_market_deals::<DB>)?;
module.register_async_method(STATE_MINER_INFO, state_miner_info::<DB>)?;
module.register_async_method(MINER_GET_BASE_INFO, miner_get_base_info::<DB>)?;
module.register_async_method(STATE_MINER_ACTIVE_SECTORS, state_miner_active_sectors::<DB>)?;
module.register_async_method(STATE_MINER_SECTORS, state_miner_sectors::<DB>)?;
module.register_async_method(STATE_MINER_PARTITIONS, state_miner_partitions::<DB>)?;
Expand Down
24 changes: 0 additions & 24 deletions src/rpc/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ mod tsk_impl;
#[cfg(test)]
mod tests;

use crate::beacon::BeaconEntry;
use crate::blocks::TipsetKey;
use crate::libp2p::Multihash;
use crate::lotus_json::{lotus_json_with_self, HasLotusJson, LotusJson};
use crate::shim::sector::SectorInfo;
use crate::shim::{
address::Address,
clock::ChainEpoch,
Expand Down Expand Up @@ -206,28 +204,6 @@ pub struct MinerPowerLotusJson {
has_min_power: bool,
}

// Note: kept the name in line with Lotus implementation for cross-referencing simplicity.
#[derive(Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct MiningBaseInfo {
#[serde(with = "crate::lotus_json")]
pub miner_power: crate::shim::sector::StoragePower,
#[serde(with = "crate::lotus_json")]
pub network_power: fvm_shared2::sector::StoragePower,
#[serde(with = "crate::lotus_json")]
pub sectors: Vec<SectorInfo>,
#[serde(with = "crate::lotus_json")]
pub worker_key: Address,
pub sector_size: fvm_shared2::sector::SectorSize,
#[serde(with = "crate::lotus_json")]
pub prev_beacon_entry: BeaconEntry,
#[serde(with = "crate::lotus_json")]
pub beacon_entries: Vec<BeaconEntry>,
pub eligible_for_mining: bool,
}

lotus_json_with_self!(MiningBaseInfo);

#[derive(Serialize, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct ApiActorState {
Expand Down
Loading

0 comments on commit 50f36f6

Please sign in to comment.