@@ -169,19 +169,33 @@ func (c *triggerForceCloseCommand) Execute(_ *cobra.Command, _ []string) error {
169169 pubKeys []string
170170 outputs []string
171171 )
172- for _ , openChan := range channels {
172+ for idx , openChan := range channels {
173173 addr := pickAddr (openChan .Node2Info .Node .Addresses )
174174 peerAddr := fmt .Sprintf ("%s@%s" , openChan .Node2 , addr )
175+
176+ if c .TorProxy == "" &&
177+ strings .Contains (addr , ".onion" ) {
178+
179+ log .Infof ("Skipping channel %s with peer %s " +
180+ "because it is a Tor address and no " +
181+ "Tor proxy is configured" ,
182+ openChan .ChanPoint , peerAddr )
183+ continue
184+ }
185+
175186 log .Infof ("Attempting to force close channel %s with " +
176- "peer %s" , openChan .ChanPoint , peerAddr )
187+ "peer %s (channel %d of %d)" ,
188+ openChan .ChanPoint , peerAddr , idx + 1 ,
189+ len (channels ))
177190
178191 outputAddrs , err := closeChannel (
179192 identityPriv , api , openChan .ChanPoint ,
180193 peerAddr , c .TorProxy ,
181194 )
182195 if err != nil {
183196 log .Errorf ("Error closing channel %s, " +
184- "skipping: %v" , openChan .ChanPoint , err )
197+ "skipping and trying next one. " +
198+ "Reason: %v" , openChan .ChanPoint , err )
185199 continue
186200 }
187201
@@ -220,7 +234,7 @@ func pickAddr(addrs []*gqAddress) string {
220234
221235 // We'll pick the first address that is not a Tor address.
222236 for _ , addr := range addrs {
223- if ! strings .HasSuffix (addr .Address , ".onion" ) {
237+ if ! strings .Contains (addr .Address , ".onion" ) {
224238 return addr .Address
225239 }
226240 }
@@ -262,13 +276,21 @@ func closeChannel(identityPriv *btcec.PrivateKey, api *btc.ExplorerAPI,
262276 if err != nil {
263277 return nil , fmt .Errorf ("error getting spends: %w" , err )
264278 }
279+
280+ counter := 0
265281 for len (spends ) == 0 {
266282 log .Infof ("No spends found yet, waiting 5 seconds..." )
267283 time .Sleep (5 * time .Second )
268284 spends , err = api .Spends (channelAddress )
269285 if err != nil {
270286 return nil , fmt .Errorf ("error getting spends: %w" , err )
271287 }
288+
289+ counter ++
290+ if counter >= 12 {
291+ return nil , errors .New ("no spends found after 60 " +
292+ "seconds, aborting re-try loop" )
293+ }
272294 }
273295
274296 log .Infof ("Found force close transaction %v" , spends [0 ].TXID )
@@ -289,7 +311,11 @@ func noiseDial(idKey keychain.SingleKeyECDH, lnAddr *lnwire.NetAddress,
289311}
290312
291313func connectPeer (peerHost , torProxy string , identity keychain.SingleKeyECDH ,
292- dialTimeout time.Duration ) (* peer.Brontide , error ) {
314+ dialTimeout time.Duration ) (* peer.Brontide , func () error , error ) {
315+
316+ cleanup := func () error {
317+ return nil
318+ }
293319
294320 var dialNet tor.Net = & tor.ClearNet {}
295321 if torProxy != "" {
@@ -306,7 +332,8 @@ func connectPeer(peerHost, torProxy string, identity keychain.SingleKeyECDH,
306332 peerHost , "9735" , dialNet .ResolveTCPAddr ,
307333 )
308334 if err != nil {
309- return nil , fmt .Errorf ("error parsing peer address: %w" , err )
335+ return nil , cleanup , fmt .Errorf ("error parsing peer address: " +
336+ "%w" , err )
310337 }
311338
312339 peerPubKey := peerAddr .IdentityKey
@@ -315,7 +342,11 @@ func connectPeer(peerHost, torProxy string, identity keychain.SingleKeyECDH,
315342 peerAddr .String ())
316343 conn , err := noiseDial (identity , peerAddr , dialNet , dialTimeout )
317344 if err != nil {
318- return nil , fmt .Errorf ("error dialing peer: %w" , err )
345+ return nil , cleanup , fmt .Errorf ("error dialing peer: %w" , err )
346+ }
347+
348+ cleanup = func () error {
349+ return conn .Close ()
319350 }
320351
321352 log .Infof ("Attempting to establish p2p connection to peer %x, dial" +
@@ -324,9 +355,20 @@ func connectPeer(peerHost, torProxy string, identity keychain.SingleKeyECDH,
324355 Addr : peerAddr ,
325356 Permanent : false ,
326357 }
327- p , err := lnd .ConnectPeer (conn , req , chainParams , identity )
358+ p , channelDB , err := lnd .ConnectPeer (conn , req , chainParams , identity )
328359 if err != nil {
329- return nil , fmt .Errorf ("error connecting to peer: %w" , err )
360+ return nil , cleanup , fmt .Errorf ("error connecting to peer: %w" ,
361+ err )
362+ }
363+
364+ cleanup = func () error {
365+ p .Disconnect (errors .New ("done with peer" ))
366+ if channelDB != nil {
367+ if err := channelDB .Close (); err != nil {
368+ log .Errorf ("Error closing channel DB: %v" , err )
369+ }
370+ }
371+ return conn .Close ()
330372 }
331373
332374 log .Infof ("Connection established to peer %x" ,
@@ -336,17 +378,23 @@ func connectPeer(peerHost, torProxy string, identity keychain.SingleKeyECDH,
336378 select {
337379 case <- p .ActiveSignal ():
338380 case <- p .QuitSignal ():
339- return nil , fmt .Errorf ("peer %x disconnected" ,
381+ return nil , cleanup , fmt .Errorf ("peer %x disconnected" ,
340382 peerPubKey .SerializeCompressed ())
341383 }
342384
343- return p , nil
385+ return p , cleanup , nil
344386}
345387
346388func requestForceClose (peerHost , torProxy string , channelPoint wire.OutPoint ,
347389 identity keychain.SingleKeyECDH ) error {
348390
349- p , err := connectPeer (peerHost , torProxy , identity , dialTimeout )
391+ p , cleanup , err := connectPeer (
392+ peerHost , torProxy , identity , dialTimeout ,
393+ )
394+ defer func () {
395+ _ = cleanup ()
396+ }()
397+
350398 if err != nil {
351399 return fmt .Errorf ("error connecting to peer: %w" , err )
352400 }
@@ -383,6 +431,9 @@ func requestForceClose(peerHost, torProxy string, channelPoint wire.OutPoint,
383431 return fmt .Errorf ("error sending message: %w" , err )
384432 }
385433
434+ // Wait a few seconds to give the peer time to process the message.
435+ time .Sleep (5 * time .Second )
436+
386437 return nil
387438}
388439
0 commit comments