Skip to content

fix: expire stale pending cooperative exits after configurable threshold - #130

Open
vwinee21 wants to merge 2 commits into
buildonspark:mainfrom
vwinee21:fix/expire-pending-coop-exits
Open

fix: expire stale pending cooperative exits after configurable threshold#130
vwinee21 wants to merge 2 commits into
buildonspark:mainfrom
vwinee21:fix/expire-pending-coop-exits

Conversation

@vwinee21

Copy link
Copy Markdown

Problem

Pending cooperative exits (ConfirmationHeightIsNil()) accumulate indefinitely if the L1 transaction is never confirmed — for example, when evicted from the Bitcoin mempool due to low fees or replaced via RBF. This was noted in a TODO comment in watch_chain.go.

Solution

Add expiry logic that runs each block processing cycle. Pending coop exits older than KnobWatchChainCoopExitPendingExpiryDays (default: 14 days) are deleted.

Why 14 days? This matches Bitcoin Core's DEFAULT_MEMPOOL_EXPIRY — by this point, any unconfirmed transaction would have been dropped from the mempool, so the pending record serves no purpose.

Changes

  • so/knobs/knobs.go — add KnobWatchChainCoopExitPendingExpiryDays knob + CoopExitPendingExpiryDays = 14 default constant
  • so/chain/watch_chain.go — replace TODO with expiry logic; logs count at Info level when non-zero

Behavior

  • Threshold is runtime-configurable via the knob system (no code deploy needed)
  • Expiry only affects ConfirmationHeightIsNil() entries — confirmed exits are untouched
  • Non-zero expiry count logged for observability

vwinee21 added 2 commits May 13, 2026 08:00
Replace fragile prefix matching with proper btcutil.DecodeAddress
validation which includes checksum verification.

Resolves TODO in IsBitcoinAddressForNetwork.
Pending coop exits with ConfirmationHeightIsNil() can accumulate
indefinitely if the L1 transaction is never confirmed (e.g. evicted
from mempool due to low fee or replaced via RBF).

Add expiry logic that runs each block cycle and deletes pending coop
exits older than KnobWatchChainCoopExitPendingExpiryDays (default: 14
days). The 14-day default matches Bitcoin Core's DEFAULT_MEMPOOL_EXPIRY
so entries are cleaned up around the time Bitcoin Core would drop them.

Expiry count is logged at Info level when non-zero for observability.
The threshold is runtime-configurable via the knob system without a
code deploy.
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