forest/state_manager/
address_resolution.rs1use super::*;
5use crate::db::EthMappingsStore;
6use crate::shim::address::{Payload, Protocol};
7use anyhow::Context as _;
8use bls_signatures::{PublicKey as BlsPublicKey, Serialize as _};
9
10impl<DB> StateManager<DB>
11where
12 DB: Blockstore + Send + Sync + 'static,
13{
14 pub fn get_bls_public_key(
16 db: &Arc<DB>,
17 addr: &Address,
18 state_cid: Cid,
19 ) -> Result<BlsPublicKey, Error> {
20 let state = StateTree::new_from_root(Arc::clone(db), &state_cid)
21 .map_err(|e| Error::Other(e.to_string()))?;
22 let kaddr =
23 resolve_to_key_addr(&state, db, addr).context("Failed to resolve key address")?;
24
25 match kaddr.into_payload() {
26 Payload::BLS(key) => BlsPublicKey::from_bytes(&key)
27 .context("Failed to construct bls public key")
28 .map_err(Error::from),
29 _ => Err(Error::state(
30 "Address must be BLS address to load bls public key",
31 )),
32 }
33 }
34
35 pub fn lookup_id(&self, addr: &Address, ts: &Tipset) -> Result<Option<Address>, Error> {
37 let state_tree = StateTree::new_from_root(self.blockstore_owned(), ts.parent_state())
38 .map_err(|e| format!("{e:?}"))?;
39 Ok(state_tree
40 .lookup_id(addr)
41 .map_err(|e| Error::Other(e.to_string()))?
42 .map(Address::new_id))
43 }
44
45 pub fn lookup_required_id(&self, addr: &Address, ts: &Tipset) -> Result<Address, Error> {
47 self.lookup_id(addr, ts)?
48 .ok_or_else(|| Error::Other(format!("Failed to lookup the id address {addr}")))
49 }
50
51 pub async fn resolve_to_key_addr(
54 self: &Arc<Self>,
55 addr: &Address,
56 ts: &Tipset,
57 ) -> anyhow::Result<Address>
58 where
59 DB: EthMappingsStore,
60 {
61 match addr.protocol() {
62 Protocol::BLS | Protocol::Secp256k1 | Protocol::Delegated => return Ok(*addr),
63 Protocol::Actor => {
64 return Err(Error::Other(
65 "cannot resolve actor address to key address".to_string(),
66 )
67 .into());
68 }
69 _ => {}
70 };
71
72 let state = StateTree::new_from_root(self.blockstore_owned(), ts.parent_state())?;
75 if let Ok(addr) = resolve_to_key_addr(&state, self.blockstore(), addr) {
76 return Ok(addr);
77 }
78
79 let TipsetState { state_root, .. } = self.load_tipset_state(ts).await?;
81 let state = StateTree::new_from_root(self.blockstore_owned(), &state_root)?;
82
83 resolve_to_key_addr(&state, self.blockstore(), addr)
84 }
85
86 pub async fn resolve_to_deterministic_address(
89 self: &Arc<Self>,
90 address: Address,
91 ts: &Tipset,
92 ) -> anyhow::Result<Address>
93 where
94 DB: EthMappingsStore,
95 {
96 use crate::shim::address::Protocol::*;
97 match address.protocol() {
98 BLS | Secp256k1 | Delegated => Ok(address),
99 Actor => anyhow::bail!("cannot resolve actor address to key address"),
100 ID => {
101 let id = address.id()?;
102 if let Some(cached) = self.id_to_deterministic_address_cache.get_cloned(&id) {
103 return Ok(cached);
104 }
105 let resolved = if let Ok(state) =
107 StateTree::new_from_root(self.blockstore_owned(), ts.parent_state())
108 && let Ok(address) = state
109 .resolve_to_deterministic_addr(self.chain_store().blockstore(), address)
110 {
111 address
112 } else {
113 let TipsetState { state_root, .. } = self.load_tipset_state(ts).await?;
115 let state = StateTree::new_from_root(self.blockstore_owned(), &state_root)?;
116 state.resolve_to_deterministic_addr(self.chain_store().blockstore(), address)?
117 };
118 self.id_to_deterministic_address_cache.push(id, resolved);
119 Ok(resolved)
120 }
121 }
122 }
123}