fix(localnet): make [localnet].port actually take effect - #264
Conversation
Fixes logos-co#263. [localnet].port did nothing: two bugs canceled out. The sequencer binds the port given by its --port CLI flag (clap default 3040), never the sequencer_config.json 'port' key that prepare_sequencer_config patches — that key was written but never read for binding. start_localnet never passed --port, so the sequencer always bound 3040 regardless of the configured port. Separately, prepare_wallet_home seeds a fresh wallet home by copying the vendored LEZ debug wallet_config.json verbatim, which hardcodes sequencer_addr to http://127.0.0.1:3040. Because the key is present (not absent), load_wallet_runtime's fallback to default_sequencer_http_url_for_project never triggers, so the wallet always targeted 3040 too. Fixing only one side breaks the other: move the sequencer alone and deploy/wallet flows fail with connection refused; leave the sequencer alone and no wallet fix does anything. This does both: - start_localnet now passes --port <configured>, mirroring test_node. - prepare_wallet_home now overrides the seeded wallet's sequencer_addr with the project's configured address. Root cause verified against the pinned sequencer_service source (logos-execution-zone @ cf3639d8, the DEFAULT_LEZ pin) rather than assumed from the issue text alone; this also caught a stale doc comment on prepare_sequencer_config claiming --port isn't accepted, now corrected. tests/cli.rs's localnet_start_patches_config_and_uses_configured_port previously locked in the buggy behavior (asserted --port must NOT be passed); inverted to assert it is, with a fake sequencer that binds --port like the real one. Added two new state.rs regression tests for the wallet-seeding half.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
weboko
left a comment
There was a problem hiding this comment.
Verified the fix end-to-end on a non-default port, and confirmed the premise against the pinned LEZ source.
Premise checks (LEZ cf3639d8): sequencer/service/src/main.rs parses #[clap(short, long, default_value = "3040")] port and hands it to sequencer_service::run(config, port), which binds SocketAddr::from(([0,0,0,0], port)) in run_server. Nothing reads the config file's port key for RPC binding. Both halves of the PR description hold.
What I ran (fresh default-template project, [localnet].port = 3141, real sequencer + wallet):
setup→ seeded.scaffold/wallet/wallet_config.jsonwith"sequencer_addr": "http://127.0.0.1:3141", all fourinitial_accountsand the other keys intact.localnet start→sequencer_service …/sequencer_config.json --port 3141; 3141 open, 3040 closed.doctor→PASS | sequencer port 3141,PASS | wallet network config | wallet points to local sequencer,PASS | wallet usability. That row is a standing WARN onmasterat any non-default port, so this is the check becoming meaningful, exactly as #263 predicted.wallet topup→Network: local sequencer (http://127.0.0.1:3141);deploy hello_world→Succeeded: 1.- Full suite green: 587 lib / 186 CLI / 3 test-node / 5 doctests, including the inverted
localnet_start_patches_config_and_uses_configured_port.
The gap: projects that already ran setup are left broken, and the error sends them the wrong way
prepare_wallet_home only writes sequencer_addr when it is seeding a fresh wallet home — and prepare_wallet_home_does_not_touch_existing_wallet_config deliberately locks that in. But the population this bug affects is precisely the projects that already ran setup with [localnet].port != 3040. Today those work by accident (both halves wrong in the same direction). After this change the sequencer moves and the wallet does not, which is the regression #263 warned about — just relocated from "everyone" to "everyone who upgrades".
Reproduced on the same project by restoring the wallet config to the pre-PR on-disk state (sequencer_addr = http://127.0.0.1:3040) while localnet ran on 3141:
$ lgs deploy hello_world_with_move_function
error: cannot deploy programs: http://127.0.0.1:3040/: Connection Failed: Connection refused (os error 111)
sequencer appears unavailable at http://127.0.0.1:3040
Run `logos-scaffold localnet start`.
Another project's sequencer may already be running and may not match this project.
Localnet is running, and the advice is to start it again. doctor does say the real thing (WARN | wallet network config with a remediation naming the file and the value), but nothing in the failing command points there, so the natural next step is a loop of localnet start / localnet status that never mentions the port mismatch.
Either fix would close it:
- Detect and say so — in
load_wallet_runtime(or the deploy preflight), whensequencer_addris a loopback URL whose port disagrees with[localnet].port, replace the hint with that fact: "wallet is configured for 127.0.0.1:3040 but[localnet].portis 3141 — update.scaffold/wallet/wallet_config.jsonor runlgs doctor". Lowest risk, and keeps the PR's "don't silently rewrite a value the user can see" stance. - Repair on
setup— rewrite an existingsequencer_addrwhen it is loopback with a disagreeing port (leave any non-loopback address alone). Fixes it without the user reading anything, at the cost of the invariant the new test asserts.
I'd take (1); (2) alone would still leave anyone who never re-runs setup stuck. Whichever you pick, it seems worth a line in #263 about the upgrade path, since the issue explicitly framed "fix one and a previously-working project breaks" as the thing to avoid.
Minor: seeding now round-trips the config through serde_json, so the written file is re-indented (4→2 spaces) and its keys come out alphabetically reordered (initial_accounts first, sequencer_addr last). Harmless, but this is a file doctor tells people to hand-edit and that some will have diffed before; serde_json's preserve_order feature would keep it recognisable if that matters to you.
Generated by Claude Code
Fixes #263.
[localnet].portinscaffold.tomldid nothing — two bugs canceled out in opposite directions.Sequencer side: the pinned
sequencer_servicebinds the port given by its--portCLI flag (clap default3040) — confirmed by readingsequencer/service/src/main.rsandlib.rs::run()directly at the pinned SHA (logos-execution-zone@cf3639d8). It never reads thesequencer_config.jsonportkey thatprepare_sequencer_configpatches for this purpose.start_localnetnever passed--port, so the sequencer always bound3040regardless of the configured port. (test_nodealready does this correctly — a separate code path.)Wallet side:
prepare_wallet_homeseeds a fresh wallet home by copying the vendored LEZ debugwallet_config.jsonverbatim. That file hardcodessequencer_addr: http://127.0.0.1:3040. Since the key is present,load_wallet_runtime's fallback todefault_sequencer_http_url_for_project(which does follow[localnet].port) never triggers.As the issue notes, fixing only one side breaks the other — moving the sequencer without fixing the wallet breaks
deploywithConnection refused. This PR does both:start_localnetnow passes--port <configured>, mirroringtest_node's existing pattern.prepare_wallet_homenow takes the project's configured sequencer address and writes it into the freshly-seeded wallet config, instead of leaving the vendored3040default.prepare_sequencer_configthat incorrectly claimed the pinned sequencer doesn't accept--port.tests/cli.rs::localnet_start_patches_config_and_uses_configured_portpreviously locked in the old behavior (asserted--portmust not be passed, per the issue's own note); inverted here, with the fake sequencer now binding--portlike the real one. Added two regression tests for the wallet-seeding half instate.rs.[localnet].portis left at the default3040.