Merge pull request #3737 from guggero/resume-scb

chanbackup: continue recovery if channel already exists
This commit is contained in:
Olaoluwa Osuntokun 2019-11-22 19:40:47 -08:00 committed by GitHub
commit 74849e7325
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 0 deletions

@ -5,6 +5,7 @@ import (
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
) )
@ -47,6 +48,14 @@ func Recover(backups []Single, restorer ChannelRestorer,
backup.FundingOutpoint) backup.FundingOutpoint)
err := restorer.RestoreChansFromSingles(backup) 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 { if err != nil {
return err return err
} }

@ -14218,6 +14218,72 @@ func testChannelBackupRestore(net *lntest.NetworkHarness, t *harnessTest) {
}, nil }, 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? // TODO(roasbeef): online vs offline close?