cmd/chantools+lnd: fix triggerforceclose command

This commit fixes two issues:
1. Some new peer related config values weren't set, leading to an error.
2. Triggering the force close with a CLN node can be timing-sensitive.
   It appears that trying both methods independently directly after
   connecting yields the most reliable result.
This commit is contained in:
Oliver Gugger 2025-10-08 23:41:25 +02:00
parent 2b59a56ee2
commit 0b904f2135
No known key found for this signature in database
GPG key ID: 8E4256593F177720
2 changed files with 45 additions and 3 deletions

View file

@ -259,7 +259,11 @@ func closeChannel(identityPriv *btcec.PrivateKey, api *btc.ExplorerAPI,
return nil, fmt.Errorf("error parsing channel point: %w", err)
}
err = requestForceClose(peer, torProxy, *outPoint, identityECDH)
err = requestForceCloseLnd(peer, torProxy, *outPoint, identityECDH)
if err != nil {
return nil, fmt.Errorf("error requesting force close: %w", err)
}
err = requestForceCloseCln(peer, torProxy, *outPoint, identityECDH)
if err != nil {
return nil, fmt.Errorf("error requesting force close: %w", err)
}
@ -287,6 +291,17 @@ func closeChannel(identityPriv *btcec.PrivateKey, api *btc.ExplorerAPI,
}
counter++
if counter >= 6 {
log.Info("Waited 30 seconds, still no spends found, " +
"re-triggering CLN request")
err = requestForceCloseCln(
peer, torProxy, *outPoint, identityECDH,
)
if err != nil {
return nil, fmt.Errorf("error requesting "+
"force close: %w", err)
}
}
if counter >= 12 {
return nil, errors.New("no spends found after 60 " +
"seconds, aborting re-try loop")
@ -385,7 +400,7 @@ func connectPeer(peerHost, torProxy string, identity keychain.SingleKeyECDH,
return p, cleanup, nil
}
func requestForceClose(peerHost, torProxy string, channelPoint wire.OutPoint,
func requestForceCloseLnd(peerHost, torProxy string, channelPoint wire.OutPoint,
identity keychain.SingleKeyECDH) error {
p, cleanup, err := connectPeer(
@ -415,6 +430,32 @@ func requestForceClose(peerHost, torProxy string, channelPoint wire.OutPoint,
return err
}
// Wait a few seconds to give the peer time to process the message.
time.Sleep(5 * time.Second)
return nil
}
func requestForceCloseCln(peerHost, torProxy string, channelPoint wire.OutPoint,
identity keychain.SingleKeyECDH) error {
p, cleanup, err := connectPeer(
peerHost, torProxy, identity, dialTimeout,
)
defer func() {
_ = cleanup()
}()
if err != nil {
return fmt.Errorf("error connecting to peer: %w", err)
}
channelID := lnwire.NewChanIDFromOutPoint(channelPoint)
// Channel ID (32 byte) + u16 for the data length (which will be 0).
data := make([]byte, 34)
copy(data[:32], channelID[:])
log.Infof("Sending channel error message to peer to trigger force "+
"close of channel %v", channelPoint)

View file

@ -217,7 +217,8 @@ func ConnectPeer(conn *brontide.Conn, connReq *connmgr.ConnReq,
return nil
},
})
},
)
if err != nil {
_ = channelDB.Close()
return nil, nil, fmt.Errorf("unable to create channel status "+