From 4728ac844a10690f70db9d023f46feec165c5452 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 18 Nov 2019 09:02:56 +0100 Subject: [PATCH 1/2] chanbackup: continue recovery if channel already exists --- chanbackup/recover.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/chanbackup/recover.go b/chanbackup/recover.go index 89c094583..2340e9777 100644 --- a/chanbackup/recover.go +++ b/chanbackup/recover.go @@ -5,6 +5,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/keychain" ) @@ -47,6 +48,14 @@ func Recover(backups []Single, restorer ChannelRestorer, backup.FundingOutpoint) err := restorer.RestoreChansFromSingles(backup) + + // If a channel is already present in the channel DB, we can + // just continue. No reason to fail a whole set of multi backups + // for example. This allows resume of a restore in case another + // error happens. + if err == channeldb.ErrChanAlreadyExists { + continue + } if err != nil { return err } From 570275435b5f4fc523f18e94ec7d71dd98158f44 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 20 Nov 2019 10:57:20 +0100 Subject: [PATCH 2/2] lntest: add SCB repeated restore test --- lntest/itest/lnd_test.go | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 5817e85db..672f6a0a5 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -14130,6 +14130,72 @@ func testChannelBackupRestore(net *lntest.NetworkHarness, t *harnessTest) { }, nil }, }, + + // Restore the backup from the on-disk file a second time to + // make sure imports can be canceled and later resumed. + { + name: "restore from backup file twice", + initiator: true, + private: false, + restoreMethod: func(oldNode *lntest.HarnessNode, + backupFilePath string, + mnemonic []string) (nodeRestorer, error) { + + // Read the entire Multi backup stored within + // this node's chaannels.backup file. + multi, err := ioutil.ReadFile(backupFilePath) + if err != nil { + return nil, err + } + + // Now that we have Dave's backup file, we'll + // create a new nodeRestorer that will restore + // using the on-disk channels.backup. + backup := &lnrpc.RestoreChanBackupRequest_MultiChanBackup{ + MultiChanBackup: multi, + } + + ctxb := context.Background() + + return func() (*lntest.HarnessNode, error) { + newNode, err := net.RestoreNodeWithSeed( + "dave", nil, password, mnemonic, + 1000, nil, + ) + if err != nil { + return nil, fmt.Errorf("unable to "+ + "restore node: %v", err) + } + + _, err = newNode.RestoreChannelBackups( + ctxb, + &lnrpc.RestoreChanBackupRequest{ + Backup: backup, + }, + ) + if err != nil { + return nil, fmt.Errorf("unable "+ + "to restore backups: %v", + err) + } + + _, err = newNode.RestoreChannelBackups( + ctxb, + &lnrpc.RestoreChanBackupRequest{ + Backup: backup, + }, + ) + if err != nil { + return nil, fmt.Errorf("unable "+ + "to restore backups the"+ + "second time: %v", + err) + } + + return newNode, nil + }, nil + }, + }, } // TODO(roasbeef): online vs offline close?