Skip to content

fix(zetaclient): backport respect DisableTssBlockScan in Bitcoin observer#4599

Open
skosito wants to merge 1 commit into
release/zetaclient/v38from
respect-disable-tss-block-scan-in-btc-observer-v38
Open

fix(zetaclient): backport respect DisableTssBlockScan in Bitcoin observer#4599
skosito wants to merge 1 commit into
release/zetaclient/v38from
respect-disable-tss-block-scan-in-btc-observer-v38

Conversation

@skosito
Copy link
Copy Markdown
Member

@skosito skosito commented May 20, 2026

original PR #4597

How Has This Been Tested?

  • Tested CCTX in localnet
  • Tested in development environment
  • Go unit tests
  • Go integration tests
  • Tested via GitHub Actions

Note

Medium Risk
When DisableTssBlockScan is enabled, Bitcoin inbound deposits will no longer be observed/voted on (by design), so misconfiguration could halt deposit processing; changes are otherwise localized with added unit coverage.

Overview
Respects DisableTssBlockScan for Bitcoin inbound handling. The Bitcoin observer now returns early from both ObserveInbound block-range scanning and observeInboundTrackers processing when ChainParams.DisableTssBlockScan is true, emitting sampled info logs.

Adds unit tests asserting that with the flag enabled, neither block scanning nor inbound-tracker processing attempts any Bitcoin RPC calls and the methods exit cleanly.

Reviewed by Cursor Bugbot for commit 3b718ef. Configure here.

Greptile Summary

This PR ports the DisableTssBlockScan guard from the EVM observer to the Bitcoin observer, ensuring that when the flag is set both ObserveInbound and observeInboundTrackers return early without scanning or voting on inbound transactions.

  • inbound.go: guard is inserted after updateLastBlock (preserving block-height tracking) but before any scanning, matching the intent of the flag.
  • inbound_tracker.go: guard is inserted at the top of observeInboundTrackers, covering both external (ProcessInboundTrackers) and internal (ProcessInternalTrackers) tracker paths via the shared helper.
  • inbound_test.go: two new tests confirm the early-return behaviour by relying on testify mock's strict unexpected-call detection.

Confidence Score: 4/5

The change is a targeted, minimal flag-check insertion with no impact on outbound processing; safe to merge.

Both guard locations are correct and the logic is straightforward. The only gap is that the public callers ProcessInboundTrackers and ProcessInternalTrackers still perform preliminary network/state work before the guard is reached inside observeInboundTrackers, and neither is covered by a dedicated test. This is a minor quality concern rather than a functional defect.

zetaclient/chains/bitcoin/observer/inbound_test.go — the tests exercise observeInboundTrackers directly but do not cover the public ProcessInboundTrackers and ProcessInternalTrackers entry-points.

Important Files Changed

Filename Overview
zetaclient/chains/bitcoin/observer/inbound.go Adds an early-return guard for DisableTssBlockScan after updateLastBlock; consistent with existing EVM pattern
zetaclient/chains/bitcoin/observer/inbound_tracker.go Adds DisableTssBlockScan guard at the top of observeInboundTrackers; covers both external and internal tracker paths
zetaclient/chains/bitcoin/observer/inbound_test.go Adds two tests verifying early-return behaviour; relies on testify mock's strict-call detection but ProcessInboundTrackers/ProcessInternalTrackers callers are not covered

Sequence Diagram

sequenceDiagram
    participant Scheduler
    participant Observer

    Note over Scheduler,Observer: ObserveInbound path
    Scheduler->>Observer: ObserveInbound(ctx)
    Observer->>Observer: updateLastBlock(ctx)
    alt "DisableTssBlockScan == true"
        Observer-->>Scheduler: return nil (early exit)
    else "DisableTssBlockScan == false"
        Observer->>Observer: observeInboundInBlockRange(...)
        Observer-->>Scheduler: return nil
    end

    Note over Scheduler,Observer: ProcessInboundTrackers path
    Scheduler->>Observer: ProcessInboundTrackers(ctx)
    Observer->>Observer: GetInboundTrackers(ctx)
    Observer->>Observer: observeInboundTrackers(ctx, trackers, false)
    alt "DisableTssBlockScan == true"
        Observer-->>Scheduler: return nil (early exit)
    else "DisableTssBlockScan == false"
        Observer->>Observer: CheckReceiptAndPostVoteForBtcTxHash(...)
        Observer-->>Scheduler: return nil
    end

    Note over Scheduler,Observer: ProcessInternalTrackers path
    Scheduler->>Observer: ProcessInternalTrackers(ctx)
    Observer->>Observer: GetInboundInternalTrackers(ctx)
    Observer->>Observer: observeInboundTrackers(ctx, trackers, true)
    alt "DisableTssBlockScan == true"
        Observer-->>Scheduler: return nil (early exit)
    else "DisableTssBlockScan == false"
        Observer->>Observer: CheckReceiptAndPostVoteForBtcTxHash(...)
        Observer-->>Scheduler: return nil
    end
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
zetaclient/chains/bitcoin/observer/inbound_test.go:149-163
**Test does not cover public callers (`ProcessInboundTrackers` / `ProcessInternalTrackers`)**

The guard lives inside `observeInboundTrackers`, but `ProcessInboundTrackers` still calls `ob.ZetaRepo().GetInboundTrackers(ctx)` and `ProcessInternalTrackers` still calls `ob.GetInboundInternalTrackers` before reaching the guard. Those callers are the ones actually triggered by the scheduler, yet neither is covered by a test here. A test for each public entry-point would confirm the full intended behaviour (and would also catch any future guard-bypass regression if the guard is accidentally moved or removed in a refactor).

Reviews (1): Last reviewed commit: "fix(zetaclient): respect DisableTssBlock..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

* fix(zetaclient): respect DisableTssBlockScan in Bitcoin observer

* same fix in inbound tracker

* log

* changelog
@skosito skosito requested a review from a team as a code owner May 20, 2026 01:36
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Important

Review skipped

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

🗂️ Base branches to auto review (1)
  • develop

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 11f45b96-8997-4985-b9d6-bfdb210f5fba

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 respect-disable-tss-block-scan-in-btc-observer-v38

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 and usage tips.

@skosito skosito changed the title fix(zetaclient): respect DisableTssBlockScan in Bitcoin observer (#4597) fix(zetaclient): backport respect DisableTssBlockScan in Bitcoin observer May 20, 2026
@skosito skosito added the no-changelog Skip changelog CI check label May 20, 2026
Comment on lines +149 to +163
func Test_ObserveInbound_DisableTssBlockScan(t *testing.T) {
chain := chains.BitcoinMainnet
ob := newTestSuite(t, chain)

// flip the chain param to disable inbound scanning
chainParams := ob.ChainParams()
chainParams.DisableTssBlockScan = true
ob.SetChainParams(chainParams)

// ObserveInbound should return early without scanning any block.
// We intentionally do NOT mock GetBlockHash/GetBlockVerbose — if scanning
// were attempted, the mock client would fail the test on unexpected calls.
err := ob.ObserveInbound(ob.ctx)
require.NoError(t, err)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Test does not cover public callers (ProcessInboundTrackers / ProcessInternalTrackers)

The guard lives inside observeInboundTrackers, but ProcessInboundTrackers still calls ob.ZetaRepo().GetInboundTrackers(ctx) and ProcessInternalTrackers still calls ob.GetInboundInternalTrackers before reaching the guard. Those callers are the ones actually triggered by the scheduler, yet neither is covered by a test here. A test for each public entry-point would confirm the full intended behaviour (and would also catch any future guard-bypass regression if the guard is accidentally moved or removed in a refactor).

Prompt To Fix With AI
This is a comment left during a code review.
Path: zetaclient/chains/bitcoin/observer/inbound_test.go
Line: 149-163

Comment:
**Test does not cover public callers (`ProcessInboundTrackers` / `ProcessInternalTrackers`)**

The guard lives inside `observeInboundTrackers`, but `ProcessInboundTrackers` still calls `ob.ZetaRepo().GetInboundTrackers(ctx)` and `ProcessInternalTrackers` still calls `ob.GetInboundInternalTrackers` before reaching the guard. Those callers are the ones actually triggered by the scheduler, yet neither is covered by a test here. A test for each public entry-point would confirm the full intended behaviour (and would also catch any future guard-bypass regression if the guard is accidentally moved or removed in a refactor).

How can I resolve this? If you propose a fix, please make it concise.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Skip changelog CI check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants