Skip to content

chore: additional low-risk code-quality follow-ups#4187

Open
piotr-roslaniec wants to merge 17 commits into
chore/code-quality-cleanupfrom
chore/code-quality-followups
Open

chore: additional low-risk code-quality follow-ups#4187
piotr-roslaniec wants to merge 17 commits into
chore/code-quality-cleanupfrom
chore/code-quality-followups

Conversation

@piotr-roslaniec

Copy link
Copy Markdown
Collaborator

Summary

A second, focused batch of low-risk code-quality improvements across the node,
continuing the cleanup in #4185. The changes reduce duplication, remove dead
code, add missing test coverage, and fix two latent correctness issues found
while cleaning up. No feature or protocol behavior changes beyond the two fixes
noted below.

Stacked on #4185 — this PR targets chore/code-quality-cleanup and should be
merged after #4185. GitHub will retarget it to main automatically once #4185
merges.

Fixes (behavior)

  • fix(beacon): abort protocol setup when channel filter cannot be set
    JoinDKGIfEligible and GenerateRelayEntry previously logged and then
    continued when SetFilter failed, running the protocol on an unfiltered
    broadcast channel that would accept messages from operators outside the
    group. Both now fail closed and abort before launching the protocol
    goroutines.
  • fix(libp2p): keep SetMetricsRecorder param anonymous for cmd wiring
    cmd.start wires the performance metrics recorder into the libp2p provider
    via a structural assertion against an anonymous interface. Naming that
    interface would silently break the assertion at runtime (metrics stop being
    recorded) with no build or test failure. A guard test now pins the contract.

Refactors (dedup / clarity)

  • refactor(spv): dedupe unproven-transaction search and drop dead metrics
    singleton
    — the four getUnproven*Transactions functions shared identical
    search scaffolding, now extracted into unprovenSearchStartBlock and
    collectUnprovenWalletTransactions. Also removes an unwired global metrics
    singleton.
  • refactor(tbtcpg): extract shared capped-fee estimation — moving-funds and
    moved-funds-sweep fee estimation shared the same size/fee/cap logic, now in
    estimateCappedFee.
  • refactor(libp2p): name the repeated metrics-recorder interface — replaces
    a repeated inline interface literal with a named type at the sites that can
    safely use it (see the fix above for the one that must stay anonymous).
  • refactor(beacon): extract shared broadcast-channel filter helper — the
    set-filter-and-abort logic (see the beacon fix) lived in two places; now in
    setBroadcastChannelFilter.
  • refactor(gjkr): drop test-only receivedQualifiedSharesT field — a member
    field that was only ever read by tests; coverage preserved by returning the
    value through the existing test helper.

Tests

  • test(ethereum): cover timestamp-based block search — new unit tests for
    closerBlock / GetBlockNumberByTimestamp, previously only exercised via
    integration.

  • test(spv): cover shared unproven-transaction search helper — pins the
    stop-at-first-match branch (both directions) and the error paths of the
    extracted helper.

  • test(beacon): cover broadcast-channel filter abort path — asserts the
    fail-closed contract from the beacon fix.

  • test(tbtc): synchronize follower routine instead of sleeping — replaces a
    time.Sleep(1s) in a coordination test with deterministic synchronization.

  • style: use idiomatic zero-value and any declarations — minor, mechanical.

Verification

  • go build ./... and go vet ./... clean.
  • Full test suites pass for every touched package: pkg/beacon/... (incl. the
    DKG integration test), pkg/maintainer/spv, pkg/tbtc, pkg/tbtcpg,
    pkg/net/libp2p, pkg/chain/ethereum, pkg/bitcoin/electrum.

- declare loop index with var i int instead of var i = 0 in chain.Addresses.String
- use the any alias instead of interface{} for the requestWithRetry type parameter
Add non-integration unit tests for GetBlockNumberByTimestamp and closerBlock,
which previously had coverage only under a skippable integration test. The
tests use a lightweight in-memory client to exercise the backward/forward
search loops and the closer-block tie-breaking.
The three-method metrics-recorder interface was declared inline in many
places across the package. Introduce a named fullMetricsRecorder interface
(MetricsRecorder plus SetGauge) and use it at those sites. The transport
keeps its narrower two-method MetricsRecorder contract.
EstimateMovingFundsFee and EstimateMovedFundsSweepFee shared an identical
virtual-size, fee-estimate, and cap-check block. Extract it into
estimateCappedFee, parameterized by the size estimator, the cap, and the
fee-too-high error to return.
…cs singleton

- extract unprovenSearchStartBlock and collectUnprovenWalletTransactions,
  shared by the four getUnproven*Transactions functions
- remove the package-level global metrics recorder and its setter/getter,
  which were never wired in production and always resolved to nil; the proof
  submission functions retain their metricsRecorder parameter as the DI seam
JoinDKGIfEligible and GenerateRelayEntry logged a SetFilter failure and then
launched protocol goroutines on an unfiltered broadcast channel, accepting
messages from operators outside the selected group. Abort on the failure
instead, matching the fail-closed behavior already used by the tbtc node.
The receivedQualifiedSharesT (t_ji) map on the member struct was written and
deleted on the production path but never read there; only tests consumed it.
Remove it from the struct and keep only receivedQualifiedSharesS (s_ji), which
is the actual reconstruction state. The share-count assertions now rely on the
S map (populated identically), and the accusation tests obtain the t_ji shares
from a value returned by the group-initialization helper.
The follower-routine coordination test slept a fixed second hoping the
receiver had registered its broadcast channel handler before the sender
started publishing. Wrap the follower channel so the sender waits for the
actual Recv registration, removing the timing assumption.
cmd.start wires the performance metrics recorder into the provider via a
structural type assertion against an anonymous interface. Naming that
parameter fullMetricsRecorder made the assertion no longer match the provider
(a defined type differs from an identical anonymous interface), so metrics
were silently no longer wired. Restore the anonymous parameter and add a test
that pins this wiring contract.
Directly exercise collectUnprovenWalletTransactions, pinning the
stop-at-first-match branch in both directions and the chain and
predicate error paths that were previously only reached indirectly.
Both JoinDKGIfEligible and GenerateRelayEntry installed the membership
filter and aborted on failure with identical logic. Extract it into
setBroadcastChannelFilter so the fail-closed contract lives in one place
and can be exercised directly.
Assert setBroadcastChannelFilter surfaces the SetFilter error so callers
abort instead of proceeding on an unfiltered channel that would accept
messages from operators outside the group.
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 291cbec5-c68b-408f-b327-35ce672647f9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/code-quality-followups

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

unprovenSearchStartBlock returned currentBlock - historyDepth without
guarding the subtraction. On short chains where historyDepth exceeds the
current tip the unsigned subtraction wraps to a near-maximum block number,
silently changing the search range. Clamp to the genesis block instead.

This preserves behavior on mainnet, where the tip always dwarfs the
configured history depth.
The existing timestamp-search table uses a 12s block spacing, below the
13s averageBlockTime the algorithm assumes, so the initial backward jump
always lands at or after the target and the forward-walk branch never
runs. Add a case with 15s spacing so the backward jump overshoots below
the target and the forward loop is exercised.
Replace the hand-rolled blockOutOfRangeError struct with a plain
errors.New sentinel; it was only ever used as an opaque marker error.
The old comment block described the pre-refactor behavior (storing t_ji
on the member) that no longer holds, named the wrong function, and
carried a typo. Keep only the accurate block.
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.

1 participant