use cid::Cid;
use fil_actors_shared::fvm_ipld_hamt::Hamtv0 as Hamt;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;
use super::state_tree::StateRoot;
use super::state_tree::StateTreeVersion;
use crate::shim::address::Address;
pub use fvm2::state_tree::ActorState as ActorStateV2;
const HAMTV0_BIT_WIDTH: u32 = 5;
pub struct StateTreeV0<S> {
hamt: Hamt<S, ActorStateV2>,
}
impl<S> StateTreeV0<S>
where
S: Blockstore,
{
pub fn new_from_root(store: S, c: &Cid) -> anyhow::Result<Self> {
let (version, actors) = if let Ok(Some(StateRoot {
version, actors, ..
})) = store.get_cbor(c)
{
(StateTreeVersion::from(version), actors)
} else {
(StateTreeVersion::V0, *c)
};
match version {
StateTreeVersion::V0 => {
let hamt = Hamt::load_with_bit_width(&actors, store, HAMTV0_BIT_WIDTH)?;
Ok(Self { hamt })
}
_ => anyhow::bail!("unsupported state tree version: {:?}", version),
}
}
pub fn store(&self) -> &S {
self.hamt.store()
}
pub fn get_actor(&self, addr: &Address) -> anyhow::Result<Option<ActorStateV2>> {
let addr = match self.lookup_id(addr)? {
Some(addr) => addr,
None => return Ok(None),
};
let act = self.hamt.get(&addr.to_bytes())?.cloned();
Ok(act)
}
pub fn lookup_id(&self, addr: &Address) -> anyhow::Result<Option<Address>> {
if addr.protocol() == fvm_shared4::address::Protocol::ID {
return Ok(Some(*addr));
}
anyhow::bail!("StateTreeV0::lookup_id is only defined for ID addresses")
}
}