diff --git a/actors/init/src/v0/state.rs b/actors/init/src/v0/state.rs index 721f5fbe..04791851 100644 --- a/actors/init/src/v0/state.rs +++ b/actors/init/src/v0/state.rs @@ -2,8 +2,13 @@ // SPDX-License-Identifier: Apache-2.0, MIT use cid::Cid; +use fil_actors_shared::v9::{make_map_with_root_and_bitwidth, shared::HAMT_BIT_WIDTH}; +use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::tuple::*; -use fvm_shared::ActorID; +use fvm_shared::{ + address::{Address, Protocol}, + ActorID, +}; /// Defines first available ID address after builtin actors pub const FIRST_NON_SINGLETON_ADDR: ActorID = 100; @@ -24,4 +29,28 @@ impl State { network_name, } } + + /// `ResolveAddress` resolves an address to an ID-address, if possible. + /// If the provided address is an ID address, it is returned as-is. + /// This means that mapped ID-addresses (which should only appear as values, not keys) and + /// singleton actor addresses (which are not in the map) pass through unchanged. + /// + /// Returns an ID-address and `true` if the address was already an ID-address or was resolved + /// in the mapping. + /// Returns an undefined address and `false` if the address was not an ID-address and not found + /// in the mapping. + /// Returns an error only if state was inconsistent. + pub fn resolve_address( + &self, + store: &BS, + addr: &Address, + ) -> anyhow::Result> { + if addr.protocol() == Protocol::ID { + return Ok(Some(*addr)); + } + + let map = make_map_with_root_and_bitwidth(&self.address_map, store, HAMT_BIT_WIDTH)?; + + Ok(map.get(&addr.to_bytes())?.copied().map(Address::new_id)) + } } diff --git a/forest b/forest index 88ab624e..45f2b74c 160000 --- a/forest +++ b/forest @@ -1 +1 @@ -Subproject commit 88ab624edb9d73551e6c757449f8b2027607835b +Subproject commit 45f2b74cf586b40661e5c7a78acfce114c90a646