forest/state_manager/
address_resolution.rs1use super::*;
5use crate::prelude::*;
6use crate::shim::address::Payload;
7use bls_signatures::{PublicKey as BlsPublicKey, Serialize as _};
8
9impl StateManager {
10 pub fn get_bls_public_key(
12 db: &(impl Blockstore + ShallowClone),
13 addr: Address,
14 state_cid: Cid,
15 ) -> Result<BlsPublicKey, Error> {
16 let state =
17 StateTree::new_from_root(db, &state_cid).map_err(|e| Error::Other(e.to_string()))?;
18 let kaddr = state
19 .resolve_to_deterministic_address(db, addr)
20 .context("Failed to resolve key address")?;
21
22 match kaddr.into_payload() {
23 Payload::BLS(key) => BlsPublicKey::from_bytes(&key)
24 .context("Failed to construct bls public key")
25 .map_err(Error::from),
26 _ => Err(Error::state(
27 "Address must be BLS address to load bls public key",
28 )),
29 }
30 }
31
32 pub fn lookup_id(&self, addr: &Address, ts: &Tipset) -> Result<Option<Address>, Error> {
34 let state_tree =
35 StateTree::new_from_root(self.db(), ts.parent_state()).map_err(|e| format!("{e:?}"))?;
36 Ok(state_tree
37 .lookup_id(addr)
38 .map_err(|e| Error::Other(e.to_string()))?
39 .map(Address::new_id))
40 }
41
42 pub fn lookup_required_id(&self, addr: &Address, ts: &Tipset) -> Result<Address, Error> {
44 self.lookup_id(addr, ts)?
45 .ok_or_else(|| Error::Other(format!("Failed to lookup the id address {addr}")))
46 }
47
48 pub async fn resolve_to_deterministic_address(
51 &self,
52 address: Address,
53 ts: &Tipset,
54 ) -> anyhow::Result<Address> {
55 use crate::shim::address::Protocol::*;
56 match address.protocol() {
57 BLS | Secp256k1 | Delegated => Ok(address),
58 Actor => anyhow::bail!("cannot resolve actor address to key address"),
59 ID => {
60 let id = address.id()?;
61 let resolve = async {
62 let resolved = if let Ok(state) =
64 StateTree::new_from_root(self.db(), ts.parent_state())
65 && let Ok(address) =
66 state.resolve_to_deterministic_address(self.db(), address)
67 {
68 address
69 } else {
70 let TipsetState { state_root, .. } = self.load_tipset_state(ts).await?;
72 let state = StateTree::new_from_root(self.db(), &state_root)?;
73 state.resolve_to_deterministic_address(self.db(), address)?
74 };
75 anyhow::Ok(resolved)
76 };
77 match &self.id_to_deterministic_address_cache {
80 Some(cache) => cache.get_or_insert_async(&id, resolve).await,
81 None => resolve.await,
82 }
83 }
84 }
85 }
86}