diff --git a/CHANGELOG.md b/CHANGELOG.md index e94e2ef8abd..5a308da823d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ ### Fixed - [#6327](https://github.com/ChainSafe/forest/pull/6327) Fixed: Forest returns 404 for all invalid api paths. +- [#6354](https://github.com/ChainSafe/forest/pull/6354) Fixed: Correctly calculate the epoch range instead of directly using the look back limit value while searching for messages. ## Forest v0.30.5 "Dulce de Leche" diff --git a/src/rpc/methods/state.rs b/src/rpc/methods/state.rs index 51eb3c47f7b..3e3d644ef0d 100644 --- a/src/rpc/methods/state.rs +++ b/src/rpc/methods/state.rs @@ -1266,7 +1266,6 @@ impl RpcMethod<4> for StateSearchMsg { } } -/// Looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed. /// See pub enum StateSearchMsgLimited {} @@ -1275,7 +1274,9 @@ impl RpcMethod<2> for StateSearchMsgLimited { const PARAM_NAMES: [&'static str; 2] = ["message_cid", "look_back_limit"]; const API_PATHS: BitFlags = make_bitflags!(ApiPaths::V0); // Not supported in V1 const PERMISSION: Permission = Permission::Read; - + const DESCRIPTION: Option<&'static str> = Some( + "Looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed.", + ); type Params = (Cid, i64); type Ok = MessageLookup; diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index 4e46d91aaf7..7244acf2f65 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -41,7 +41,8 @@ pub use methods::*; /// Protocol or transport-specific error pub use jsonrpsee::core::ClientError; -const LOOKBACK_NO_LIMIT: ChainEpoch = -1; +/// Sentinel value, indicating no limit on how far back to search in the chain (all the way to genesis epoch). +pub const LOOKBACK_NO_LIMIT: ChainEpoch = -1; /// The macro `callback` will be passed in each type that implements /// [`RpcMethod`]. diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 24f501d092e..1e151052e72 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -1046,17 +1046,17 @@ where &self, mut current: Tipset, message: &ChainMessage, - look_back_limit: Option, - allow_replaced: Option, + lookback_max_epoch: ChainEpoch, + allow_replaced: bool, ) -> Result, Error> { - let allow_replaced = allow_replaced.unwrap_or(true); let message_from_address = message.from(); let message_sequence = message.sequence(); let mut current_actor_state = self .get_required_actor(&message_from_address, *current.parent_state()) .map_err(Error::state)?; let message_from_id = self.lookup_required_id(&message_from_address, ¤t)?; - while current.epoch() > look_back_limit.unwrap_or_default() { + + while current.epoch() >= lookback_max_epoch { let parent_tipset = self .chain_index() .load_required_tipset(current.parents()) @@ -1091,6 +1091,7 @@ where Ok(None) } + /// Searches backwards through the chain for a message receipt. fn search_back_for_message( &self, current: Tipset, @@ -1098,7 +1099,22 @@ where look_back_limit: Option, allow_replaced: Option, ) -> Result, Error> { - self.check_search(current, message, look_back_limit, allow_replaced) + let current_epoch = current.epoch(); + let allow_replaced = allow_replaced.unwrap_or(true); + + // Calculate the max lookback epoch (inclusive lower bound) for the search. + let lookback_max_epoch = match look_back_limit { + // No search: limit = 0 means search 0 epochs + Some(0) => return Ok(None), + // Limited search: calculate the inclusive lower bound, clamped to genesis + // Example: limit=5 at epoch=1000 → min_epoch=996, searches [996,1000] = 5 epochs + // Example: limit=2000 at epoch=1000 → min_epoch=0, searches [0,1000] = 1001 epochs (all available) + Some(limit) if limit > 0 => (current_epoch - limit + 1).max(0), + // Search all the way to genesis (epoch 0) + _ => 0, + }; + + self.check_search(current, message, lookback_max_epoch, allow_replaced) } /// Returns a message receipt from a given tipset and message CID. diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index 7adf8786268..11e9634087a 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -288,8 +288,8 @@ filecoin_statereadstate_1748444218790447.rpcsnap.json.zst filecoin_statereadstate_1748444218790807.rpcsnap.json.zst filecoin_statereadstate_1749657617007020.rpcsnap.json.zst filecoin_statereplay_1743504051038215.rpcsnap.json.zst -filecoin_statesearchmsg_1741784596636715.rpcsnap.json.zst -filecoin_statesearchmsglimited_1741784596704877.rpcsnap.json.zst +filecoin_statesearchmsg_1767947430707712.rpcsnap.json.zst +filecoin_statesearchmsglimited_1767936905056090.rpcsnap.json.zst filecoin_statesectorexpiration_1741784727996672.rpcsnap.json.zst filecoin_statesectorgetinfo_1743098602783105.rpcsnap.json.zst filecoin_statesectorpartition_1737546933391247.rpcsnap.json.zst