Skip to content

Commit

Permalink
feat(rpc): implement Filecoin.StateMarketParticipants (#4302)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanabi1224 authored May 9, 2024
1 parent ece117d commit e5066ba
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 14 deletions.
37 changes: 37 additions & 0 deletions src/rpc/methods/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use types::*;
use crate::blocks::Tipset;
use crate::cid_collections::CidHashSet;
use crate::libp2p::NetworkMessage;
use crate::shim::actors::market::BalanceTableExt as _;
use crate::shim::message::Message;
use crate::shim::piece::PaddedPieceSize;
use crate::shim::state_tree::StateTree;
Expand Down Expand Up @@ -88,6 +89,7 @@ macro_rules! for_each_method {
$callback!(crate::rpc::state::StateListMiners);
$callback!(crate::rpc::state::StateNetworkVersion);
$callback!(crate::rpc::state::StateMarketBalance);
$callback!(crate::rpc::state::StateMarketParticipants);
$callback!(crate::rpc::state::StateMarketDeals);
$callback!(crate::rpc::state::StateDealProviderCollateralBounds);
$callback!(crate::rpc::state::StateMarketStorageDeal);
Expand Down Expand Up @@ -1423,6 +1425,41 @@ impl RpcMethod<2> for StateMarketStorageDeal {
}
}

pub enum StateMarketParticipants {}

impl RpcMethod<1> for StateMarketParticipants {
const NAME: &'static str = "Filecoin.StateMarketParticipants";
const PARAM_NAMES: [&'static str; 1] = ["tipset_key"];
const API_VERSION: ApiVersion = ApiVersion::V0;
const PERMISSION: Permission = Permission::Read;

type Params = (ApiTipsetKey,);
type Ok = HashMap<String, MarketBalance>;

async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(ApiTipsetKey(tsk),): Self::Params,
) -> Result<Self::Ok, ServerError> {
let ts = ctx.chain_store.load_required_tipset_or_heaviest(&tsk)?;
let market_state = ctx.state_manager.market_state(&ts)?;
let escrow_table = market_state.escrow_table(ctx.store())?;
let locked_table = market_state.locked_table(ctx.store())?;
let mut result = HashMap::new();
escrow_table.for_each(|address, escrow| {
let locked = locked_table.get(&address.into())?;
result.insert(
address.to_string(),
MarketBalance {
escrow: escrow.clone(),
locked: locked.into(),
},
);
Ok(())
})?;
Ok(result)
}
}

pub enum StateDealProviderCollateralBounds {}

impl RpcMethod<3> for StateDealProviderCollateralBounds {
Expand Down
13 changes: 13 additions & 0 deletions src/shim/actors/market.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

mod balance_table;

use crate::shim::address::Address;
use crate::shim::econ::TokenAmount;

pub trait BalanceTableExt {
fn for_each<F>(&self, f: F) -> anyhow::Result<()>
where
F: FnMut(&Address, &TokenAmount) -> anyhow::Result<()>;
}
37 changes: 37 additions & 0 deletions src/shim/actors/market/balance_table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;
use fil_actor_interface::market::BalanceTable;
use fvm_ipld_blockstore::Blockstore;

impl<'bs, BS: Blockstore> BalanceTableExt for BalanceTable<'bs, BS> {
fn for_each<F>(&self, mut f: F) -> anyhow::Result<()>
where
F: FnMut(&Address, &TokenAmount) -> anyhow::Result<()>,
{
match self {
Self::V8(t) => {
t.0.for_each(|key, escrow| f(&Address::from_bytes(&key.0)?, &escrow.into()))?
}
Self::V9(t) => {
t.0.for_each(|key, escrow| f(&Address::from_bytes(&key.0)?, &escrow.into()))?
}
Self::V10(t) => {
t.0.for_each(|key, escrow| f(&Address::from_bytes(&key.0)?, &escrow.into()))?
}
Self::V11(t) => {
t.0.for_each(|key, escrow| f(&Address::from_bytes(&key.0)?, &escrow.into()))?
}
Self::V12(t) => t.0.for_each(|address, escrow| {
f(&address.into(), &escrow.into())
.map_err(|e| fil_actors_shared::v12::ActorError::unspecified(e.to_string()))
})?,
Self::V13(t) => t.0.for_each(|address, escrow| {
f(&address.into(), &escrow.into())
.map_err(|e| fil_actors_shared::v13::ActorError::unspecified(e.to_string()))
})?,
};
Ok(())
}
}
4 changes: 4 additions & 0 deletions src/shim/actors/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

pub mod market;
1 change: 1 addition & 0 deletions src/shim/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

pub mod actors;
pub mod address;
pub mod bigint;
pub mod clock;
Expand Down
25 changes: 11 additions & 14 deletions src/state_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ impl TipsetStateCache {
pub struct MarketBalance {
#[schemars(with = "LotusJson<TokenAmount>")]
#[serde(with = "crate::lotus_json")]
escrow: TokenAmount,
pub escrow: TokenAmount,
#[schemars(with = "LotusJson<TokenAmount>")]
#[serde(with = "crate::lotus_json")]
locked: TokenAmount,
pub locked: TokenAmount,
}
lotus_json_with_self!(MarketBalance);

Expand Down Expand Up @@ -1019,19 +1019,16 @@ where
.ok_or_else(|| Error::Other(format!("Failed to lookup the id address {addr}")))
}

/// Retrieves market balance in escrow and locked tables.
pub fn market_balance(
&self,
addr: &Address,
ts: &Tipset,
) -> anyhow::Result<MarketBalance, Error> {
let actor = self
.get_actor(&Address::MARKET_ACTOR, *ts.parent_state())?
.ok_or_else(|| {
Error::State("Market actor address could not be resolved".to_string())
})?;

/// Retrieves market state
pub fn market_state(&self, ts: &Tipset) -> Result<market::State, Error> {
let actor = self.get_required_actor(&Address::MARKET_ACTOR, *ts.parent_state())?;
let market_state = market::State::load(self.blockstore(), actor.code, actor.state)?;
Ok(market_state)
}

/// Retrieves market balance in escrow and locked tables.
pub fn market_balance(&self, addr: &Address, ts: &Tipset) -> Result<MarketBalance, Error> {
let market_state = self.market_state(ts)?;

let new_addr = self
.lookup_id(addr, ts)?
Expand Down
1 change: 1 addition & 0 deletions src/tool/subcommands/api_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ fn state_tests_with_tipset<DB: Blockstore>(
RpcTest::identity(StateVMCirculatingSupplyInternal::request((tipset
.key()
.into(),))?),
RpcTest::identity(StateMarketParticipants::request((tipset.key().into(),))?),
];

// Get deals
Expand Down

0 comments on commit e5066ba

Please sign in to comment.