Skip to content

Commit

Permalink
[Feature] Filecoin.StateGetAllocation RPC endpoint. (#4382)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruseinov authored Jun 4, 2024
1 parent dfc97e7 commit 2d7ac55
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
`Filecoin.StateGetClaim` RPC method.
- [#4356](https://github.com/ChainSafe/forest/pull/4356) Add support for the
`Filecoin.NetProtectAdd` RPC method.
- [#4382](https://github.com/ChainSafe/forest/pull/4382) Add support for the
`Filecoin.StateGetAllocation` RPC method.

### Changed

Expand Down
88 changes: 88 additions & 0 deletions src/lotus_json/allocation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;
use ::cid::Cid;
use fil_actor_interface::verifreg::Allocation;
use fvm_shared4::clock::ChainEpoch;
use fvm_shared4::piece::PaddedPieceSize;
use fvm_shared4::ActorID;

#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
#[schemars(rename = "Allocation")]
pub struct AllocationLotusJson {
// The verified client which allocated the DataCap.
pub client: ActorID,
// The provider (miner actor) which may claim the allocation.
pub provider: ActorID,
// Identifier of the data to be committed.
#[schemars(with = "LotusJson<Cid>")]
#[serde(with = "crate::lotus_json")]
pub data: Cid,
// The (padded) size of data.
#[schemars(with = "u64")]
pub size: PaddedPieceSize,
// The minimum duration which the provider must commit to storing the piece to avoid
// early-termination penalties (epochs).
pub term_min: ChainEpoch,
// The maximum period for which a provider can earn quality-adjusted power
// for the piece (epochs).
pub term_max: ChainEpoch,
// The latest epoch by which a provider must commit data before the allocation expires.
pub expiration: ChainEpoch,
}

impl HasLotusJson for Allocation {
type LotusJson = AllocationLotusJson;
#[cfg(test)]
fn snapshots() -> Vec<(serde_json::Value, Self)> {
vec![(
json! {{
"TermMin": 0,
"TermMax": 0,
"Provider": 0,
"Client": 0,
"Expiration": 0,
"Size": 0,
"Data": {"/":"baeaaaaa"},
}},
Allocation {
term_min: 0,
term_max: 0,
provider: 0,
client: 0,
expiration: 0,
size: PaddedPieceSize(0),
data: Cid::default(),
},
)]
}
fn into_lotus_json(self) -> Self::LotusJson {
AllocationLotusJson {
client: self.client,
provider: self.provider,
data: self.data,
size: self.size,
term_min: self.term_min,
term_max: self.term_max,
expiration: self.expiration,
}
}
fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
Allocation {
client: lotus_json.client,
provider: lotus_json.provider,
data: lotus_json.data,
size: lotus_json.size,
term_min: lotus_json.term_min,
term_max: lotus_json.term_max,
expiration: lotus_json.expiration,
}
}
}

#[test]
fn snapshots() {
assert_all_snapshots::<Allocation>();
}
3 changes: 2 additions & 1 deletion src/lotus_json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@

use derive_more::From;
use fil_actor_interface::miner::DeadlineInfo;
use fvm_shared2::piece::PaddedPieceSize;
use fvm_shared4::piece::PaddedPieceSize;
use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(test)]
Expand Down Expand Up @@ -216,6 +216,7 @@ decl_and_test!(

// If a module cannot be tested normally above, you MAY declare it separately here
// but you MUST document any tech debt - the reason WHY it cannot be tested above.
mod allocation;
mod beneficiary_term; // fil_actor_miner_state::v12::BeneficiaryTerm: !quickcheck::Arbitrary
mod bit_field; // fil_actors_shared::fvm_ipld_bitfield::BitField: !quickcheck::Arbitrary
mod cid; // can't make snapshots of generic type
Expand Down
24 changes: 23 additions & 1 deletion src/rpc/methods/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use anyhow::Context as _;
use anyhow::Result;
use cid::Cid;
use fil_actor_interface::market::DealState;
use fil_actor_interface::verifreg::Claim;
use fil_actor_interface::verifreg::{Allocation, Claim};
use fil_actor_interface::{
market, miner,
miner::{MinerInfo, MinerPower},
Expand Down Expand Up @@ -1879,6 +1879,28 @@ impl RpcMethod<3> for StateGetClaim {
}
}

pub enum StateGetAllocation {}

impl RpcMethod<3> for StateGetAllocation {
const NAME: &'static str = "Filecoin.StateGetAllocation";
const PARAM_NAMES: [&'static str; 3] = ["address", "allocation_id", "tipset_key"];
const API_VERSION: ApiVersion = ApiVersion::V1;
const PERMISSION: Permission = Permission::Read;

type Params = (Address, ClaimID, ApiTipsetKey);
type Ok = Option<Allocation>;

async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(address, allocation_id, ApiTipsetKey(tsk)): Self::Params,
) -> Result<Self::Ok, ServerError> {
let ts = ctx.chain_store.load_required_tipset_or_heaviest(&tsk)?;
Ok(ctx
.state_manager
.get_allocation(&address, &ts, allocation_id)?)
}
}

pub enum StateGetNetworkParams {}

impl RpcMethod<0> for StateGetNetworkParams {
Expand Down
1 change: 1 addition & 0 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ macro_rules! for_each_method {
$callback!(crate::rpc::state::StateMinerPreCommitDepositForPower);
$callback!(crate::rpc::state::StateVerifierStatus);
$callback!(crate::rpc::state::StateGetClaim);
$callback!(crate::rpc::state::StateGetAllocation);
$callback!(crate::rpc::state::StateSectorExpiration);

// sync vertical
Expand Down
15 changes: 13 additions & 2 deletions src/state_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ use cid::Cid;
pub use circulating_supply::GenesisInfo;
use fil_actor_interface::init::{self, State};
use fil_actor_interface::miner::{MinerInfo, MinerPower, Partition};
use fil_actor_interface::verifreg::Claim;
use fil_actor_interface::verifreg::{Allocation, Claim};
use fil_actor_interface::*;
use fil_actor_verifreg_state::v12::DataCap;
use fil_actor_verifreg_state::v13::ClaimID;
use fil_actor_verifreg_state::v13::{AllocationID, ClaimID};
use fil_actors_shared::fvm_ipld_amt::Amtv0 as Amt;
use fil_actors_shared::fvm_ipld_bitfield::BitField;
use fil_actors_shared::v12::runtime::DomainSeparationTag;
Expand Down Expand Up @@ -1332,6 +1332,17 @@ where
state.get_claim(self.blockstore(), id_address.into(), claim_id)
}

pub fn get_allocation(
self: &Arc<Self>,
addr: &Address,
ts: &Arc<Tipset>,
allocation_id: AllocationID,
) -> anyhow::Result<Option<Allocation>> {
let id_address = self.lookup_required_id(addr, ts)?;
let state = self.get_verified_registry_actor_state(ts)?;
state.get_allocation(self.blockstore(), id_address.id()?, allocation_id)
}

pub fn verified_client_status(
self: &Arc<Self>,
addr: &Address,
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 @@ -846,6 +846,13 @@ fn state_tests_with_tipset<DB: Blockstore>(
0,
tipset.key().into(),
))?),
// NOTE: Once StateGetAllocations is implemented we need to retrieve a valid
// allocation_id and use that for testing.
RpcTest::identity(StateGetAllocation::request((
block.miner_address,
0,
tipset.key().into(),
))?),
]);

for sector in StateSectorGetInfo::get_sectors(store, &block.miner_address, tipset)?
Expand Down

0 comments on commit 2d7ac55

Please sign in to comment.