22// SPDX-License-Identifier: Apache-2.0, MIT
33
44use crate :: blocks:: { CachingBlockHeader , Tipset , TipsetKey } ;
5+ use crate :: chain:: index:: ResolveNullTipset ;
56use crate :: chain:: { ChainStore , HeadChanges } ;
67use crate :: message:: { ChainMessage , SignedMessage } ;
78use crate :: message_pool:: errors:: Error ;
@@ -10,7 +11,7 @@ use crate::message_pool::msg_pool::{
1011} ;
1112use crate :: networks:: Height ;
1213use crate :: shim:: {
13- address:: Address ,
14+ address:: { Address , Protocol :: * } ,
1415 econ:: TokenAmount ,
1516 message:: Message ,
1617 state_tree:: { ActorState , StateTree } ,
@@ -101,13 +102,37 @@ impl<DB: Blockstore> Provider for ChainStore<DB> {
101102 . map_err ( |err| err. into ( ) )
102103 }
103104
104- // TODO(forest): https://github.com/ChainSafe/forest/issues/6891
105+ /// Resolves an address to its deterministic key form using the state at
106+ /// finality lookback, This ensures the resolved address is reorg-stable.
105107 fn resolve_to_key ( & self , addr : & Address , ts : & Tipset ) -> Result < Address , Error > {
106- let state = StateTree :: new_from_root ( self . blockstore ( ) . clone ( ) , ts. parent_state ( ) )
107- . map_err ( |e| Error :: Other ( e. to_string ( ) ) ) ?;
108- state
109- . resolve_to_deterministic_addr ( self . blockstore ( ) , * addr)
110- . map_err ( |e| Error :: Other ( e. to_string ( ) ) )
108+ match addr. protocol ( ) {
109+ BLS | Secp256k1 | Delegated => return Ok ( * addr) ,
110+ Actor => {
111+ return Err ( Error :: Other (
112+ "Cannot resolve actor address to key address" . into ( ) ,
113+ ) ) ;
114+ }
115+ _ => {
116+ let lookback_ts = if ts. epoch ( ) > self . chain_config ( ) . policy . chain_finality {
117+ self . chain_index ( )
118+ . tipset_by_height (
119+ ts. epoch ( ) - self . chain_config ( ) . policy . chain_finality ,
120+ ts. clone ( ) ,
121+ ResolveNullTipset :: TakeOlder ,
122+ )
123+ . map_err ( |e| Error :: Other ( e. to_string ( ) ) ) ?
124+ } else {
125+ ts. clone ( )
126+ } ;
127+
128+ let state =
129+ StateTree :: new_from_root ( self . blockstore ( ) . clone ( ) , lookback_ts. parent_state ( ) )
130+ . map_err ( |e| Error :: Other ( e. to_string ( ) ) ) ?;
131+ state
132+ . resolve_to_deterministic_addr ( self . blockstore ( ) , * addr)
133+ . map_err ( |e| Error :: Other ( e. to_string ( ) ) )
134+ }
135+ }
111136 }
112137
113138 fn messages_for_tipset ( & self , ts : & Tipset ) -> Result < Arc < Vec < ChainMessage > > , Error > {
0 commit comments