You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chantools/cmd/chantools/removechannel.go

95 lines
2.3 KiB
Go

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"
"github.com/spf13/cobra"
)
type removeChannelCommand struct {
ChannelDB string
Channel string
cmd *cobra.Command
}
func newRemoveChannelCommand() *cobra.Command {
cc := &removeChannelCommand{}
cc.cmd = &cobra.Command{
Use: "removechannel",
Short: "Remove a single channel from the given channel DB",
Example: `chantools --channeldb ~/.lnd/data/graph/mainnet/channel.db \
--channel 3149764effbe82718b280de425277e5e7b245a4573aa4a0203ac12cee1c37816:0`,
RunE: cc.Execute,
}
cc.cmd.Flags().StringVar(
&cc.ChannelDB, "channeldb", "", "lnd channel.backup file to "+
"remove the channel from",
)
cc.cmd.Flags().StringVar(
&cc.Channel, "channel", "", "channel to remove from the DB "+
"file, identified by its channel point "+
"(<txid>:<txindex>)",
)
return cc.cmd
}
func (c *removeChannelCommand) Execute(_ *cobra.Command, _ []string) error {
// 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))
}