lncli: backup/verify/restore single channel from file

author ardevd <edvard.holst@gmail.com> 1676983861 +0100
committer ardevd <ardevd@users.noreply.github.com> 1677705118 +0100

Write to the specified file if the user specifies a chan_point for
backup and also specifies an output file to write the backup to.

Fixes #7436
This commit is contained in:
ardevd
2023-02-21 13:51:01 +01:00
committed by user
parent b9143c1623
commit ddc4bc6b32

View File

@@ -2314,8 +2314,9 @@ func exportChanBackup(ctx *cli.Context) error {
} }
var ( var (
err error err error
chanPointStr string chanPointStr string
outputFileName string
) )
args := ctx.Args() args := ctx.Args()
@@ -2330,6 +2331,10 @@ func exportChanBackup(ctx *cli.Context) error {
return fmt.Errorf("must specify chan_point if --all isn't set") return fmt.Errorf("must specify chan_point if --all isn't set")
} }
if ctx.IsSet("output_file") {
outputFileName = ctx.String("output_file")
}
if chanPointStr != "" { if chanPointStr != "" {
chanPointRPC, err := parseChanPoint(chanPointStr) chanPointRPC, err := parseChanPoint(chanPointStr)
if err != nil { if err != nil {
@@ -2357,6 +2362,14 @@ func exportChanBackup(ctx *cli.Context) error {
Index: chanPointRPC.OutputIndex, Index: chanPointRPC.OutputIndex,
} }
if outputFileName != "" {
return os.WriteFile(
outputFileName,
chanBackup.ChanBackup,
0666,
)
}
printJSON(struct { printJSON(struct {
ChanPoint string `json:"chan_point"` ChanPoint string `json:"chan_point"`
ChanBackup []byte `json:"chan_backup"` ChanBackup []byte `json:"chan_backup"`
@@ -2378,9 +2391,9 @@ func exportChanBackup(ctx *cli.Context) error {
return err return err
} }
if ctx.IsSet("output_file") { if outputFileName != "" {
return ioutil.WriteFile( return os.WriteFile(
ctx.String("output_file"), outputFileName,
chanBackup.MultiChanBackup.MultiChanBackup, chanBackup.MultiChanBackup.MultiChanBackup,
0666, 0666,
) )
@@ -2416,13 +2429,16 @@ var verifyChanBackupCommand = cli.Command{
backup for integrity. This is useful when a user has a backup, but is backup for integrity. This is useful when a user has a backup, but is
unsure as to if it's valid or for the target node. unsure as to if it's valid or for the target node.
The command will accept backups in one of three forms: The command will accept backups in one of four forms:
* A single channel packed SCB, which can be obtained from * A single channel packed SCB, which can be obtained from
exportchanbackup. This should be passed in hex encoded format. exportchanbackup. This should be passed in hex encoded format.
* A packed multi-channel SCB, which couples several individual * A packed multi-channel SCB, which couples several individual
static channel backups in single blob. static channel backups in single blob.
* A file path which points to a packed single-channel backup within a
file, using the same format that lnd does in its channel.backup file.
* A file path which points to a packed multi-channel backup within a * A file path which points to a packed multi-channel backup within a
file, using the same format that lnd does in its channel.backup file, using the same format that lnd does in its channel.backup
@@ -2439,6 +2455,13 @@ var verifyChanBackupCommand = cli.Command{
Usage: "a hex encoded multi-channel backup obtained " + Usage: "a hex encoded multi-channel backup obtained " +
"from exportchanbackup", "from exportchanbackup",
}, },
cli.StringFlag{
Name: "single_file",
Usage: "the path to a single-channel backup file",
TakesFile: true,
},
cli.StringFlag{ cli.StringFlag{
Name: "multi_file", Name: "multi_file",
Usage: "the path to a multi-channel back up file", Usage: "the path to a multi-channel back up file",
@@ -2499,7 +2522,7 @@ var restoreChanBackupCommand = cli.Command{
channel. If successful, this command will allows the user to recover channel. If successful, this command will allows the user to recover
the settled funds stored in the recovered channels. the settled funds stored in the recovered channels.
The command will accept backups in one of three forms: The command will accept backups in one of four forms:
* A single channel packed SCB, which can be obtained from * A single channel packed SCB, which can be obtained from
exportchanbackup. This should be passed in hex encoded format. exportchanbackup. This should be passed in hex encoded format.
@@ -2507,6 +2530,10 @@ var restoreChanBackupCommand = cli.Command{
* A packed multi-channel SCB, which couples several individual * A packed multi-channel SCB, which couples several individual
static channel backups in single blob. static channel backups in single blob.
* A file path which points to a packed single-channel backup within
a file, using the same format that lnd does in its channel.backup
file.
* A file path which points to a packed multi-channel backup within a * A file path which points to a packed multi-channel backup within a
file, using the same format that lnd does in its channel.backup file, using the same format that lnd does in its channel.backup
file. file.
@@ -2522,6 +2549,13 @@ var restoreChanBackupCommand = cli.Command{
Usage: "a hex encoded multi-channel backup obtained " + Usage: "a hex encoded multi-channel backup obtained " +
"from exportchanbackup", "from exportchanbackup",
}, },
cli.StringFlag{
Name: "single_file",
Usage: "the path to a single-channel backup file",
TakesFile: true,
},
cli.StringFlag{ cli.StringFlag{
Name: "multi_file", Name: "multi_file",
Usage: "the path to a multi-channel back up file", Usage: "the path to a multi-channel back up file",
@@ -2573,6 +2607,23 @@ func parseChanBackups(ctx *cli.Context) (*lnrpc.RestoreChanBackupRequest, error)
}, },
}, nil }, nil
case ctx.IsSet("single_file"):
packedSingle, err := os.ReadFile(ctx.String("single_file"))
if err != nil {
return nil, fmt.Errorf("unable to decode single "+
"packed backup: %v", err)
}
return &lnrpc.RestoreChanBackupRequest{
Backup: &lnrpc.RestoreChanBackupRequest_ChanBackups{
ChanBackups: &lnrpc.ChannelBackups{
ChanBackups: []*lnrpc.ChannelBackup{{
ChanBackup: packedSingle,
}},
},
},
}, nil
case ctx.IsSet("multi_file"): case ctx.IsSet("multi_file"):
packedMulti, err := ioutil.ReadFile(ctx.String("multi_file")) packedMulti, err := ioutil.ReadFile(ctx.String("multi_file"))
if err != nil { if err != nil {