diff --git a/CHANGELOG.md b/CHANGELOG.md index 256dd15085f7..902af529f817 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,12 @@ ### Added +- [#4545](https://github.com/ChainSafe/forest/pull/4545) Add support for the + `Filecoin.StateGetAllClaims` RPC method. + +- [#4545](https://github.com/ChainSafe/forest/pull/4545) Add support for the + `Filecoin.StateGetAllAllocations` RPC method. + - [#4503](https://github.com/ChainSafe/forest/pull/4503) Add support for the `Filecoin.StateMinerAllocated` RPC method. diff --git a/Cargo.lock b/Cargo.lock index 0ec5e718fa04..0f5245633da2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2621,9 +2621,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "fil_actor_account_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c001e6c3952f311bb118d2ded5a8895642a033ad5d4558421a86a1e19f64c5" +checksum = "8d32c2b5601caa2dd2bea95530d0fe2aabbfaf95ab9162e230f4bddd6f14b8fb" dependencies = [ "frc42_macros", "fvm_ipld_encoding", @@ -2637,9 +2637,9 @@ dependencies = [ [[package]] name = "fil_actor_cron_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff94b767f31f091a2eb17985c5c9eb02b33dcfceb78d4b922caa09b06b448e30" +checksum = "ea2152e9454180195d8df5588205790969e7997ef69a1b627e45fd1990e4d24c" dependencies = [ "fvm_ipld_encoding", "fvm_shared 2.7.0", @@ -2652,9 +2652,9 @@ dependencies = [ [[package]] name = "fil_actor_datacap_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddddc761fc5e463287ef9d25a547f539b79d9be539685aeb35c829bd75debc68" +checksum = "3dd3f41b8b5275cb71404fdf76b82b4e768d37ce3b2c5b58d39b435835956a02" dependencies = [ "fil_actors_shared", "frc42_macros", @@ -2672,9 +2672,9 @@ dependencies = [ [[package]] name = "fil_actor_evm_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f853a82a3709c31f13d4f6db65ef5da629ed630d7cba23e940845f687fa49b" +checksum = "5f9d7b4c977cc43ff471984039ac30f04fa9a13008c5b0eaea9cd6d26a2e7a0c" dependencies = [ "cid", "fil_actors_shared", @@ -2692,9 +2692,9 @@ dependencies = [ [[package]] name = "fil_actor_init_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad95698b8e0304697acd08aa0330e85ce9ecbf7cfac0af25dbb3af135918bfc" +checksum = "57fdb8be617a9b6d0be9ba6c314cc12011fe2055cb041145acced3133be6b0aa" dependencies = [ "anyhow", "cid", @@ -2713,9 +2713,9 @@ dependencies = [ [[package]] name = "fil_actor_interface" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d9fe53aca285762365b3032a5bff4f976c0d8b34b672cf696916131f2442d4" +checksum = "ec2a4007127d0bcd8d2067ff03fbd01b84f6b99bf93538cfc16d0871460bfe80" dependencies = [ "anyhow", "cid", @@ -2751,9 +2751,9 @@ dependencies = [ [[package]] name = "fil_actor_market_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dacd1e836fed9faf71d0dd2371f664a2680254d125eb8d985a99217b4f5f238f" +checksum = "819569b9cb1ab8f297579aa56a4de0c19630122e38e07df9629df71e98aeea47" dependencies = [ "anyhow", "cid", @@ -2778,9 +2778,9 @@ dependencies = [ [[package]] name = "fil_actor_miner_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfafc071444d071d004fc510371ab103795ff0a034c2e7cb09cc67fdfcdf870" +checksum = "39ea731d8bbba13f385260e7c6a5477290b599797f43d6954c3289d2f76502ac" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -2809,9 +2809,9 @@ dependencies = [ [[package]] name = "fil_actor_multisig_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d17f929c15f325234c9deb2f4dc7ce0fd14fdd1d008a8d3d0cc6b48a4fb881a" +checksum = "2049c06ad6c90d76756099a637924fd01ae22bb499f7ec4e7617bc4171b10c3d" dependencies = [ "anyhow", "cid", @@ -2833,9 +2833,9 @@ dependencies = [ [[package]] name = "fil_actor_power_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5375f201d6d04627364f0cb0aff558911f48945f2933789c94f3339ed048ab2c" +checksum = "66118ca91e91e121806d45a455a9f2e1724c97e6376f3d56d7e434e189d2484f" dependencies = [ "anyhow", "cid", @@ -2857,9 +2857,9 @@ dependencies = [ [[package]] name = "fil_actor_reward_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668c981a0bd39198e441526a27141bb1d358397e7104e127cf24fd995f50d866" +checksum = "d34d3fb0770f0e4b58d74cbd178eda246cacb80fe6850ae557f562adaa54974e" dependencies = [ "fil_actor_miner_state", "fil_actors_shared", @@ -2875,9 +2875,9 @@ dependencies = [ [[package]] name = "fil_actor_system_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d51b44d50e848a185d05dab7d28f8e8a0131b9ede3ed50df82825c932891236" +checksum = "8fe011c4f18245af9d3caacfbcdc6717884457bf26caf583e4d5086f3ab2aa22" dependencies = [ "cid", "fil_actors_shared", @@ -2892,9 +2892,9 @@ dependencies = [ [[package]] name = "fil_actor_verifreg_state" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced66872a6b12b9c8106b085a3a5e67c9e1845c52caf777d5cbaaaa12f58b239" +checksum = "89ed5cf4b39aff5957554f58dd5f3fb5878e0f14a14b2b35617c74e16fd95376" dependencies = [ "anyhow", "cid", @@ -2914,9 +2914,9 @@ dependencies = [ [[package]] name = "fil_actors_shared" -version = "15.1.0" +version = "15.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ce31431a0083f6ba25bf3c3572b72e7d032f1cded4973df846503f51bba72" +checksum = "f0a3107d59d8488603ad2ee25a0d1eb112ed94e9339ed2bf6f76190dbf1682fb" dependencies = [ "anyhow", "cid", diff --git a/Cargo.toml b/Cargo.toml index 7ae558eeefab..873edd8202ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,18 +47,18 @@ digest = "0.10" directories = "5" displaydoc = "0.2" ethereum-types = "0.14" -fil_actor_account_state = { version = "15.1" } -fil_actor_cron_state = { version = "15.1" } -fil_actor_datacap_state = { version = "15.1" } -fil_actor_init_state = { version = "15.1" } -fil_actor_interface = { version = "15.1" } -fil_actor_market_state = { version = "15.1" } -fil_actor_miner_state = { version = "15.1" } -fil_actor_power_state = { version = "15.1" } -fil_actor_reward_state = { version = "15.1" } -fil_actor_system_state = { version = "15.1" } -fil_actor_verifreg_state = { version = "15.1" } -fil_actors_shared = { version = "15.1", features = ["json"] } +fil_actor_account_state = { version = "15.2" } +fil_actor_cron_state = { version = "15.2" } +fil_actor_datacap_state = { version = "15.2" } +fil_actor_init_state = { version = "15.2" } +fil_actor_interface = { version = "15.2" } +fil_actor_market_state = { version = "15.2" } +fil_actor_miner_state = { version = "15.2" } +fil_actor_power_state = { version = "15.2" } +fil_actor_reward_state = { version = "15.2" } +fil_actor_system_state = { version = "15.2" } +fil_actor_verifreg_state = { version = "15.2" } +fil_actors_shared = { version = "15.2", features = ["json"] } flume = "0.11" fs_extra = "1" futures = "0.3" diff --git a/src/rpc/methods/state.rs b/src/rpc/methods/state.rs index c2d8373888aa..82dada3e886b 100644 --- a/src/rpc/methods/state.rs +++ b/src/rpc/methods/state.rs @@ -2170,6 +2170,26 @@ impl StateGetClaims { } } +pub enum StateGetAllClaims {} + +impl RpcMethod<1> for StateGetAllClaims { + const NAME: &'static str = "Filecoin.StateGetAllClaims"; + const PARAM_NAMES: [&'static str; 1] = ["tipset_key"]; + const API_PATHS: ApiPaths = ApiPaths::V0; + const PERMISSION: Permission = Permission::Read; + + type Params = (ApiTipsetKey,); + type Ok = HashMap; + + async fn handle( + ctx: Ctx, + (ApiTipsetKey(tsk),): Self::Params, + ) -> Result { + let ts = ctx.chain_store.load_required_tipset_or_heaviest(&tsk)?; + Ok(ctx.state_manager.get_all_claims(&ts)?) + } +} + pub enum StateGetAllocation {} impl RpcMethod<3> for StateGetAllocation { @@ -2340,6 +2360,26 @@ impl StateGetAllocations { } } +pub enum StateGetAllAllocations {} + +impl RpcMethod<1> for crate::rpc::prelude::StateGetAllAllocations { + const NAME: &'static str = "Filecoin.StateGetAllAllocations"; + const PARAM_NAMES: [&'static str; 1] = ["tipset_key"]; + const API_PATHS: ApiPaths = ApiPaths::V0; + const PERMISSION: Permission = Permission::Read; + + type Params = (ApiTipsetKey,); + type Ok = HashMap; + + async fn handle( + ctx: Ctx, + (ApiTipsetKey(tsk),): Self::Params, + ) -> Result { + let ts = ctx.chain_store.load_required_tipset_or_heaviest(&tsk)?; + Ok(ctx.state_manager.get_all_allocations(&ts)?) + } +} + pub enum StateGetAllocationIdForPendingDeal {} impl RpcMethod<2> for StateGetAllocationIdForPendingDeal { diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index c1940e931df7..4f1ab3167ddc 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -175,8 +175,10 @@ macro_rules! for_each_method { $callback!(crate::rpc::state::StateVerifierStatus); $callback!(crate::rpc::state::StateGetClaim); $callback!(crate::rpc::state::StateGetClaims); + $callback!(crate::rpc::state::StateGetAllClaims); $callback!(crate::rpc::state::StateGetAllocation); $callback!(crate::rpc::state::StateGetAllocations); + $callback!(crate::rpc::state::StateGetAllAllocations); $callback!(crate::rpc::state::StateGetAllocationIdForPendingDeal); $callback!(crate::rpc::state::StateGetAllocationForPendingDeal); $callback!(crate::rpc::state::StateSectorExpiration); diff --git a/src/shim/actors/verifreg.rs b/src/shim/actors/verifreg.rs index 1e1b4252d6d8..0a1bd52e0d2e 100644 --- a/src/shim/actors/verifreg.rs +++ b/src/shim/actors/verifreg.rs @@ -16,9 +16,17 @@ pub trait VerifiedRegistryStateExt { address: &Address, ) -> anyhow::Result>; + fn get_all_allocations( + &self, + store: &BS, + ) -> anyhow::Result>; + fn get_claims( &self, store: &BS, provider_id_address: &Address, ) -> anyhow::Result>; + + fn get_all_claims(&self, store: &BS) + -> anyhow::Result>; } diff --git a/src/shim/actors/verifreg/state.rs b/src/shim/actors/verifreg/state.rs index b43d9a71541e..463e476148a9 100644 --- a/src/shim/actors/verifreg/state.rs +++ b/src/shim/actors/verifreg/state.rs @@ -66,6 +66,119 @@ impl VerifiedRegistryStateExt for State { Ok(result) } + fn get_all_allocations( + &self, + store: &BS, + ) -> anyhow::Result> { + let mut result = HashMap::default(); + match self { + State::V8(_) => return Err(anyhow::anyhow!("unsupported in actors v8")), + State::V9(state) => { + let mut map = state.load_allocs(store)?; + let mut actors = vec![]; + map.for_each_outer(|k, _| { + let actor_id = fil_actors_shared::v9::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + map.for_each(actor_id, |k, v| { + let allocation_id = fil_actors_shared::v9::parse_uint_key(k)?; + result.insert(allocation_id, v.into()); + Ok(()) + })?; + } + } + State::V10(state) => { + let mut map = state.load_allocs(store)?; + let mut actors = vec![]; + map.for_each_outer(|k, _| { + let actor_id = fil_actors_shared::v10::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + map.for_each(actor_id, |k, v| { + let allocation_id = fil_actors_shared::v10::parse_uint_key(k)?; + result.insert(allocation_id, v.into()); + Ok(()) + })?; + } + } + State::V11(state) => { + let mut map = state.load_allocs(store)?; + let mut actors = vec![]; + map.for_each_outer(|k, _| { + let actor_id = fil_actors_shared::v11::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + map.for_each(actor_id, |k, v| { + let allocation_id = fil_actors_shared::v11::parse_uint_key(k)?; + result.insert(allocation_id, v.into()); + Ok(()) + })?; + } + } + State::V12(state) => { + let mut map = state.load_allocs(store)?; + let mut actors = vec![]; + map.for_each(|k, _| { + let actor_id = fil_actors_shared::v12::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + map.for_each_in(actor_id, |k, v| { + let allocation_id = fil_actors_shared::v12::parse_uint_key(k)?; + result.insert(allocation_id, v.into()); + Ok(()) + })?; + } + } + State::V13(state) => { + let mut map = state.load_allocs(store)?; + let mut actors = vec![]; + map.for_each(|k, _| { + let actor_id = fil_actors_shared::v13::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + map.for_each_in(actor_id, |k, v| { + let allocation_id = fil_actors_shared::v13::parse_uint_key(k)?; + result.insert(allocation_id, v.into()); + Ok(()) + })?; + } + } + State::V14(state) => { + let mut map = state.load_allocs(store)?; + let mut actors = vec![]; + map.for_each(|k, _| { + let actor_id = fil_actors_shared::v14::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + map.for_each_in(actor_id, |k, v| { + let allocation_id = fil_actors_shared::v14::parse_uint_key(k)?; + result.insert(allocation_id, v.into()); + Ok(()) + })?; + } + } + }; + Ok(result) + } + fn get_claims( &self, store: &BS, @@ -128,4 +241,117 @@ impl VerifiedRegistryStateExt for State { }; Ok(result) } + + fn get_all_claims( + &self, + store: &BS, + ) -> anyhow::Result> { + let mut result = HashMap::default(); + match self { + Self::V8(_) => return Err(anyhow::anyhow!("unsupported in actors v8")), + Self::V9(s) => { + let mut claims = s.load_claims(store)?; + let mut actors = vec![]; + claims.for_each_outer(|k, _| { + let actor_id = fil_actors_shared::v9::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + claims.for_each(actor_id, |k, v| { + let claim_id = fil_actors_shared::v9::parse_uint_key(k)?; + result.insert(claim_id, v.into()); + Ok(()) + })?; + } + } + Self::V10(s) => { + let mut claims = s.load_claims(store)?; + let mut actors = vec![]; + claims.for_each_outer(|k, _| { + let actor_id = fil_actors_shared::v10::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + claims.for_each(actor_id, |k, v| { + let claim_id = fil_actors_shared::v10::parse_uint_key(k)?; + result.insert(claim_id, v.into()); + Ok(()) + })?; + } + } + Self::V11(s) => { + let mut claims = s.load_claims(store)?; + let mut actors = vec![]; + claims.for_each_outer(|k, _| { + let actor_id = fil_actors_shared::v11::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + claims.for_each(actor_id, |k, v| { + let claim_id = fil_actors_shared::v11::parse_uint_key(k)?; + result.insert(claim_id, v.into()); + Ok(()) + })?; + } + } + Self::V12(s) => { + let mut claims = s.load_claims(store)?; + let mut actors = vec![]; + claims.for_each(|k, _| { + let actor_id = fil_actors_shared::v12::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + claims.for_each_in(actor_id, |k, v| { + let claim_id = fil_actors_shared::v12::parse_uint_key(k)?; + result.insert(claim_id, v.into()); + Ok(()) + })?; + } + } + Self::V13(s) => { + let mut claims = s.load_claims(store)?; + let mut actors = vec![]; + claims.for_each(|k, _| { + let actor_id = fil_actors_shared::v13::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + claims.for_each_in(actor_id, |k, v| { + let claim_id = fil_actors_shared::v13::parse_uint_key(k)?; + result.insert(claim_id, v.into()); + Ok(()) + })?; + } + } + Self::V14(s) => { + let mut claims = s.load_claims(store)?; + let mut actors = vec![]; + claims.for_each(|k, _| { + let actor_id = fil_actors_shared::v14::parse_uint_key(k)?; + actors.push(actor_id); + Ok(()) + })?; + + for actor_id in actors { + claims.for_each_in(actor_id, |k, v| { + let claim_id = fil_actors_shared::v14::parse_uint_key(k)?; + result.insert(claim_id, v.into()); + Ok(()) + })?; + } + } + }; + Ok(result) + } } diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 949d01bba4b1..89b1d1404b4d 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -28,6 +28,7 @@ use crate::networks::ChainConfig; use crate::rpc::state::{ApiInvocResult, InvocResult, MessageGasCost}; use crate::rpc::types::{MiningBaseInfo, SectorOnChainInfo}; use crate::shim::actors::miner::MinerStateExt as _; +use crate::shim::actors::verifreg::VerifiedRegistryStateExt; use crate::shim::{ address::{Address, Payload, Protocol}, clock::ChainEpoch, @@ -754,8 +755,8 @@ where && s.equal_call(message) }) .map(|(index, m)| { - // A replacing message is a message with a different CID, - // any of Gas values, and different signature, but with all + // A replacing message is a message with a different CID, + // any of Gas values, and different signature, but with all // other parameters matching (source/destination, nonce, params, etc.) if !allow_replaced && message.cid() != m.cid(){ Err(Error::Other(format!( @@ -1342,6 +1343,11 @@ where state.get_claim(self.blockstore(), id_address.into(), claim_id) } + pub fn get_all_claims(&self, ts: &Tipset) -> anyhow::Result> { + let state = self.get_verified_registry_actor_state(ts)?; + state.get_all_claims(self.blockstore()) + } + pub fn get_allocation( &self, addr: &Address, @@ -1353,6 +1359,14 @@ where state.get_allocation(self.blockstore(), id_address.id()?, allocation_id) } + pub fn get_all_allocations( + &self, + ts: &Tipset, + ) -> anyhow::Result> { + let state = self.get_verified_registry_actor_state(ts)?; + state.get_all_allocations(self.blockstore()) + } + pub fn verified_client_status( &self, addr: &Address, diff --git a/src/tool/subcommands/api_cmd.rs b/src/tool/subcommands/api_cmd.rs index 3256ff846ff7..8ab635c16156 100644 --- a/src/tool/subcommands/api_cmd.rs +++ b/src/tool/subcommands/api_cmd.rs @@ -18,6 +18,7 @@ use crate::rpc::beacon::BeaconGetEntry; use crate::rpc::eth::types::{EthAddress, EthBytes}; use crate::rpc::gas::GasEstimateGasLimit; use crate::rpc::miner::BlockTemplate; +use crate::rpc::state::StateGetAllClaims; use crate::rpc::types::{ApiTipsetKey, MessageFilter, MessageLookup}; use crate::rpc::{self, eth::*}; use crate::rpc::{prelude::*, start_rpc, RPCState}; @@ -901,6 +902,8 @@ fn state_tests_with_tipset( block.miner_address, tipset.key().into(), ))?), + RpcTest::identity(StateGetAllClaims::request((tipset.key().into(),))?), + RpcTest::identity(StateGetAllAllocations::request((tipset.key().into(),))?), RpcTest::identity(StateSectorPreCommitInfo::request(( block.miner_address, u16::MAX as _, // invalid sector number