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

feat(rpc): add StateMinerInitialPledgeForSector method #5096

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
- [#5020](https://github.com/ChainSafe/forest/issues/5020) Add support for the
`Filecoin.EthGetTransactionByBlockNumberAndIndex` RPC method.

- [#4907](https://github.com/ChainSafe/forest/issues/4907) Add support for the
`Filecoin.StateMinerInitialPledgeForSector` RPC method.

### Changed

### Removed
Expand Down
92 changes: 92 additions & 0 deletions src/rpc/methods/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2800,3 +2800,95 @@ impl TryFrom<&ChainConfig> for ForkUpgradeParams {
})
}
}

pub enum StateMinerInitialPledgeForSector {}
impl RpcMethod<4> for StateMinerInitialPledgeForSector {
const NAME: &'static str = "Filecoin.StateMinerInitialPledgeForSector";
const PARAM_NAMES: [&'static str; 4] = [
"sector_duration",
"sector_size",
"verified_size",
"tipset_key",
];
const API_PATHS: ApiPaths = ApiPaths::V1;
const PERMISSION: Permission = Permission::Read;

type Params = (ChainEpoch, SectorSize, u64, ApiTipsetKey);
type Ok = TokenAmount;

async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(sector_duration, sector_size, verified_size, ApiTipsetKey(tsk)): Self::Params,
) -> Result<Self::Ok, ServerError> {
if sector_duration <= 0 {
return Err(anyhow::anyhow!("sector duration must be greater than 0").into());
}

if verified_size > sector_size as u64 {
return Err(
anyhow::anyhow!("verified deal size cannot be larger than sector size").into(),
);
}

let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?;

let power_state: power::State = ctx.state_manager.get_actor_state(&ts)?;
let power_smoothed = power_state.total_power_smoothed();
let pledge_collateral = power_state.total_locked();

let reward_state: reward::State = ctx.state_manager.get_actor_state(&ts)?;

let genesis_info = GenesisInfo::from_chain_config(ctx.chain_config().clone());
let circ_supply = genesis_info.get_vm_circulating_supply_detailed(
ts.epoch(),
&ctx.store_owned(),
ts.parent_state(),
)?;

let deal_weight = BigInt::from(0);
let verified_deal_weight = BigInt::from(verified_size) * sector_duration;
let sector_weight = qa_power_for_weight(
sector_size.into(),
sector_duration,
&deal_weight,
&verified_deal_weight,
);

let (epochs_since_start, duration) = get_pledge_ramp_params(&ctx, ts.epoch(), &ts)?;

let initial_pledge: TokenAmount = reward_state
.initial_pledge_for_power(
&sector_weight,
pledge_collateral,
power_smoothed,
&circ_supply.fil_circulating.into(),
epochs_since_start,
duration,
)?
.into();

let (value, _) = (initial_pledge * INITIAL_PLEDGE_NUM).div_rem(INITIAL_PLEDGE_DEN);
Ok(value)
}
}

fn get_pledge_ramp_params(
ctx: &Ctx<impl Blockstore + Send + Sync + 'static>,
height: ChainEpoch,
ts: &Tipset,
) -> Result<(ChainEpoch, u64), anyhow::Error> {
let state_tree = ctx.state_manager.get_state_tree(ts.parent_state())?;

let power_state: power::State = state_tree
.get_actor_state()
.map_err(|e| anyhow::anyhow!("loading power actor state: {e}"))?;

if power_state.ramp_start_epoch() > 0 {
Ok((
height - power_state.ramp_start_epoch(),
power_state.ramp_duration_epochs(),
))
} else {
Ok((0, 0))
}
}
1 change: 1 addition & 0 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ macro_rules! for_each_method {
$callback!(crate::rpc::state::StateVMCirculatingSupplyInternal);
$callback!(crate::rpc::state::StateWaitMsg);
$callback!(crate::rpc::state::StateWaitMsgV0);
$callback!(crate::rpc::state::StateMinerInitialPledgeForSector);

// sync vertical
$callback!(crate::rpc::sync::SyncCheckBad);
Expand Down
7 changes: 7 additions & 0 deletions src/tool/subcommands/api_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::rpc::types::{ApiTipsetKey, MessageFilter, MessageLookup};
use crate::rpc::{prelude::*, Permission};
use crate::shim::actors::market;
use crate::shim::actors::MarketActorStateLoad as _;
use crate::shim::sector::SectorSize;
use crate::shim::{
address::{Address, Protocol},
crypto::Signature,
Expand Down Expand Up @@ -810,6 +811,12 @@ fn state_tests_with_tipset<DB: Blockstore>(
let mut tests = vec![
RpcTest::identity(StateNetworkName::request(())?),
RpcTest::identity(StateGetNetworkParams::request(())?),
RpcTest::identity(StateMinerInitialPledgeForSector::request((
1,
SectorSize::_2KiB,
1024,
tipset.key().into(),
))?),
RpcTest::identity(StateGetActor::request((
Address::SYSTEM_ACTOR,
tipset.key().into(),
Expand Down
Loading