Skip to content

Add new nonce-fix and replace mpool tools#6911

Closed
sudo-shashank wants to merge 16 commits into
mainfrom
shashank/nonce-fix-cmd
Closed

Add new nonce-fix and replace mpool tools#6911
sudo-shashank wants to merge 16 commits into
mainfrom
shashank/nonce-fix-cmd

Conversation

@sudo-shashank
Copy link
Copy Markdown
Contributor

@sudo-shashank sudo-shashank commented Apr 15, 2026

Summary of changes

Changes introduced in this pull request:

  • Implement mpool nonce-fix and replace cli commands.

Reference issue to close (if applicable)

Closes

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation. All new code adheres to the team's documentation standards,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

Outside contributions

  • I have read and agree to the CONTRIBUTING document.
  • I have read and agree to the AI Policy document. I understand that failure to comply with the guidelines will lead to rejection of the pull request.

Summary by CodeRabbit

  • New Features

    • Added forest-cli mpool nonce-fix command to fill nonce gaps with address range and gas fee customization options.
    • Added forest-cli mpool replace command to replace pending messages with adjusted gas parameters using replace-by-fee mechanism, supporting both auto and manual modes.
  • Tests

    • Added integration tests for mempool command operations.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding two new mempool CLI commands ('nonce-fix' and 'replace') to the mpool tools.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch shashank/nonce-fix-cmd
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch shashank/nonce-fix-cmd

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Comment thread src/cli/subcommands/mpool_cmd.rs Dismissed
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/rpc/methods/gas.rs (1)

334-334: ⚡ Quick win

Prefer pub(crate) for cap_gas_fee unless external crate consumers are intentional.

This appears to be an internal utility used across crate modules; pub broadens API surface and long-term compatibility burden.

🔧 Suggested change
-pub fn cap_gas_fee(
+pub(crate) fn cap_gas_fee(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/rpc/methods/gas.rs` at line 334, Change the visibility of the cap_gas_fee
function from public to crate-only to limit the API surface: locate the function
named cap_gas_fee and replace its declaration visibility from pub to pub(crate)
so it remains accessible across crate modules but not exported to dependent
crates; ensure there are no external call sites expecting a public symbol and
run tests to verify internal usages still compile.
src/message_pool/mod.rs (1)

17-17: ⚡ Quick win

Narrow utils visibility to crate scope instead of public wildcard export.

pub use utils::* exposes internal helpers as part of external API. For this PR’s usage, pub(crate) access is sufficient and safer for API stability.

🔧 Suggested change
-pub use self::{
+pub(crate) use self::{
     config::*,
     errors::*,
     mpool_locker::MpoolLocker,
     msgpool::{msg_pool::MessagePool, *},
     nonce_tracker::NonceTracker,
     utils::*,
 };
As per coding guidelines, "`**/mod.rs`: Each module should have a `mod.rs` file with public API exports and private submodules for implementation details".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/message_pool/mod.rs` at line 17, The file exposes internal helpers via a
public wildcard re-export (utils), so change the export from a public API to
crate-scoped by replacing the `pub use utils::*` export with a crate-only export
(e.g., `pub(crate) use utils::*`) in src/message_pool/mod.rs so the utils module
remains internal; update the mod's export line and run cargo check to ensure no
external code relied on the now-hidden symbols and adjust any caller imports if
needed.
src/cli/subcommands/mpool_cmd.rs (1)

977-977: ⚡ Quick win

Use .get(0) instead of direct indexing in tests.

pending[0] can panic if fixture setup changes; .get(0) keeps the assertion failure explicit and follows repo guidance.

🔧 Suggested change
-        assert_eq!(found.cid(), pending[0].cid());
+        assert_eq!(
+            found.cid(),
+            pending.get(0).expect("expected one pending message").cid()
+        );
As per coding guidelines, "`**/*.rs`: Use `.get()` instead of direct indexing `[index]` to avoid panics".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/subcommands/mpool_cmd.rs` at line 977, The test currently indexes
pending with pending[0] which can panic; change the assertion to use
pending.get(0) and fail explicitly (e.g., pending.get(0).expect("expected at
least one pending entry")) when obtaining the element before comparing CIDs so
the assertion is explicit and non-panicking; update the line with the symbols
found.cid(), pending.get(0).expect(...).cid() inside the existing assert_eq!
call.
tests/calibnet_mpool_tools.rs (1)

60-63: ⚡ Quick win

This assertion does not verify replacement behavior.

Polling StateSearchMsg for the original CID can succeed even if replacement never happened (the original message may simply be mined). Consider asserting on the new CID returned by mpool replace.

🔧 Suggested direction
-    forest_cli(&[
+    let out = forest_cli(&[
         "mpool",
         "replace",
         "--from",
         addr,
         "--nonce",
         &nonce.to_string(),
         "--auto",
-    ])
-    .unwrap();
+    ]).unwrap();
+
+    let new_cid = out
+        .strip_prefix("new message cid: ")
+        .context("unexpected mpool replace output")?
+        .trim()
+        .to_string();

     assert!(
-        poll_until_state_search_msg(&cid).await.is_ok(),
-        "mpool replace --auto should replace message {cid} from {addr} at nonce {nonce}."
+        poll_until_state_search_msg(&new_cid).await.is_ok(),
+        "mpool replace --auto should land replacement message {new_cid} for nonce {nonce}."
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/calibnet_mpool_tools.rs` around lines 60 - 63, The test currently only
polls for the original CID using poll_until_state_search_msg(&cid) which can
succeed even if replacement never occurred; change the test to capture the new
CID returned by the `mpool replace --auto` command (the replacement result),
then assert that poll_until_state_search_msg(&new_cid).await.is_ok() to verify
the replacement was registered, and optionally assert that the original cid is
not pending/mined in the mempool if you can query mempool state; locate the
`mpool replace` invocation and the poll_until_state_search_msg call in
tests/calibnet_mpool_tools.rs and replace the existing assertion to use the
returned new CID instead of the original `cid`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli/subcommands/mpool_cmd.rs`:
- Around line 223-225: Add a validation in the manual replace path to reject
cases where gas_feecap is less than gas_premium: after computing gas_premium and
gas_feecap (the lines that set original_msg.gas_premium and
original_msg.gas_fee_cap) check if gas_feecap < gas_premium and return a CLI
validation error (with a clear message like "gas-feecap must be >= gas-premium")
instead of proceeding to set fields or pushing; update the same branch that
contains the if let Some(limit) = gas_limit block so the check runs before
modifying original_msg or attempting the push.

In `@tests/calibnet_mpool_tools.rs`:
- Around line 14-15: These calibnet mpool integration tests mutate shared state
and must run serially; add the serial_test::serial attribute to them. For the
test function mpool_nonce_fix_auto_unblocks_pending (and the other calibnet
mpool test in this file), annotate each test with #[serial_test::serial] in
addition to #[tokio::test] (order doesn't matter) so the tests run sequentially
and avoid nonce/mempool race flakiness.

---

Nitpick comments:
In `@src/cli/subcommands/mpool_cmd.rs`:
- Line 977: The test currently indexes pending with pending[0] which can panic;
change the assertion to use pending.get(0) and fail explicitly (e.g.,
pending.get(0).expect("expected at least one pending entry")) when obtaining the
element before comparing CIDs so the assertion is explicit and non-panicking;
update the line with the symbols found.cid(), pending.get(0).expect(...).cid()
inside the existing assert_eq! call.

In `@src/message_pool/mod.rs`:
- Line 17: The file exposes internal helpers via a public wildcard re-export
(utils), so change the export from a public API to crate-scoped by replacing the
`pub use utils::*` export with a crate-only export (e.g., `pub(crate) use
utils::*`) in src/message_pool/mod.rs so the utils module remains internal;
update the mod's export line and run cargo check to ensure no external code
relied on the now-hidden symbols and adjust any caller imports if needed.

In `@src/rpc/methods/gas.rs`:
- Line 334: Change the visibility of the cap_gas_fee function from public to
crate-only to limit the API surface: locate the function named cap_gas_fee and
replace its declaration visibility from pub to pub(crate) so it remains
accessible across crate modules but not exported to dependent crates; ensure
there are no external call sites expecting a public symbol and run tests to
verify internal usages still compile.

In `@tests/calibnet_mpool_tools.rs`:
- Around line 60-63: The test currently only polls for the original CID using
poll_until_state_search_msg(&cid) which can succeed even if replacement never
occurred; change the test to capture the new CID returned by the `mpool replace
--auto` command (the replacement result), then assert that
poll_until_state_search_msg(&new_cid).await.is_ok() to verify the replacement
was registered, and optionally assert that the original cid is not pending/mined
in the mempool if you can query mempool state; locate the `mpool replace`
invocation and the poll_until_state_search_msg call in
tests/calibnet_mpool_tools.rs and replace the existing assertion to use the
returned new CID instead of the original `cid`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e1af9eac-68cc-4b79-abe2-5c8263471529

📥 Commits

Reviewing files that changed from the base of the PR and between 3f55831 and 425dd15.

📒 Files selected for processing (12)
  • .config/forest.dic
  • Cargo.toml
  • docs/docs/users/reference/cli.md
  • mise.toml
  • src/cli/subcommands/mpool_cmd.rs
  • src/message_pool/mod.rs
  • src/message_pool/msgpool/msg_set.rs
  • src/message_pool/msgpool/utils.rs
  • src/rpc/methods/gas.rs
  • tests/calibnet_mpool_tools.rs
  • tests/calibnet_wallet.rs
  • tests/common/calibnet_wallet_helpers.rs

Comment thread src/cli/subcommands/mpool_cmd.rs
Comment thread tests/calibnet_mpool_tools.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/cli/subcommands/mpool_cmd.rs (1)

478-493: 💤 Low value

Consider making gas_premium configurable for filler messages.

The hardcoded gas_premium of 5 atto works for typical conditions but may cause fillers to be stuck during network congestion. Users can override gas_fee_cap but not gas_premium. This is consistent with Lotus's lotus-shed nonce-fix, so acceptable as-is—flagging as optional enhancement for future consideration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/subcommands/mpool_cmd.rs` around lines 478 - 493, The filler messages
currently hardcode gas_premium to TokenAmount::from_atto(5u64) inside the loop
that builds Message (see Message { ... gas_premium:
TokenAmount::from_atto(5u64), ... }) before WalletSignMessage::call and
MpoolPush::call; make gas_premium configurable by adding a CLI/command option
(e.g., --filler-gas-premium) or a parameter passed into this command, parse it
into a TokenAmount variable (e.g., filler_gas_premium) and replace the hardcoded
TokenAmount::from_atto(5u64) with that variable so filler messages use the
user-provided gas_premium value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/cli/subcommands/mpool_cmd.rs`:
- Around line 478-493: The filler messages currently hardcode gas_premium to
TokenAmount::from_atto(5u64) inside the loop that builds Message (see Message {
... gas_premium: TokenAmount::from_atto(5u64), ... }) before
WalletSignMessage::call and MpoolPush::call; make gas_premium configurable by
adding a CLI/command option (e.g., --filler-gas-premium) or a parameter passed
into this command, parse it into a TokenAmount variable (e.g.,
filler_gas_premium) and replace the hardcoded TokenAmount::from_atto(5u64) with
that variable so filler messages use the user-provided gas_premium value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 37e3bdb4-ab2f-41e9-9a08-6fb9324a816b

📥 Commits

Reviewing files that changed from the base of the PR and between 425dd15 and 305be3c.

📒 Files selected for processing (6)
  • docs/docs/users/reference/cli.md
  • src/cli/subcommands/mpool_cmd.rs
  • src/message_pool/mod.rs
  • src/message_pool/msgpool/utils.rs
  • src/rpc/methods/gas.rs
  • tests/calibnet_mpool_tools.rs
✅ Files skipped from review due to trivial changes (1)
  • docs/docs/users/reference/cli.md

@sudo-shashank sudo-shashank changed the title Add new mpool tools Add new nonce-fix and replace mpool tools May 20, 2026
@sudo-shashank sudo-shashank deleted the shashank/nonce-fix-cmd branch May 20, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants