Skip to content

refactor(node): remove sequencer support (and other refactors) - #3892

Open
rodrodros wants to merge 5 commits into
mainfrom
refactor-node
Open

refactor(node): remove sequencer support (and other refactors)#3892
rodrodros wants to merge 5 commits into
mainfrom
refactor-node

Conversation

@rodrodros

Copy link
Copy Markdown
Contributor

No description provided.

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @rodrodros's task in 8m 0s —— View job


Review: refactor(node): remove sequencer support

Read the full diff against the PR base (HEAD~4), plus the surrounding code in node/, db/remote/, clients/feeder/, pruner/ and sync/. go build ./... type-checks cleanly (link fails only because the Rust static libs aren't built in this sandbox) and go vet ./core/... ./node/... ./clients/feeder/... ./db/remote/... is clean.

The split is a real improvement — New goes from one 600-line branch-heavy function to a linear flow, and collapsing the sequencer/non-sequencer duplication removes a lot of divergence risk. Two things fixed along the way that are worth calling out because they weren't advertised:

  • NewReadinessHandlers(chain, syncReader, …) (node.go:307) closes a latent nil deref. A p2p non-feeder node set synchronizer = nil, and the old code passed that typed-nil *sync.Synchronizer into the sync.Reader interface — so /ready would panic in HighestBlockHeader() (s.highestBlockHeader.Load() on a nil receiver). It now gets &sync.NoopSynchronizer{}.
  • len(unverifiableRange) == 2 (block.go:134) is safer than != nil: a malformed 1-element custom range used to index [1] and panic.

I checked the two nil-listener paths introduced by makeFeederMetrics(cfg.Metrics) / makePrunerMetrics(cfg.Metrics) — both SelectiveListener types nil-check every callback, and feeder.NewClient's default listener is already &SelectiveListener{}, so those are behaviour-preserving. The VerifyBlockHash control-flow rewrite is also equivalent to the original (both return on the first fallback address when skipVerification).

Findings

Important

  • node/node.go:91remote.DB stores the ctx on the struct and uses it for every transaction (db/remote/db.go:60), so passing the signal-cancelled cmd.Context() means all remote-DB I/O fails after SIGINT. That includes the deferred WriteRunningEventFilter() in Run, which by construction runs after <-ctx.Done() — with --remote-db the running event filter is now lost on every shutdown. context.TODO() didn't have this problem. Fix this →
  • core/block.go:126%d applied to a *felt.Felt (which is fp.Element = [4]uint64) prints raw Montgomery limbs instead of the hash, and the same line uses %s for the other side of the comparison. go vet doesn't flag it because all fields are integers. Fix this →
  • Stale docs. docs/docs/sequencer.md (a whole page) and docs/docs/_config-options.md:145-148 still document --seq-enable, --seq-block-time, --seq-genesis-file and --seq-disable-fees. Those flags now either fail as unknown flags or hard-error at startup. The versioned_docs/ copies are correct as historical snapshots and should stay.

Nit

  • node/sequencer.go — 148 lines of purely commented-out code. Git history already preserves it, and this copy has already drifted from what was deleted (felt.NewFromUint64[felt.Felt](1234) vs. the real SetUint64(1337)) and references Config fields the PR removes.
  • clients/feeder/timeouts.go:162%d on time.Duration prints nanoseconds where %v printed 5s; this string reaches operators via the PUT /feeder/timeouts 400 response.
  • node/node.go:211-238 — the synchronizer is built and given the plugin, then discarded for p2p non-feeder nodes. Nothing leaks (sync.New allocates only), but deciding before constructing would read better.
  • node/node.go:221 — the GatewayURL == nil check moved behind the FeeTokenAddresses network call; cheap validation should stay ahead of I/O.
  • node/node.go:303"starting rpc servers" describes registration, not startup.
  • node/config.go:35 — the comment implies stale sequencer configs are caught, but only seq-enable is; the other three keys are silently ignored by viper's non-strict Unmarshal.

Details are in the 7 inline comments. Nothing here blocks merging.

· branch refactor-node

Comment thread core/block.go Outdated
Comment thread node/node.go
Comment thread clients/feeder/timeouts.go
Comment thread node/sequencer.go
Comment thread node/node.go
Comment thread node/node.go
Comment thread node/node.go Outdated
Comment thread node/config.go
- Remove sequencing support from the node for now
- Move the config file to its own folder
- Move the RPC servers logic to it's own script
- Move local databse to script
- Modified metrics with the option patter to reduce some ifs

chore: minor improvs

chore: improvements
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Claude finished @rodrodros's task in 6m 48s —— View job


Re-review after force-push

The branch was amended and force-pushed (same 4 commit subjects, new SHAs). I diffed the new head against origin/main, re-read node/, clients/feeder/, db/remote/ and core/block.go, and re-checked each finding from the previous round. go build ./... type-checks (link fails only because the Rust static libs aren't built in this sandbox) and go vet ./core/... ./node/... ./clients/feeder/... ./db/remote/... ./rpc/... is clean.

Fixed since last review

  • core/block.go:126%d%s on block.Receipts[i].TransactionHash. Both sides of the comparison now print as hashes.
  • clients/feeder/timeouts.go:162%d%s on time.Duration, so the PUT /feeder/timeouts 400 response reads 5s again rather than 5000000000.
  • node/node.go:303"starting rpc servers""building rpc servers".

Also re-verified as equivalent to the original: the VerifyBlockHash fallback loop (swapping the skipVerification / hash.Equal order can't change the outcome — either being true returns the same commitments), and makeFeederMetrics / makePrunerMetrics returning empty SelectiveListeners when --metrics is off.

Still open

Important

  • node/node.go:89 — the remote-DB context. remote.DB stores the ctx and uses it for every transaction (db/remote/db.go:60), so passing the signal-cancelled cmd.Context() means the deferred WriteRunningEventFilter() in Run — which by construction runs after <-ctx.Done() — always fails under --remote-db. This is the one item from last round with no reply; details in the inline comment. Fix this →

Nit

  • clients/feeder/timeouts.go:130-133 (new this round) — dropping the "" early-return removes the only guard that short-circuited before the values slicing. ParseTimeouts(" ") now falls through to return timeouts, false, nil with an empty slice, and makeTimeouts then indexes timeouts[0] → index out of range. Reachable via --gw-timeouts " " (panic inside node.New) and PUT /feeder/timeouts?timeouts=%20 (the empty-string check at line 189 doesn't catch a space). Pre-existing — the old code special-cased exactly "", not whitespace — but this PR is the one relaxing the guard, and the fix is a one-line if len(timeouts) == 0 at the end. The inline comment also notes that "" now yields dynamic 5s while getDefaultFixedTimeouts() yields fixed 5s from the same constant, which the doc comment glosses over.
  • docs/docs/sequencer.md — still a live page (orphaned from sidebars.js, but Docusaurus still builds and serves it) documenting --seq-enable, --seq-block-time, --seq-genesis-file, --seq-disable-fees, none of which exist after this PR. Correcting my previous round: docs/docs/_config-options.md is not a problem — it carries a "generated automatically" header and docs/package.json regenerates it via node generate-config.js on every docs build, so those four rows disappear on their own. Only the hand-written page needs attention. The versioned_docs/ copies are historical snapshots and should stay.

Acknowledged as author decisions, not re-raised: keeping node/sequencer.go, the GatewayURL check staying next to the gateway client, and deferring the p2p/synchronizer construction reorder to a follow-up.

Nothing here blocks merging.

· branch refactor-node

Comment thread clients/feeder/timeouts.go
Comment thread node/node.go
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.79433% with 88 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.69%. Comparing base (33a422d) to head (c257bec).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
node/node.go 63.94% 40 Missing and 13 partials ⚠️
node/l1.go 20.68% 22 Missing and 1 partial ⚠️
node/rpc.go 82.85% 3 Missing and 3 partials ⚠️
node/metrics.go 80.00% 3 Missing ⚠️
node/db.go 88.88% 1 Missing and 1 partial ⚠️
cmd/juno/juno.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3892      +/-   ##
==========================================
+ Coverage   75.26%   75.69%   +0.42%     
==========================================
  Files         443      445       +2     
  Lines       40058    39864     -194     
==========================================
+ Hits        30150    30174      +24     
+ Misses       7806     7598     -208     
+ Partials     2102     2092      -10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

* fix(feeder): timeouts don't crash on whitespace input

* tests(clients/feeder): more timeout cases

@infrmtcs infrmtcs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please feel free to ignore the comments if any of them is too nit!

Comment thread clients/feeder/feeder.go

currentTimeout := timeouts.GetCurrentTimeout()
if currentTimeout >= mediumGrowThreshold {
if currentTimeout >= 2*time.Minute {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think keeping the constant make it easier to see and change it, and the name, while not the best name possible, can give us some ideas about what it is, while 2*time.Minute doesn't auto translate to a meaningful reason.

Comment thread clients/feeder/timeouts.go
Comment thread node/node_test.go
DisableL1Verification: true,
SubmittedTransactionsCacheEntryTTL: time.Second,
}, "v0.1", logLevel)
_, err = node.New(t.Context(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I think t.Context() should be in its own line.

Comment thread node/config.go
// Sequencer support was removed and no CLI flag is registered for this
// key. It is still decoded from config files so that stale sequencer
// configs fail loudly in New instead of silently running a full node.
Sequencer bool `mapstructure:"seq-enable"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think instead of keeping this in the config, we can use MarkDeprecated instead (see "Deprecating a flag or its shorthand" in https://pkg.go.dev/github.com/spf13/pflag#section-readme).
We can also use MarkHidden to hide it from user.

Comment thread node/node.go
Comment on lines +411 to +413
const upgraderDelay = 5 * time.Minute
const githubAPIUrl = "https://api.github.com/repos/NethermindEth/juno/releases/latest"
const latestReleaseURL = "https://github.com/NethermindEth/juno/releases/latest"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we move the constants here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same idea of scoping them to where they are used. Global constants for for global usage. I believe is more tidy this way

Comment thread node/node.go
Comment on lines +391 to +396
if !node.cfg.DisableL1Verification {
// Due to mutually exclusive flag we can do the following.
if n.cfg.EthNode == "" {
return nil, fmt.Errorf("ethereum node address not found; Use --disable-l1-verification flag if L1 verification is not required")
if node.cfg.EthNode == "" {
return nil, fmt.Errorf("ethereum node address not set; " +
"Use --disable-l1-verification flag if L1 verification is not required",
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since we're touching this, I think we can use this instead:
https://pkg.go.dev/github.com/spf13/cobra#Command.MarkFlagsOneRequired

Comment thread node/node.go

// History pruning needs an L1-finalised cutoff to know which blocks are
// safe to drop. If no L1 client is given, new cutoffs cannot be set.
if cfg.Prune && cfg.DisableL1Verification {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since we're touching this, I think we should use this instead:
https://pkg.go.dev/github.com/spf13/cobra#Command.MarkFlagsMutuallyExclusive

Comment thread node/sequencer.go
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