Skip to content

feat(go): add testnet4 mapping and harden runtime integration behavior - #4002

Merged
lionakhnazarov merged 7 commits into
mainfrom
stack/testnet4-04-go-testnet4-runtime
Jun 9, 2026
Merged

feat(go): add testnet4 mapping and harden runtime integration behavior#4002
lionakhnazarov merged 7 commits into
mainfrom
stack/testnet4-04-go-testnet4-runtime

Conversation

@lionakhnazarov

@lionakhnazarov lionakhnazarov commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Stack Context

This is PR 4/4 in the reorganization stack.
Base: #4001 (stack/testnet4-03-deployment-artifacts)

What Changed

1) CLI/config wiring for Testnet4

  • CLI flags/start flow updates:
    • cmd/flags.go, cmd/flags_test.go, cmd/start.go
  • Added embedded Electrum URL set for testnet4:
    • config/_electrum_urls/testnet4
  • Config/network mapping updates and tests:
    • config/network/network.go
    • config/config_test.go
    • config/electrum_test.go
    • config/contracts.go

2) Bitcoin/Electrum behavior and tests

  • Network type/string handling and electrum client behavior updates:
    • pkg/bitcoin/bitcoin.go
    • pkg/bitcoin/electrum/electrum.go
  • Integration/unit test adjustments for reliability and expected behavior:
    • pkg/bitcoin/electrum/electrum_integration_test.go
    • pkg/bitcoin/electrum/electrum_test.go

3) Ethereum chain integration + TBTC wiring

  • Chain adapter updates including DKG validator support and integration behavior:
    • pkg/chain/ethereum/bitcoin_difficulty.go
    • pkg/chain/ethereum/ecdsa_dkg_validator_chain.go (new)
    • pkg/chain/ethereum/ethereum.go
    • pkg/chain/ethereum/ethereum_integration_test.go
    • pkg/chain/ethereum/tbtc.go

4) Runtime reliability and maintainer logic

  • Local block counter/watcher reliability update:
    • pkg/chain/local_v1/blockcounter.go
  • DKG test helper adjustment:
    • pkg/internal/dkgtest/dkgtest.go
  • Bitcoin difficulty maintainer behavior + tests/config/errors:
    • pkg/maintainer/btcdiff/bitcoin_difficulty.go
    • pkg/maintainer/btcdiff/bitcoin_difficulty_test.go
    • pkg/maintainer/btcdiff/config.go
    • pkg/maintainer/btcdiff/errors.go (new)

5) TBTC logic/tests and integration test config updates

  • TBTC behavior/tests:
    • pkg/tbtc/inactivity.go
    • pkg/tbtc/inactivity_test.go
    • pkg/tbtc/tbtc.go
    • pkg/tbtc/coordination_test.go
  • TBTC PG test marshaling helper:
    • pkg/tbtcpg/internal/test/marshaling.go
  • Updated test config fixtures:
    • test/config.json, test/config.toml, test/config.yaml

Test Plan

  • go test ./config/... ./pkg/bitcoin/...
  • go test ./pkg/maintainer/btcdiff/... ./pkg/tbtc/...
  • go test ./pkg/chain/ethereum/...

Summary by CodeRabbit

  • New Features

    • Bitcoin Testnet4 support with a default Electrum endpoint.
    • CLI flag to idle instead of failing on certain preflight Bitcoin checks.
    • Option to fetch TBTC wallet sizing from an on-chain validator when available.
  • Improvements

    • More robust fee estimation with multiple fallback targets.
    • Improved blockchain interaction stability (transaction confirmation waits, retries, and lighter integration test handling).
    • Better maintainer and claim submission resilience.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 919eccb4-81f6-4484-a287-084b7b411ea5

📥 Commits

Reviewing files that changed from the base of the PR and between 2d040dc and 1f7c905.

📒 Files selected for processing (2)
  • pkg/chain/ethereum/bitcoin_difficulty.go
  • pkg/chain/ethereum/bitcoin_difficulty_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/chain/ethereum/bitcoin_difficulty.go

📝 Walkthrough

Walkthrough

Adds Bitcoin Testnet4 and Electrum network plumbing; implements ordered Electrum fee fallback and network-gated low-fee fallback; adds maintainer preflight verification with IdleOnPreflightFailure flag; waits for retarget transactions to be mined/confirmed; reads TBTC group parameters from an optional on-chain validator; and improves watcher lifecycle and multiple tests.

Changes

Bitcoin testnet4 and maintainer improvements

Layer / File(s) Summary
Bitcoin testnet4 network support
pkg/bitcoin/bitcoin.go, config/network/network.go, config/_electrum_urls/testnet4, config/electrum_test.go
Adds Testnet4 network constant, maps client Testnet to Testnet4, adds default Electrum URL for testnet4 and updates related tests.
Electrum client config and integration tests
pkg/bitcoin/electrum/config.go, pkg/bitcoin/electrum/electrum_integration_test.go, pkg/bitcoin/electrum/electrum_test.go
Adds Network field to electrum.Config, propagates resolved network into integration configs, broadens expected error variants, and hardens/skips flaky integration assertions.
Electrum fee estimation with fallback confirmation targets
pkg/bitcoin/electrum/electrum.go, pkg/bitcoin/electrum/electrum_test.go
Replaces single-call fee estimate with ordered/deduplicated fallback-target attempts, per-request GetFee helper with timeout/reconnect/mutex, oracle-failure detection, and final fallback/result logic; adds unit tests.
Bitcoin difficulty preflight validation with idle-on-failure
pkg/maintainer/btcdiff/config.go, pkg/maintainer/btcdiff/errors.go, pkg/maintainer/btcdiff/bitcoin_difficulty.go, pkg/maintainer/btcdiff/bitcoin_difficulty_test.go, cmd/flags.go, cmd/flags_test.go, test/config.*
Adds IdleOnPreflightFailure config and CLI flag, introduces ErrUniformPreRetargetDifficulty, verifies uniform pre-retarget nBits (accept DIFF1/min), and supports idle-or-fail behavior with tests for rejection, idle skip, and min-difficulty acceptance.
Retarget transaction mining/confirmation waits
pkg/chain/ethereum/bitcoin_difficulty.go
Adds waitDeployBackendTransactionMined and waitForBlockHeightCtx to wait for bind.WaitMined receipt success and additional L1 confirmations; updates Retarget and RetargetWithRefund to wait.
On-chain EcdsaDkgValidator group parameter discovery
pkg/chain/ethereum/ecdsa_dkg_validator_chain.go, pkg/chain/ethereum/tbtc.go, config/contracts.go
Embeds minimal ABI, implements eth_call readers for group constants with validation/limits, wires optional validator address alias, and exposes EcdsaWalletGroupParametersFromChain.
TBTC Initialize network-aware defaults and on-chain override
pkg/tbtc/tbtc.go, cmd/start.go
Initialize gains ethereumNetwork parameter, uses network-based defaultGroupParameters, attempts on-chain override, and logs/apply non-nil results; startup passes network.
Watcher lifecycle, DKG sync, and local blockcounter changes
pkg/chain/local_v1/blockcounter.go, pkg/internal/dkgtest/dkgtest.go, pkg/chain/ethereum/ethereum.go, pkg/chain/ethereum/ethereum_integration_test.go
Increases watcher buffer, moves cleanup into tick-time filtering and safe closes, serializes DKG test failure slice appends with a mutex, uses latest header for current block, and skips transient rate-limit errors in integration tests.
Coordination and inactivity tests and fixes
pkg/tbtc/coordination_test.go, pkg/tbtc/inactivity.go, pkg/tbtc/inactivity_test.go
Deterministic fixed block emission for coordination tests, SubmitClaim suppresses errors when nonce advanced by another member, adds stale-nonce test and fixes an error-var bug.
Misc config/flags/tests wiring
config/contracts.go, cmd/flags.go, cmd/flags_test.go, config/config_test.go, test/config.*
Adds contract alias for validator, registers bitcoinDifficulty.idleOnPreflightFailure CLI flag, updates config read tests, and updates test fixture configs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Suggested reviewers

  • piotr-roslaniec

Poem

🐰 I nibbled code where tests ran wild,

I steadied Testnet4 and made the flows mild,
Electrum now tries backups, gentle and wise,
Preflight idles when mismatch takes us by surprise,
On-chain sizes and mined waits — a tidy prize.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: introducing Testnet4 support and hardening runtime integration behavior across multiple modules.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch stack/testnet4-04-go-testnet4-runtime

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

@piotr-roslaniec
piotr-roslaniec force-pushed the stack/testnet4-04-go-testnet4-runtime branch from 754346d to dc687c9 Compare June 4, 2026 13:04
@piotr-roslaniec
piotr-roslaniec force-pushed the stack/testnet4-03-deployment-artifacts branch from 9ade31f to 5b40e26 Compare June 4, 2026 13:04
lionakhnazarov added a commit that referenced this pull request Jun 4, 2026
## Stack Context
Follow-up to #4002 (`stack/testnet4-04-go-testnet4-runtime`).
Base: `stack/testnet4-04-go-testnet4-runtime`

Addresses three runtime/operability issues surfaced during review of
#4002.

## What's in this PR

### 1) Bound the synchronous retarget wait —
`pkg/chain/ethereum/bitcoin_difficulty.go`
`waitDeployBackendTransactionMined` previously called
`bind.WaitMined(context.Background(), …)` with no timeout, then
`BlockCounter.WaitForBlockHeight` (which has no context parameter). A
stalled RPC or chain that stopped producing blocks would hang the
maintainer indefinitely on every `Retarget` / `RetargetWithRefund` call
— including on mainnet.

Both waits are now bounded under a shared 10-minute deadline. A small
`waitForBlockHeightCtx` shim adapts the context-less `BlockCounter`
interface, with a regression test verifying it returns
`context.DeadlineExceeded` when the counter blocks forever.

### 2) Warn loudly about Sepolia DKG fragility — `pkg/tbtc/tbtc.go`,
`pkg/chain/ethereum/tbtc.go`
The Sepolia/Developer `defaultGroupParameters` returns `{GroupSize:3,
GroupQuorum:3, HonestThreshold:2}`. Quorum equals size — a single
offline operator prevents DKG progress.

- Elevated the existing `Infof` to `Warnf` and spelled out the
operational consequence.
- Added a `Warnf` in `pkg/chain/ethereum/tbtc.go` where the
`EcdsaDkgValidator` `ErrAddressNotConfigured` branch previously fell
through silently. Operators now see at startup whether group sizing is
coming from on-chain values or compile-time defaults.

No sizing values are changed.

### 3) Document the testnet3 → testnet4 wiring as breaking
No code change in this PR; the startup banner at `config/config.go:101`
already prints the resolved Bitcoin network. Operator-facing note is
captured here and should be folded into release notes when #4002 lands.

After #4002 lands, `network.Type=Testnet` (Sepolia) resolves to
`bitcoin.Testnet4` rather than `bitcoin.Testnet` (testnet3). Existing
Sepolia operators will switch both the embedded Electrum URL set and the
Bitcoin network on upgrade. Pin to a pre-#4002 build to remain on
testnet3.

## Test Plan
- [x] `go build ./...`
- [x] `go vet ./pkg/chain/ethereum/... ./pkg/tbtc/...`
- [x] `go test ./pkg/chain/ethereum/...`
- [x] `go test ./pkg/tbtc/`
- [x] New regression: `TestWaitForBlockHeightCtx_DeadlineExceeded`,
`TestWaitForBlockHeightCtx_ReturnsImmediatelyOnSuccess`
@lionakhnazarov
lionakhnazarov force-pushed the stack/testnet4-03-deployment-artifacts branch from 3b156d8 to 979333c Compare June 5, 2026 11:33
lionakhnazarov added a commit that referenced this pull request Jun 6, 2026
…#4019)

## Problem

PR #4002 added an Electrum fee-estimate fallback: when
`blockchain.estimatefee` returns no estimate for any confirmation target
(common on quiet testnet4 mempools, which answer `-32603` for every
target), `EstimateSatPerVByteFee` returns a hardcoded `2` sat/vByte
instead of an error.

That fallback is network-blind. Before, an oracle failure returned an
error and no transaction was broadcast on a guessed feerate (fail-safe).
After, the same failure yields a fixed `2` sat/vByte that flows into the
production tBTC proposal fee paths (`tbtcpg/deposit_sweep.go`,
`redemptions.go`, `moving_funds.go`, `moved_funds_sweep.go`) on mainnet
as well, with no minimum-feerate floor in
`TransactionFeeEstimator.EstimateFee`. On mainnet a `2` sat/vByte
transaction can be left unconfirmable under congestion, or evicted if
the dynamic mempool minimum feerate rises above it — stalling sweeps and
redemptions (delayed mints / undelivered BTC). The funds are not lost,
but operations can get stuck.

## Solution

Gate the fallback to networks where an underpriced transaction is
economically harmless — `testnet`, `testnet4`, `regtest`. On `mainnet`,
and on any unset or unknown network, the oracle failure is surfaced as
an error so callers do not broadcast at a guessed feerate (fail-closed
default).

- A new `electrum.Config.Network` field carries the resolved Bitcoin
network into the connection. It is set from the client configuration in
`config.resolveElectrum`, tagged `mapstructure:"-"`, and assigned after
config unmarshal — so a config-file key cannot re-enable the fallback on
mainnet.
- The fallback decision is factored into pure helpers
(`feeFallbackResult` and `lowFeeFallbackAllowed`) so it can be tested
deterministically without a live Electrum client.
- testnet4's existing graceful degradation is preserved; only mainnet
(and unknown-network) behavior changes — back to the pre-#4002
fail-safe.

## Tests

- New unit test `TestFeeFallbackResult` covers the decision per network:
mainnet and unknown fail safe with an error; testnet/testnet4/regtest
use the fallback; transport-level failures always error.
- `config.TestResolveElectrum` now asserts the resolved network is
propagated into the Electrum config.
- The Electrum integration test configs carry their network so the
integration path exercises the gate rather than defaulting to `Unknown`.
- Local CI is green: `gofmt -l`, `go vet`, `go build ./...`, `go test`
(changed packages), `go vet -tags=integration` (compile), Staticcheck
2025.1.1, and gosec (0 issues).

## Notes

This is a follow-up to the review of #4002 and is based on its head
branch (`stack/testnet4-04-go-testnet4-runtime`), so the diff is scoped
to this fix.
lrsaturnino
lrsaturnino previously approved these changes Jun 6, 2026

@lrsaturnino lrsaturnino left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@lionakhnazarov
lionakhnazarov force-pushed the stack/testnet4-03-deployment-artifacts branch from 979333c to 0e373f5 Compare June 8, 2026 11:33
lionakhnazarov added a commit that referenced this pull request Jun 9, 2026
…lows (#4000)

## Stack Context
This is **PR 2/4** in the reorganization stack.
Base: #3999 (`stack/testnet4-01-ci-yarn`)
Next: #4001

## What Changed
### 1) ECDSA deploy/runtime logic
- Contract-level adjustments:
  - `solidity/ecdsa/contracts/WalletRegistry.sol`
- Deploy script updates for deployment flow and account/approval
behavior:
  - `solidity/ecdsa/deploy/00_resolve_reimbursement_pool.ts`
  - `solidity/ecdsa/deploy/00_resolve_token_staking.ts`
  - `solidity/ecdsa/deploy/01_deploy_ecdsa_sortition_pool.ts`
  - `solidity/ecdsa/deploy/02_deploy_dkg_validator.ts`
  - `solidity/ecdsa/deploy/03_deploy_wallet_registry.ts`
  - `solidity/ecdsa/deploy/07_approve_wallet_registry.ts`
  - `solidity/ecdsa/deploy/09_deploy_wallet_registry_governance.ts`
- Added verification helper:
  - `solidity/ecdsa/deploy/etherscanVerification.ts`
- Hardhat runtime/config updates:
  - `solidity/ecdsa/hardhat.config.ts`
- Wallet owner initialization logic update:
  - `solidity/ecdsa/tasks/initialize-wallet-owner.ts`

### 2) ECDSA test/fixture/type updates
- Tests:
  - `solidity/ecdsa/test/WalletRegistry.Authorization.test.ts`
  - `solidity/ecdsa/test/WalletRegistry.CustomErrors.test.ts`
  - `solidity/ecdsa/test/WalletRegistry.Rewards.test.ts`
  - `solidity/ecdsa/test/WalletRegistry.Slashing.test.ts`
  - `solidity/ecdsa/test/WalletRegistry.Upgrade.test.ts`
  - `solidity/ecdsa/test/WalletRegistry.WalletCreation.test.ts`
  - `solidity/ecdsa/test/WalletRegistryGovernance.test.ts`
- Fixtures/utilities:
  - `solidity/ecdsa/test/fixtures/index.ts`
  - `solidity/ecdsa/test/utils/operators.ts`
- Added types:
  - `solidity/ecdsa/types/TokenStaking.extensions.d.ts`
  - `solidity/ecdsa/types/chai.d.ts`

### 3) Random beacon deploy/config/test alignment
- Deploy/config:
-
`solidity/random-beacon/deploy/05_approve_random_beacon_in_token_staking.ts`
  - `solidity/random-beacon/hardhat.config.ts`
- Tests/fixtures/utilities:
  - `solidity/random-beacon/test/RandomBeacon.Authorization.test.ts`
  - `solidity/random-beacon/test/RandomBeacon.Callback.test.ts`
  - `solidity/random-beacon/test/RandomBeacon.GroupCreation.test.ts`
  - `solidity/random-beacon/test/RandomBeacon.Relay.test.ts`
  - `solidity/random-beacon/test/RandomBeacon.Rewards.test.ts`
  - `solidity/random-beacon/test/system/e2e.test.ts`
  - `solidity/random-beacon/test/fixtures/index.ts`
  - `solidity/random-beacon/test/utils/operators.ts`
- Added types:
  - `solidity/random-beacon/types/TokenStaking.extensions.d.ts`

### 4) Embedded export deploy scripts for ECDSA external random-beacon
export
- Added scripts under:
- `solidity/ecdsa/external/random-beacon-export/deploy/01_*.js ...
09_*.js`

## Out of Scope
- Generated `deployments/sepolia` JSON snapshots (handled in #4001).
- Go/Testnet4 runtime changes (handled in #4002).

## Test Plan
- [ ] `cd solidity/ecdsa && yarn test`
- [ ] `cd solidity/random-beacon && yarn test`
- [ ] Spot-check deployment flows for expected skip/redeploy behavior.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added deployment verification helper wrappers for improved error
resilience.
* Introduced random beacon deployment automation with network-aware
initialization.
* Enhanced wallet governance initialization with additional consistency
validation.

* **Bug Fixes**
* Made deployment scripts network-aware to gracefully skip unavailable
contracts on local development networks.
* Added ABI-level feature detection to prevent failures when calling
unsupported contract methods.
* Improved deployment transaction handling with environment-based gas
price configuration.

* **Documentation**
* Updated contract documentation with expanded guidance on beneficiary
address resolution behavior.
  * Added deployment guidelines for vendored external contracts.

* **Tests**
* Updated test suites to use allowlist-based authorization by default
with legacy fallback support.
* Enhanced test utilities with improved compatibility helpers for legacy
contract interactions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@lionakhnazarov
lionakhnazarov force-pushed the stack/testnet4-03-deployment-artifacts branch from 0e373f5 to 219a732 Compare June 9, 2026 07:21
lionakhnazarov added a commit that referenced this pull request Jun 9, 2026
## Stack Context
This is **PR 3/4** in the reorganization stack.
Base: #4000 (`stack/testnet4-02-solidity-logic`)
Next: #4002

## What Changed
### 1) Added generated Sepolia deployment snapshots (ECDSA)
- Added full deployment artifacts under:
  - `solidity/ecdsa/deployments/sepolia/.chainId`
  - `solidity/ecdsa/deployments/sepolia/.migrations.json`
- `solidity/ecdsa/deployments/sepolia/*.json` (Allowlist, BLS, Beacon*,
Ecdsa*, RandomBeacon*, ReimbursementPool, T, TokenStaking,
WalletRegistry*)

### 2) Added generated Sepolia deployment snapshots (Random Beacon)
- Added full deployment artifacts under:
  - `solidity/random-beacon/deployments/sepolia/.chainId`
- `solidity/random-beacon/deployments/sepolia/*.json` (BLS, Beacon*,
RandomBeacon*, ReimbursementPool, T, TokenStaking)

### 3) Repo hygiene
- Removed legacy export artifact: `solidity/random-beacon/export.json`
- Gitignored Yarn Berry runtime state (`.yarn/install-state.gz`) in
`solidity/random-beacon` to match the ecdsa package.
- Gitignored `gasReporterOutput.json` in both `solidity/ecdsa` and
`solidity/random-beacon` (regenerated on every test run, not a source
artifact).

## Why This Slice Exists
This PR intentionally isolates generated/deployment snapshot churn so
logic review stays focused in adjacent PRs.

## Out of Scope
- Deploy/runtime logic changes.
- Go runtime/network mapping changes.

## Test Plan
- [ ] Regenerated artifact set matches expected deployment outputs.
- [ ] No non-generated behavior changes are introduced in this PR.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Sepolia testnet support with full deployment artifacts and
allowlist-enabled registry flows.

* **Improvements**
* Stronger deployment safety checks and clearer errors for missing
upstream contracts.
  * Verification now fails on mainnet but is tolerant on non-mainnet.
* CI/dev housekeeping: ignore gas reporter outputs and set Sepolia chain
IDs.

* **Documentation**
  * Expanded guidance for vendored deploy script regeneration and usage.

* **Tests**
  * Test fixtures updated to require explicit allowlist mode.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Base automatically changed from stack/testnet4-03-deployment-artifacts to main June 9, 2026 12:28
@lionakhnazarov
lionakhnazarov dismissed lrsaturnino’s stale review June 9, 2026 12:28

The base branch was changed.

@lionakhnazarov
lionakhnazarov force-pushed the stack/testnet4-04-go-testnet4-runtime branch from ffc61eb to cd7ee40 Compare June 9, 2026 12:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/bitcoin/electrum/electrum.go`:
- Around line 1064-1073: The current block returns the fallback fee whenever
sawFeeOracleFailure is true, which masks transport/auth and other non-oracle
failures; change the logic in the function that computes fee estimates so that
you only apply defaultFallbackSatPerVByteWhenEstimateFails when there were
exclusively oracle "no estimate" responses (sawFeeOracleFailure == true AND no
transport/auth or other failures), otherwise propagate lastErr (or return an
explicit error). Concretely, add a boolean (e.g., sawNonOracleFailure) or
inspect lastErr/error types (using errors.Is or by checking known transport/auth
error values) alongside sawFeeOracleFailure, update the conditional around
logger.Warnf/return so the fallback path runs only when no non-oracle failures
were observed, and ensure logger.Warnf still includes lastErr when returning the
fallback and return lastErr when non-oracle failures occurred. Use the existing
symbols sawFeeOracleFailure, lastErr,
defaultFallbackSatPerVByteWhenEstimateFails, and logger.Warnf to locate and
modify the code.

In `@pkg/chain/ethereum/bitcoin_difficulty.go`:
- Around line 141-159: The current waitDeployBackendTransactionMined uses
bind.WaitMined(context.Background(), bdc.client, tx) which can block forever if
the returned tx is replaced; change it to use a bounded, replacement-aware wait:
create a context with a reasonable timeout/deadline and use the mining-waiter
API that the contract binding uses (e.g., the MiningWaiter/ForceMining return
path) or poll by sender+nonce/block number instead of waiting for the original
tx hash; specifically, replace the bind.WaitMined call to (1) derive/capture the
tx sender and nonce from the original tx, (2) create ctx, cancel :=
context.WithTimeout(...) and defer cancel, and (3) poll for a receipt via
bdc.client.TransactionReceipt(ctx, hash) in a loop that also checks for
replacement by inspecting the pending tx for the same nonce or by asking the
miner/waiter for the final mined tx, returning when a receipt for the final
mined tx is found or when ctx times out; keep the existing receipt.Status and
blockCounter handling but ensure errors include context timeout vs replacement
cases.

In `@pkg/chain/ethereum/ecdsa_dkg_validator_chain.go`:
- Around line 122-135: Add an explicit consistency check that the
validator-supplied group threshold does not exceed the active threshold: after
computing groupQuorum (activeThreshold) and honestThreshold (groupThreshold) add
a guard like "if honestThreshold > groupQuorum { return nil,
fmt.Errorf(\"groupThreshold/honestThreshold [%d] exceeds
activeThreshold/groupQuorum [%d]\", honestThreshold, groupQuorum) }" so
validators cannot submit groupThreshold > activeThreshold; reference the
existing variables groupQuorum and honestThreshold to locate where to insert
this check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 968743ff-8ca1-4ad3-9912-6b5300d0a22f

📥 Commits

Reviewing files that changed from the base of the PR and between df8067a and cd7ee40.

📒 Files selected for processing (30)
  • cmd/flags.go
  • cmd/flags_test.go
  • cmd/start.go
  • config/_electrum_urls/testnet4
  • config/config_test.go
  • config/contracts.go
  • config/electrum_test.go
  • config/network/network.go
  • pkg/bitcoin/bitcoin.go
  • pkg/bitcoin/electrum/electrum.go
  • pkg/bitcoin/electrum/electrum_integration_test.go
  • pkg/bitcoin/electrum/electrum_test.go
  • pkg/chain/ethereum/bitcoin_difficulty.go
  • pkg/chain/ethereum/ecdsa_dkg_validator_chain.go
  • pkg/chain/ethereum/ethereum.go
  • pkg/chain/ethereum/ethereum_integration_test.go
  • pkg/chain/ethereum/tbtc.go
  • pkg/chain/local_v1/blockcounter.go
  • pkg/internal/dkgtest/dkgtest.go
  • pkg/maintainer/btcdiff/bitcoin_difficulty.go
  • pkg/maintainer/btcdiff/bitcoin_difficulty_test.go
  • pkg/maintainer/btcdiff/config.go
  • pkg/maintainer/btcdiff/errors.go
  • pkg/tbtc/coordination_test.go
  • pkg/tbtc/inactivity.go
  • pkg/tbtc/inactivity_test.go
  • pkg/tbtc/tbtc.go
  • test/config.json
  • test/config.toml
  • test/config.yaml

Comment thread pkg/bitcoin/electrum/electrum.go
Comment thread pkg/chain/ethereum/bitcoin_difficulty.go Outdated
Comment thread pkg/chain/ethereum/ecdsa_dkg_validator_chain.go
lionakhnazarov and others added 6 commits June 9, 2026 13:58
…f runtime paths

Introduces testnet4 configuration and electrum URL wiring, updates chain integrations including DKG validator support, and improves btcdiff/TBTC runtime and reliability-oriented tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
WaitMined previously used context.Background() with no timeout, and the
follow-up confirmation-depth wait called the context-less
BlockCounter.WaitForBlockHeight. If the RPC stalls or the chain stops
producing blocks, the maintainer would hang indefinitely on every
Retarget / RetargetWithRefund call.

Wrap both waits under a 10-minute shared deadline and add a context
shim around WaitForBlockHeight so callers can enforce timeouts on the
context-less BlockCounter interface.
Elevate the Sepolia/Developer defaultGroupParameters log to Warn level
and spell out that GroupQuorum equals GroupSize (3/3/2), so all three
operators must stay online for DKG to progress.

Also emit a Warn when the EcdsaDkgValidator contract address is not
configured. The fallthrough was previously silent, leaving operators
unaware that group sizing was coming from compile-time defaults rather
than the on-chain validator.
When the Electrum fee oracle returns no estimate for any confirmation
target, EstimateSatPerVByteFee returned a hardcoded 2 sat/vByte for every
network. On mainnet this turns a fail-safe (error, no broadcast) into a
fail-broadcast: the tBTC sweep and redemption fee paths build and broadcast
transactions at a feerate that can be left unconfirmable or evicted under
congestion, stalling sweeps and redemptions.

Gate the fallback to test networks (testnet, testnet4, regtest) via a new
Electrum Config.Network field resolved from the client configuration. On
mainnet, and on any unset or unknown network, the oracle failure is surfaced
as an error so callers do not broadcast at a guessed feerate. The field is
tagged mapstructure:"-" and set after config unmarshal, so a config key
cannot re-enable the fallback on mainnet.

Add a unit test covering the fallback decision per network and propagate the
resolved network into the Electrum integration test configs.
- electrum: only use the low-fee fallback when every failure was a benign
  fee-oracle "no estimate" response. Previously the fallback was returned
  whenever sawFeeOracleFailure was set, even if a transport/auth (non-oracle)
  failure was also seen, masking real connectivity errors. Track
  sawNonOracleFailure and fail safe (surface the error) when one occurred.

- ecdsa_dkg_validator_chain: enforce groupThreshold <= activeThreshold
  (HonestThreshold <= GroupQuorum) in addition to the existing
  <= groupSize guard, so a validator returning groupThreshold > activeThreshold
  cannot produce inconsistent TBTC GroupParameters.

The third finding (bind.WaitMined(context.Background()) unbounded wait in
bitcoin_difficulty.go) was already resolved by including #4013's bounded-wait
fix in this branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lionakhnazarov
lionakhnazarov force-pushed the stack/testnet4-04-go-testnet4-runtime branch from cd7ee40 to 2d040dc Compare June 9, 2026 13:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/chain/ethereum/bitcoin_difficulty.go`:
- Around line 185-201: waitForBlockHeightCtx currently spawns a goroutine that
blocks forever in bc.WaitForBlockHeight when ctx times out, leaking goroutines;
change the approach to use a non-blocking channel-based waiter instead: add or
use a BlockCounter method that returns a channel (e.g.,
WaitForBlockHeightChan(blockNumber) <-chan error or BlockHeightWaiter) and then
implement waitForBlockHeightCtx to select between ctx.Done() and that channel,
returning whichever happens first; update callers and the BlockCounter
implementation to provide the channel-based waiter so no parked goroutines
remain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6bd4d665-ca18-4f63-bdba-42d3cbd1c1d8

📥 Commits

Reviewing files that changed from the base of the PR and between cd7ee40 and 2d040dc.

📒 Files selected for processing (33)
  • cmd/flags.go
  • cmd/flags_test.go
  • cmd/start.go
  • config/_electrum_urls/testnet4
  • config/config_test.go
  • config/contracts.go
  • config/electrum.go
  • config/electrum_test.go
  • config/network/network.go
  • pkg/bitcoin/bitcoin.go
  • pkg/bitcoin/electrum/config.go
  • pkg/bitcoin/electrum/electrum.go
  • pkg/bitcoin/electrum/electrum_integration_test.go
  • pkg/bitcoin/electrum/electrum_test.go
  • pkg/chain/ethereum/bitcoin_difficulty.go
  • pkg/chain/ethereum/bitcoin_difficulty_test.go
  • pkg/chain/ethereum/ecdsa_dkg_validator_chain.go
  • pkg/chain/ethereum/ethereum.go
  • pkg/chain/ethereum/ethereum_integration_test.go
  • pkg/chain/ethereum/tbtc.go
  • pkg/chain/local_v1/blockcounter.go
  • pkg/internal/dkgtest/dkgtest.go
  • pkg/maintainer/btcdiff/bitcoin_difficulty.go
  • pkg/maintainer/btcdiff/bitcoin_difficulty_test.go
  • pkg/maintainer/btcdiff/config.go
  • pkg/maintainer/btcdiff/errors.go
  • pkg/tbtc/coordination_test.go
  • pkg/tbtc/inactivity.go
  • pkg/tbtc/inactivity_test.go
  • pkg/tbtc/tbtc.go
  • test/config.json
  • test/config.toml
  • test/config.yaml
✅ Files skipped from review due to trivial changes (5)
  • test/config.yaml
  • test/config.json
  • test/config.toml
  • config/config_test.go
  • config/_electrum_urls/testnet4
🚧 Files skipped from review as they are similar to previous changes (20)
  • cmd/start.go
  • pkg/maintainer/btcdiff/config.go
  • pkg/chain/ethereum/ethereum.go
  • pkg/tbtc/inactivity.go
  • pkg/bitcoin/bitcoin.go
  • cmd/flags.go
  • pkg/chain/ethereum/ethereum_integration_test.go
  • config/network/network.go
  • pkg/tbtc/coordination_test.go
  • pkg/maintainer/btcdiff/errors.go
  • config/electrum_test.go
  • pkg/internal/dkgtest/dkgtest.go
  • pkg/maintainer/btcdiff/bitcoin_difficulty.go
  • pkg/tbtc/inactivity_test.go
  • pkg/chain/ethereum/tbtc.go
  • pkg/chain/local_v1/blockcounter.go
  • pkg/maintainer/btcdiff/bitcoin_difficulty_test.go
  • pkg/tbtc/tbtc.go
  • pkg/bitcoin/electrum/electrum_integration_test.go
  • pkg/chain/ethereum/ecdsa_dkg_validator_chain.go

Comment thread pkg/chain/ethereum/bitcoin_difficulty.go Outdated
…e buildup

Addresses a follow-up CodeRabbit finding on PR #4002. The previous shim
spawned a goroutine parked in the context-less BlockCounter.WaitForBlockHeight;
when the parent context expired first the goroutine lingered until the chain
advanced, so repeated retargets during a prolonged chain stall could accumulate
parked goroutines.

Poll the non-blocking CurrentBlock under the caller's context instead. The wait
returns as soon as the height is reached or the context fires, and leaves no
goroutine behind. Tests updated to drive the stub via CurrentBlock.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lionakhnazarov
lionakhnazarov merged commit 4137b34 into main Jun 9, 2026
30 checks passed
@lionakhnazarov
lionakhnazarov deleted the stack/testnet4-04-go-testnet4-runtime branch June 9, 2026 14:14
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.

3 participants