-
Notifications
You must be signed in to change notification settings - Fork 138
Description
The Custodian service in tapgarden/custodian.go relies on WalletAnchor.SubscribeTransactions to detect incoming on-chain asset transfers. The current error handling and channel consumption in mainEventLoop introduces a risk of a busy-loop if the connection to the backing LND node is interrupted.
Issues Identified
1. Busy-Loop Risk on Channel Closure
In mainEventLoop, the newTxChan (type <-chan lndclient.Transaction) is consumed inside a select block:
case tx := <-newTxChan:
err = c.inspectWalletTx(&tx)If the newTxChan is closed (e.g., the underlying lndclient stream is terminated), the receive operation returns immediately with the zero value of the Transaction struct (not nil).
inspectWalletTxreceives a valid pointer to this empty struct.- It calls
hasWalletTaprootOutput, which checkslen(tx.OutputDetails). Since the zero-value slice has length 0, it returnsfalsesafely. inspectWalletTxreturnsnil(no error).- The loop repeats immediately, consuming 100% CPU while processing infinite "empty" transactions.
2. Zombie State (Silent Failure)
The error channel txErrChan is handled by logging the error and continuing. There is currently no logic to re-subscribe.
Once the subscription breaks (closed channel or error), the Custodian enters a state where it is technically running but receives no new chain events, meaning incoming asset transfers will be ignored until the daemon is restarted.
Expected Behavior
- Detect Closure: The loop must use
tx, ok := <-newTxChanto detect channel closure. - Re-subscribe: Upon closure or error, the
Custodianshould attempt to re-establish the transaction subscription (ideally with a backoff strategy) to resume processing.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status