1use super::*;
5use crate::shim::actors::miner::{MinerInfo, MinerPower, Partition};
6use crate::shim::actors::verifreg::ext::VerifiedRegistryStateExt as _;
7use crate::shim::actors::verifreg::{Allocation, AllocationID, Claim};
8use ahash::HashMap;
9use fil_actor_verifreg_state::v12::DataCap;
10use fil_actor_verifreg_state::v13::ClaimID;
11use fil_actors_shared::fvm_ipld_bitfield::BitField;
12
13impl StateManager {
14 pub fn market_state(&self, ts: &Tipset) -> Result<market::State, Error> {
16 let actor = self.get_required_actor(&Address::MARKET_ACTOR, *ts.parent_state())?;
17 let market_state = market::State::load(self.db(), actor.code, actor.state)?;
18 Ok(market_state)
19 }
20
21 pub fn market_balance(&self, addr: &Address, ts: &Tipset) -> Result<MarketBalance, Error> {
23 let market_state = self.market_state(ts)?;
24 let new_addr = self.lookup_required_id(addr, ts)?;
25 let out = MarketBalance {
26 escrow: { market_state.escrow_table(self.db())?.get(&new_addr)? },
27 locked: { market_state.locked_table(self.db())?.get(&new_addr)? },
28 };
29
30 Ok(out)
31 }
32
33 pub fn miner_info(&self, addr: &Address, ts: &Tipset) -> Result<MinerInfo, Error> {
35 let actor = self.get_actor(addr, *ts.parent_state())?.ok_or_else(|| {
36 Error::state(format!(
37 "Miner actor {addr} not found at epoch {}",
38 ts.epoch()
39 ))
40 })?;
41 let state = miner::State::load(self.db(), actor.code, actor.state)?;
42
43 Ok(state.info(self.db())?)
44 }
45
46 pub fn miner_faults(&self, addr: &Address, ts: &Tipset) -> Result<BitField, Error> {
48 self.all_partition_sectors(addr, ts, |partition| partition.faulty_sectors().clone())
49 }
50
51 pub fn miner_recoveries(&self, addr: &Address, ts: &Tipset) -> Result<BitField, Error> {
53 self.all_partition_sectors(addr, ts, |partition| partition.recovering_sectors().clone())
54 }
55
56 fn all_partition_sectors(
57 &self,
58 addr: &Address,
59 ts: &Tipset,
60 get_sector: impl Fn(Partition<'_>) -> BitField,
61 ) -> Result<BitField, Error> {
62 let actor = self.get_actor(addr, *ts.parent_state())?.ok_or_else(|| {
63 Error::state(format!(
64 "Miner actor {addr} not found at epoch {}",
65 ts.epoch()
66 ))
67 })?;
68
69 let state = miner::State::load(self.db(), actor.code, actor.state)?;
70
71 let mut partitions = Vec::new();
72
73 state.for_each_deadline(&self.chain_config().policy, self.db(), |_, deadline| {
74 deadline.for_each(self.db(), |_, partition| {
75 partitions.push(get_sector(partition));
76 Ok(())
77 })
78 })?;
79
80 Ok(BitField::union(partitions.iter()))
81 }
82
83 pub fn miner_power(&self, addr: &Address, ts: &Tipset) -> Result<MinerPower, Error> {
85 if let Some((miner_power, total_power)) = self.get_power(ts.parent_state(), Some(addr))? {
86 return Ok(MinerPower {
87 miner_power,
88 total_power,
89 has_min_power: true,
90 });
91 }
92
93 Ok(MinerPower {
94 has_min_power: false,
95 miner_power: Default::default(),
96 total_power: Default::default(),
97 })
98 }
99
100 pub fn get_verified_registry_actor_state(
101 &self,
102 ts: &Tipset,
103 ) -> anyhow::Result<verifreg::State> {
104 let act = self
105 .get_actor(&Address::VERIFIED_REGISTRY_ACTOR, *ts.parent_state())
106 .map_err(Error::state)?
107 .ok_or_else(|| Error::state("actor not found"))?;
108 verifreg::State::load(self.db(), act.code, act.state)
109 }
110 pub fn get_claim(
111 &self,
112 addr: &Address,
113 ts: &Tipset,
114 claim_id: ClaimID,
115 ) -> anyhow::Result<Option<Claim>> {
116 let id_address = self.lookup_required_id(addr, ts)?;
117 let state = self.get_verified_registry_actor_state(ts)?;
118 state.get_claim(self.db(), id_address, claim_id)
119 }
120
121 pub fn get_all_claims(&self, ts: &Tipset) -> anyhow::Result<HashMap<ClaimID, Claim>> {
122 let state = self.get_verified_registry_actor_state(ts)?;
123 state.get_all_claims(self.db())
124 }
125
126 pub fn get_allocation(
127 &self,
128 addr: &Address,
129 ts: &Tipset,
130 allocation_id: AllocationID,
131 ) -> anyhow::Result<Option<Allocation>> {
132 let id_address = self.lookup_required_id(addr, ts)?;
133 let state = self.get_verified_registry_actor_state(ts)?;
134 state.get_allocation(self.db(), id_address.id()?, allocation_id)
135 }
136
137 pub fn get_all_allocations(
138 &self,
139 ts: &Tipset,
140 ) -> anyhow::Result<HashMap<AllocationID, Allocation>> {
141 let state = self.get_verified_registry_actor_state(ts)?;
142 state.get_all_allocations(self.db())
143 }
144
145 pub fn verified_client_status(
146 &self,
147 addr: &Address,
148 ts: &Tipset,
149 ) -> anyhow::Result<Option<DataCap>> {
150 let id = self.lookup_required_id(addr, ts)?;
151 let network_version = self.get_network_version(ts.epoch());
152
153 if (u32::from(network_version.0)) < 17 {
157 let state = self.get_verified_registry_actor_state(ts)?;
158 return state.verified_client_data_cap(self.db(), id);
159 }
160
161 let act = self
162 .get_actor(&Address::DATACAP_TOKEN_ACTOR, *ts.parent_state())
163 .map_err(Error::state)?
164 .ok_or_else(|| {
165 Error::state(format!(
166 "Data cap actor {} not found",
167 Address::DATACAP_TOKEN_ACTOR
168 ))
169 })?;
170
171 let state = datacap::State::load(self.db(), act.code, act.state)?;
172
173 state.verified_client_data_cap(self.db(), id)
174 }
175}