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
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
94 changes: 94 additions & 0 deletions src/rpc/methods/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2800,3 +2800,97 @@ 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());
}

let sec_size: u64 = sector_size as u64;
virajbhartiya marked this conversation as resolved.
Show resolved Hide resolved

if verified_size > sec_size {
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 (epochs_since_start, duration) = get_pledge_ramp_params(&ctx, ts.epoch(), &ts).await?;
virajbhartiya marked this conversation as resolved.
Show resolved Hide resolved

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 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)
}
}

async fn get_pledge_ramp_params(
virajbhartiya marked this conversation as resolved.
Show resolved Hide resolved
ctx: &Ctx<impl Blockstore + Send + Sync + 'static>,
height: ChainEpoch,
ts: &Tipset,
) -> Result<(i64, u64), anyhow::Error> {
virajbhartiya marked this conversation as resolved.
Show resolved Hide resolved
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