Merge pull request #3737 from guggero/resume-scb
chanbackup: continue recovery if channel already exists
This commit is contained in:
commit
74849e7325
@ -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?
|
||||||
|
Loading…
Reference in New Issue
Block a user