Add chanbackup command

pull/3/head
Oliver Gugger 4 years ago
parent b6acefd385
commit f780b0f0a8
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

@ -5,6 +5,7 @@
* [Installation](#installation)
* [Overview](#overview)
* [Commands](#commands)
+ [chanbackup](#chanbackup)
+ [derivekey](#derivekey)
+ [dumpbackup](#dumpbackup)
+ [dumpchannels](#dumpchannels)
@ -57,6 +58,7 @@ Help Options:
-h, --help Show this help message
Available commands:
chanbackup Create a channel.backup file from a channel database.
derivekey Derive a key with a specific derivation path from the BIP32 HD root key.
dumpbackup Dump the content of a channel.backup file.
dumpchannels Dump all channel information from lnd's channel database.
@ -73,6 +75,28 @@ Available commands:
## Commands
### chanbackup
```text
Usage:
chantools [OPTIONS] chanbackup [chanbackup-OPTIONS]
[chanbackup command options]
--rootkey= BIP32 HD root key of the wallet that should be used to create the backup. Leave empty to prompt for lnd 24 word aezeed.
--channeldb= The lnd channel.db file to create the backup from.
--multi_file= The lnd channel.backup file to create.
```
This command creates a new channel.backup from a channel.db file.
Example command:
```bash
chantools chanbackup --rootkey xprvxxxxxxxxxx \
--channeldb ~/.lnd/data/graph/mainnet/channel.db \
--multi_file new_channel_backup.backup
```
### derivekey
```text

@ -0,0 +1,83 @@
package main
import (
"bytes"
"fmt"
"github.com/guggero/chantools/btc"
"github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/keychain"
"path"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/lightningnetwork/lnd/channeldb"
)
type chanBackupCommand struct {
RootKey string `long:"rootkey" description:"BIP32 HD root key of the wallet that should be used to create the backup. Leave empty to prompt for lnd 24 word aezeed."`
ChannelDB string `long:"channeldb" description:"The lnd channel.db file to create the backup from."`
MultiFile string `long:"multi_file" description:"The lnd channel.backup file to create."`
}
func (c *chanBackupCommand) Execute(_ []string) error {
setupChainParams(cfg)
var (
extendedKey *hdkeychain.ExtendedKey
err error
)
// Check that root key is valid or fall back to console input.
switch {
case c.RootKey != "":
extendedKey, err = hdkeychain.NewKeyFromString(c.RootKey)
default:
extendedKey, _, err = rootKeyFromConsole()
}
if err != nil {
return fmt.Errorf("error reading root key: %v", err)
}
// Check that we have a backup file.
if c.MultiFile == "" {
return fmt.Errorf("backup file is required")
}
// Check that we have a channel DB.
if c.ChannelDB == "" {
return fmt.Errorf("channel DB is required")
}
db, err := channeldb.Open(path.Dir(c.ChannelDB))
if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err)
}
multiFile := chanbackup.NewMultiFile(c.MultiFile)
keyRing := &btc.HDKeyRing{
ExtendedKey: extendedKey,
ChainParams: chainParams,
}
return createChannelBackup(db, multiFile, keyRing)
}
func createChannelBackup(db *channeldb.DB, multiFile *chanbackup.MultiFile,
ring keychain.KeyRing) error {
singles, err := chanbackup.FetchStaticChanBackups(db)
if err != nil {
return fmt.Errorf("error extracting channel backup: %v", err)
}
multi := &chanbackup.Multi{
Version: chanbackup.DefaultMultiVersion,
StaticBackups: singles,
}
var b bytes.Buffer
err = multi.PackToWriter(&b, ring)
if err != nil {
return fmt.Errorf("unable to pack backup: %v", err)
}
err = multiFile.UpdateAndSwap(b.Bytes())
if err != nil {
return fmt.Errorf("unable to write backup file: %v", err)
}
return nil
}

@ -5,6 +5,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/lightningnetwork/lnd/chanbackup"
"io/ioutil"
"os"
"strings"
@ -12,6 +13,7 @@ import (
"time"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btclog"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/guggero/chantools/dataformat"
"github.com/jessevdk/go-flags"
@ -115,6 +117,10 @@ func runCommandParser() error {
"wallet.db file and optionally extracts the BIP32 HD "+
"root key.", "", &walletInfoCommand{},
)
_, _ = parser.AddCommand(
"chanbackup", "Create a channel.backup file from a channel "+
"database.", "", &chanBackupCommand{},
)
_, err := parser.Parse()
return err
@ -258,7 +264,9 @@ func setupChainParams(cfg *config) {
}
func setupLogging() {
logWriter.RegisterSubLogger("CHAN", log)
setSubLogger("CHAN", log)
addSubLogger("CHDB", channeldb.UseLogger)
addSubLogger("BCKP", chanbackup.UseLogger)
err := logWriter.InitLogRotator("./results/chantools.log", 10, 3)
if err != nil {
panic(err)
@ -269,6 +277,26 @@ func setupLogging() {
}
}
// addSubLogger is a helper method to conveniently create and register the
// logger of one or more sub systems.
func addSubLogger(subsystem string, useLoggers ...func(btclog.Logger)) {
// Create and register just a single logger to prevent them from
// overwriting each other internally.
logger := build.NewSubLogger(subsystem, logWriter.GenSubLogger)
setSubLogger(subsystem, logger, useLoggers...)
}
// setSubLogger is a helper method to conveniently register the logger of a sub
// system.
func setSubLogger(subsystem string, logger btclog.Logger,
useLoggers ...func(btclog.Logger)) {
logWriter.RegisterSubLogger(subsystem, logger)
for _, useLogger := range useLoggers {
useLogger(logger)
}
}
func noConsole() ([]byte, error) {
return nil, fmt.Errorf("wallet db requires console access")
}

@ -4,6 +4,7 @@ require (
git.schwanenlied.me/yawning/bsaes.git v0.0.0-20190320102049-26d1add596b6 // indirect
github.com/Yawning/aez v0.0.0-20180408160647-ec7426b44926 // indirect
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcutil v0.0.0-20191219182022-e17c9730c422
github.com/btcsuite/btcwallet v0.11.0
github.com/btcsuite/btcwallet/walletdb v1.1.0

Loading…
Cancel
Save