Skip to content

Commit

Permalink
Add removechannel command
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Dec 14, 2020
1 parent 7eee3cd commit 27da365
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
+ [fixoldbackup](#fixoldbackup)
+ [genimportscript](#genimportscript)
+ [forceclose](#forceclose)
+ [removechannel](#removechannel)
+ [rescueclosed](#rescueclosed)
+ [rescuefunding](#rescuefunding)
+ [showrootkey](#showrootkey)
Expand Down Expand Up @@ -267,6 +268,7 @@ Available commands:
fixoldbackup Fixes an old channel.backup file that is affected by the lnd issue #3881 (unable to derive shachain root key).
forceclose Force-close the last state that is in the channel.db provided.
genimportscript Generate a script containing the on-chain keys of an lnd wallet that can be imported into other software like bitcoind.
removechannel Remove a single channel from the given channel DB.
rescueclosed Try finding the private keys for funds that are in outputs of remotely force-closed channels.
rescuefunding Rescue funds locked in a funding multisig output that never resulted in a proper channel. This is the command the initiator of the channel needs to run.
showrootkey Extract and show the BIP32 HD root key from the 24 word lnd aezeed.
Expand Down Expand Up @@ -505,6 +507,26 @@ Example command:
chantools genimportscript --format bitcoin-cli --recoverywindow 5000
```

### removechannel

```text
Usage:
chantools [OPTIONS] removechannel [removechannel-OPTIONS]
[removechannel command options]
--channeldb= The lnd channel.db file to remove the channel from.
--channel= The channel to remove from the DB file, identified by its channel point (<txid>:<txindex>).
```

Removes a single channel from the given channel DB.

Example command:

```bash
chantools --channeldb ~/.lnd/data/graph/mainnet/channel.db \
--channel 3149764effbe82718b280de425277e5e7b245a4573aa4a0203ac12cee1c37816:0
```

### rescueclosed

```text
Expand Down
4 changes: 4 additions & 0 deletions cmd/chantools/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ func runCommandParser() error {
"-initiator) of the channel needs to run.", "",
&signRescueFundingCommand{},
)
_, _ = parser.AddCommand(
"removechannel", "Remove a single channel from the given "+
"channel DB.", "", &removeChannelCommand{},
)

_, err := parser.Parse()
return err
Expand Down
71 changes: 71 additions & 0 deletions cmd/chantools/removechannel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"fmt"
"strconv"
"strings"

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/guggero/chantools/lnd"
"github.com/lightningnetwork/lnd/channeldb"
)

type removeChannelCommand struct {
ChannelDB string `long:"channeldb" description:"The lnd channel.db file to remove the channel from."`
Channel string `long:"channel" description:"The channel to remove from the DB file, identified by its channel point (<txid>:<txindex>)."`
}

func (c *removeChannelCommand) Execute(_ []string) error {
setupChainParams(cfg)

// Check that we have a channel DB.
if c.ChannelDB == "" {
return fmt.Errorf("channel DB is required")
}
db, err := lnd.OpenDB(c.ChannelDB, false)
if err != nil {
return fmt.Errorf("error opening channel DB: %v", err)
}
defer func() {
if err := db.Close(); err != nil {
log.Errorf("Error closing DB: %v", err)
}
}()

parts := strings.Split(c.Channel, ":")
if len(parts) != 2 {
return fmt.Errorf("invalid channel point format: %v", c.Channel)
}
hash, err := chainhash.NewHashFromStr(parts[0])
if err != nil {
return err
}
index, err := strconv.ParseUint(parts[1], 10, 64)
if err != nil {
return err
}

return removeChannel(db, &wire.OutPoint{
Hash: *hash,
Index: uint32(index),
})
}

func removeChannel(db *channeldb.DB, chanPoint *wire.OutPoint) error {
dbChan, err := db.FetchChannel(*chanPoint)
if err != nil {
return err
}

if err := dbChan.MarkBorked(); err != nil {
return err
}

// Abandoning a channel is a three step process: remove from the open
// channel state, remove from the graph, remove from the contract
// court. Between any step it's possible that the users restarts the
// process all over again. As a result, each of the steps below are
// intended to be idempotent.
return db.AbandonChannel(chanPoint, uint32(100000))
}

0 comments on commit 27da365

Please sign in to comment.