Uh oh!
There was an error while loading. Please reload this page.
feat: strict checks for address args in forest-cli - #6011
Conversation
WalkthroughConverts the CLI to async: Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant OS as OS
participant CLI as forest-cli (bin)
participant Main as cli::main
participant Log as logger
participant RPC as rpc::Client
participant Node as Lotus RPC
OS->>CLI: start
rect rgba(200,220,255,0.25)
note right of CLI: Tokio multi_thread runtime
CLI->>Main: await main(args)
end
Main->>Log: setup_logger(...)
Main->>RPC: default_or_from_env(None)
Main->>Node: StateNetworkName.call()
Node-->>Main: NetworkName
Main->>Main: set CurrentNetwork if not Mainnet
Main->>Main: Cli::parse_from(args)
alt Subcommand: mpool pending/nonce
Main->>RPC: execute with StrictAddress (.into())
else Subcommand: state read-state
Main->>RPC: StateReadState.request(StrictAddress.into(), tipset)
else Subcommand: config
Main->>Main: run(&mut stdout)
end
Main-->>CLI: Result<()>
CLI-->>OS: exit code
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File ( |
LesnyRumcajs
commented
Aug 28, 2025
@coderabbitai create a corresponding issue for the |
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 2902 🏁 Script executed: Length of output: 2044 🏁 Script executed: Length of output: 23115 🏁 Script executed: Length of output: 3524 🏁 Script executed: Length of output: 2410 🏁 Script executed: Length of output: 2490 @LesnyRumcajs I've successfully created issue #6012 for implementing strict address validation in the The issue documents the need to apply the same stricter address validation improvements that were implemented in
The issue references this PR (#6011) and the original issue (#6006) for context, and I've assigned it to you as requested. 🐰✨ 🧠 Learnings used |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
CHANGELOG.md (1)
32-32: Reword entry for clarity and consistency.Prefer “Stricter …” and reference the actual change (StrictAddress), aligning tone with nearby entries.
-- [#6006](https://github.com/ChainSafe/forest/issues/6006) More strict checks for the address arguments in the `forest-cli` subcommands.+- [#6006](https://github.com/ChainSafe/forest/issues/6006) Stricter validation for address arguments in `forest-cli` subcommands (use `StrictAddress`).src/cli/subcommands/state_cmd.rs (2)
36-39: Public CLI surface change: document/test network-prefix expectations.
actor_address: StrictAddressnow depends onCurrentNetwork. Ensure help text or docs mention expected prefixes (f…for mainnet,t…for testnets) and add a test that fails on mismatched prefixes.
76-82: Timeout choice: reconsiderDuration::MAX.An unbounded
read-statecan hang indefinitely. Consider a reasonable default (e.g., env-configurable) with a clear error on timeout.src/cli/subcommands/mpool_cmd.rs (2)
49-70: Precompute filter keys and simplify predicates.Avoid repeated conversions inside the hot filter loop and use
map_orfor readability.fn filter_messages( messages: Vec<SignedMessage>, local_addrs: Option<HashSet<Address>>, - to: &Option<StrictAddress>,- from: &Option<StrictAddress>,+ to: &Option<StrictAddress>,+ from: &Option<StrictAddress>, ) -> anyhow::Result<Vec<SignedMessage>> { use crate::message::Message; - let filtered = messages+ // Precompute once outside the loop+ let to_addr: Option<Address> = to.as_ref().map(|a| (*a).into());+ let from_addr: Option<Address> = from.as_ref().map(|a| (*a).into());++ let filtered = messages .into_iter() .filter(|msg| { local_addrs .as_ref() .map(|addrs| addrs.contains(&msg.from())) .unwrap_or(true) - && to.map(|addr| msg.to() == addr.into()).unwrap_or(true)- && from.map(|addr| msg.from() == addr.into()).unwrap_or(true)+ && to_addr.map_or(true, |addr| msg.to() == addr)+ && from_addr.map_or(true, |addr| msg.from() == addr) }) .collect(); Ok(filtered) }
425-432: Minor: prefer mainnet/testnet-agnostic fixtures.Using
t…literals is fine for unit tests, but consider constructing viaCurrentNetworkto avoid coupling to a default. Not blocking.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
CHANGELOG.md(1 hunks)src/bin/forest-cli.rs(1 hunks)src/cli/main.rs(1 hunks)src/cli/subcommands/mpool_cmd.rs(6 hunks)src/cli/subcommands/state_cmd.rs(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: LesnyRumcajs
PR: ChainSafe/forest#5907
File: src/rpc/methods/state.rs:523-570
Timestamp: 2025-08-06T15:44:33.467Z
Learning: LesnyRumcajs prefers to rely on BufWriter's Drop implementation for automatic flushing rather than explicit flush() calls in Forest codebase.
📚 Learning: 2025-08-08T12:10:45.218Z
Learnt from: hanabi1224
PR: ChainSafe/forest#5867
File: src/ipld/util.rs:553-558
Timestamp: 2025-08-08T12:10:45.218Z
Learning: Forest project targets Rust stable >=1.89; features stabilized in 1.88 like let-chains are acceptable in this codebase.
Applied to files:
src/bin/forest-cli.rs
🧬 Code graph analysis (3)
src/bin/forest-cli.rs (1)
src/cli/main.rs (1)
main(14-51)
src/cli/subcommands/mpool_cmd.rs (3)
src/message/chain_message.rs (1)
to(53-58)src/message/signed_message.rs (1)
to(107-109)src/shim/address.rs (13)
from(311-313)from(317-319)from(323-325)from(329-331)from(335-337)from(341-343)from(347-353)from(357-359)from(363-369)from(373-375)from(379-381)from(385-387)from(391-395)
src/cli/main.rs (5)
src/bin/forest-cli.rs (1)
main(5-7)src/wallet/main.rs (1)
main(13-39)src/rpc/client.rs (3)
client(114-114)default_or_from_env(46-77)call(92-151)src/shim/address.rs (4)
from_str(178-183)from_str(299-302)set_global(66-69)default(122-124)src/cli_shared/logger/mod.rs (1)
setup_logger(21-115)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build Ubuntu
- GitHub Check: tests-release
- GitHub Check: Build MacOS
- GitHub Check: tests
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: All lint checks
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (go)
🔇 Additional comments (5)
src/bin/forest-cli.rs (1)
4-6: Async entrypoint migration looks good.Top-level Tokio runtime + await on forest_main avoids nested runtimes. No issues spotted.
src/cli/main.rs (1)
32-50: Consider honoring user-provided logger options.Passing
CliOpts::default()ignores any user-specified logging options. If CLI exposes such options, parse and pass them; otherwise, confirm this is intentional.src/cli/subcommands/state_cmd.rs (1)
7-7: Import reduction and StrictAddress usage are appropriate.Switching to
StrictAddresstightens validation at parse-time and simplifies downstream conversions.src/cli/subcommands/mpool_cmd.rs (2)
28-37: CLI types tightened toStrictAddress— good upgrade.This enforces address validity at parse time and removes ad-hoc parsing.
271-273: Nonce call conversion is correct.Passing
address.into()keeps RPC surface unchanged while enforcing strict parsing at the CLI boundary.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
36d1470 to
11ba58cCompareUh oh!
There was an error while loading. Please reload this page.
Mirrors the `forest-cli` treatment introduced in ChainSafe#6011 for the `forest-wallet` binary. Address arguments to `balance`, `export`, `has`, `delete`, `set-default`, `sign`, `verify` and the `--from` option of `send` are now parsed into `StrictAddress` at CLI-parse time. clap surfaces a `ValueValidation` error on a malformed input instead of deferring to a runtime `StrictAddress::from_str(...)?` fallback, and each handler simply destructures the typed value via `field: StrictAddress(inner)`. Network detection is moved ahead of `Cli::parse_from` so that clap-time `StrictAddress` validation accepts testnet (`t0...`) addresses when the daemon reports a testnet chain. Client construction errors propagate (matching `forest-cli`); an unreachable daemon leaves the global `CurrentNetwork` at its mainnet default. `wallet_default_address()` now returns `Option<Address>` rather than `Option<String>`, removing a stringify-then-reparse round trip through `StrictAddress::from_str` in both the `list` and `send` handlers. `Send.target_address` is intentionally kept as a `String` because it accepts ETH (`0x...`) recipients, which `StrictAddress` rejects; `resolve_target_address` continues to handle the dispatch. `ValidateAddress.address` also stays a `String`, since its purpose is to validate arbitrary user input. Two clap-level regression tests guard against an accidental revert of the `StrictAddress` typing. Refs ChainSafe#6012
Mirrors the `forest-cli` treatment introduced in ChainSafe#6011 for the `forest-wallet` binary. Address arguments to `balance`, `export`, `has`, `delete`, `set-default`, `sign`, `verify` and the `--from` option of `send` are now parsed into `StrictAddress` at CLI-parse time. clap surfaces a `ValueValidation` error on a malformed input instead of deferring to a runtime `StrictAddress::from_str(...)?` fallback, and each handler simply destructures the typed value via `field: StrictAddress(inner)`. Network detection is moved ahead of `Cli::parse_from` so that clap-time `StrictAddress` validation accepts testnet (`t0...`) addresses when the daemon reports a testnet chain. Client construction errors propagate (matching `forest-cli`); an unreachable daemon leaves the global `CurrentNetwork` at its mainnet default. `wallet_default_address()` now returns `Option<Address>` rather than `Option<String>`, removing a stringify-then-reparse round trip through `StrictAddress::from_str` in both the `list` and `send` handlers. `Send.target_address` is intentionally kept as a `String` because it accepts ETH (`0x...`) recipients, which `StrictAddress` rejects; `resolve_target_address` continues to handle the dispatch. `ValidateAddress.address` also stays a `String`, since its purpose is to validate arbitrary user input. Two clap-level regression tests guard against an accidental revert of the `StrictAddress` typing. Refs ChainSafe#6012
Mirrors the `forest-cli` treatment introduced in ChainSafe#6011 for the `forest-wallet` binary. Address arguments to `balance`, `export`, `has`, `delete`, `set-default`, `sign`, `verify` and the `--from` option of `send` are now parsed into `StrictAddress` at CLI-parse time. clap surfaces a `ValueValidation` error on a malformed input instead of deferring to a runtime `StrictAddress::from_str(...)?` fallback, and each handler simply destructures the typed value via `field: StrictAddress(inner)`. Network detection is moved ahead of `Cli::parse_from` so that clap-time `StrictAddress` validation accepts testnet (`t0...`) addresses when the daemon reports a testnet chain. Client construction errors propagate (matching `forest-cli`); an unreachable daemon leaves the global `CurrentNetwork` at its mainnet default. `wallet_default_address()` now returns `Option<Address>` rather than `Option<String>`, removing a stringify-then-reparse round trip through `StrictAddress::from_str` in both the `list` and `send` handlers. `Send.target_address` is intentionally kept as a `String` because it accepts ETH (`0x...`) recipients, which `StrictAddress` rejects; `resolve_target_address` continues to handle the dispatch. `ValidateAddress.address` also stays a `String`, since its purpose is to validate arbitrary user input. Two clap-level regression tests guard against an accidental revert of the `StrictAddress` typing. Refs ChainSafe#6012
Mirrors the `forest-cli` treatment introduced in ChainSafe#6011 for the `forest-wallet` binary. Address arguments to `balance`, `export`, `has`, `delete`, `set-default`, `sign`, `verify` and the `--from` option of `send` are now parsed into `StrictAddress` at CLI-parse time. clap surfaces a `ValueValidation` error on a malformed input instead of deferring to a runtime `StrictAddress::from_str(...)?` fallback, and each handler simply destructures the typed value via `field: StrictAddress(inner)`. Network detection is moved ahead of `Cli::parse_from` so that clap-time `StrictAddress` validation accepts testnet (`t0...`) addresses when the daemon reports a testnet chain. Client construction errors propagate (matching `forest-cli`); an unreachable daemon leaves the global `CurrentNetwork` at its mainnet default. `wallet_default_address()` now returns `Option<Address>` rather than `Option<String>`, removing a stringify-then-reparse round trip through `StrictAddress::from_str` in both the `list` and `send` handlers. `Send.target_address` is intentionally kept as a `String` because it accepts ETH (`0x...`) recipients, which `StrictAddress` rejects; `resolve_target_address` continues to handle the dispatch. `ValidateAddress.address` also stays a `String`, since its purpose is to validate arbitrary user input. Two clap-level regression tests guard against an accidental revert of the `StrictAddress` typing. Refs ChainSafe#6012
Mirrors the `forest-cli` treatment introduced in ChainSafe#6011 for the `forest-wallet` binary. Address arguments to `balance`, `export`, `has`, `delete`, `set-default`, `sign`, `verify` and the `--from` option of `send` are now parsed into `StrictAddress` at CLI-parse time. clap surfaces a `ValueValidation` error on a malformed input instead of deferring to a runtime `StrictAddress::from_str(...)?` fallback, and each handler simply destructures the typed value via `field: StrictAddress(inner)`. Network detection is moved ahead of `Cli::parse_from` so that clap-time `StrictAddress` validation accepts testnet (`t0...`) addresses when the daemon reports a testnet chain. Client construction errors propagate (matching `forest-cli`); an unreachable daemon leaves the global `CurrentNetwork` at its mainnet default. `wallet_default_address()` now returns `Option<Address>` rather than `Option<String>`, removing a stringify-then-reparse round trip through `StrictAddress::from_str` in both the `list` and `send` handlers. `Send.target_address` is intentionally kept as a `String` because it accepts ETH (`0x...`) recipients, which `StrictAddress` rejects; `resolve_target_address` continues to handle the dispatch. `ValidateAddress.address` also stays a `String`, since its purpose is to validate arbitrary user input. Two clap-level regression tests guard against an accidental revert of the `StrictAddress` typing. Refs ChainSafe#6012
Summary of changes
Changes introduced in this pull request:
forest-cli.Reference issue to close (if applicable)
Closes#6006
Other information and links
Change checklist
Summary by CodeRabbit
Improvements
Documentation