Summary
StateManager::wait_for_message currently matches Lotus behavior in a way that may still be incorrect:
- the current-head fast path can return immediately without applying the requested
confidence, and
tipset_executed_message(...) is currently called with allow_replaced=true in the wait path, which means allowReplaced=false may still accept a replacement message.
This was raised during review of #7266 and appears to mirror the Lotus implementation referenced in that discussion, so it should be tracked as a separate follow-up instead of being changed incidentally in the bugfix PR.
Why this matters
The public StateWaitMsg(..., confidence, ..., allowReplaced) API contract implies that:
- the wait should honor the requested confirmation depth consistently, including when the message is already present at the current head, and
- replacement-message acceptance should be controlled by
allowReplaced.
If the current-head fast path bypasses either of those semantics, callers can observe behavior that does not match the API parameters.
Affected areas
src/state_manager/message_search.rs
src/rpc/methods/state.rs
- parity/reference check against Lotus:
Backlinks
Requested by: @hanabi1224
Acceptance criteria
- Confirm the intended semantics for
StateWaitMsg(..., confidence, ..., allowReplaced).
- Ensure the current-head receipt path does not bypass the requested
confidence.
- Ensure every
tipset_executed_message(...) call in the wait/search flow uses the effective allow_replaced.unwrap_or(true) instead of hard-coding true.
- Add or update tests covering:
- current-head hit with
confidence > 0
- replacement message present with
allowReplaced=false
- replacement message present with
allowReplaced=true
- If Lotus has the same behavior and Forest intentionally keeps parity, document that decision in code/comments and/or API notes.
Summary
StateManager::wait_for_messagecurrently matches Lotus behavior in a way that may still be incorrect:confidence, andtipset_executed_message(...)is currently called withallow_replaced=truein the wait path, which meansallowReplaced=falsemay still accept a replacement message.This was raised during review of #7266 and appears to mirror the Lotus implementation referenced in that discussion, so it should be tracked as a separate follow-up instead of being changed incidentally in the bugfix PR.
Why this matters
The public
StateWaitMsg(..., confidence, ..., allowReplaced)API contract implies that:allowReplaced.If the current-head fast path bypasses either of those semantics, callers can observe behavior that does not match the API parameters.
Affected areas
src/state_manager/message_search.rssrc/rpc/methods/state.rsfilecoin-project/lotus/chain/stmgr/searchwait.goBacklinks
StateManager::wait_for_message#7266StateManager::wait_for_message#7266 (comment)Requested by: @hanabi1224
Acceptance criteria
StateWaitMsg(..., confidence, ..., allowReplaced).confidence.tipset_executed_message(...)call in the wait/search flow uses the effectiveallow_replaced.unwrap_or(true)instead of hard-codingtrue.confidence > 0allowReplaced=falseallowReplaced=true