chanbackup: refuse to start the SubSwapper if we can't read the SCB file
In this commit, we add an additional defense against starting up with an invalid SCB state. With this commit, we'll now fail to start up if we're unable to update or read the existing SCB state from disk. This will prevent an lnd node from starting up with an invalid SCB file, an SCB file it can't decrypt, or an SCB left over from another node.
This commit is contained in:
parent
fc65c9b2cc
commit
496e29d02e
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
@ -134,13 +135,24 @@ func NewSubSwapper(startingChans []Single, chanNotifier ChannelNotifier,
|
|||||||
|
|
||||||
// Start starts the chanbackup.SubSwapper.
|
// Start starts the chanbackup.SubSwapper.
|
||||||
func (s *SubSwapper) Start() error {
|
func (s *SubSwapper) Start() error {
|
||||||
|
var startErr error
|
||||||
s.started.Do(func() {
|
s.started.Do(func() {
|
||||||
log.Infof("Starting chanbackup.SubSwapper")
|
log.Infof("Starting chanbackup.SubSwapper")
|
||||||
|
|
||||||
|
// Before we enter our main loop, we'll update the on-disk
|
||||||
|
// state with the latest Single state, as nodes may have new
|
||||||
|
// advertised addresses.
|
||||||
|
if err := s.updateBackupFile(); err != nil {
|
||||||
|
startErr = fmt.Errorf("unable to refresh backup "+
|
||||||
|
"file: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
s.wg.Add(1)
|
s.wg.Add(1)
|
||||||
go s.backupUpdater()
|
go s.backupUpdater()
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
|
return startErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop signals the SubSwapper to being a graceful shutdown.
|
// Stop signals the SubSwapper to being a graceful shutdown.
|
||||||
@ -162,7 +174,11 @@ func (s *SubSwapper) updateBackupFile(closedChans ...wire.OutPoint) error {
|
|||||||
// already have on-disk, to make sure we can decode it (proper seed)
|
// already have on-disk, to make sure we can decode it (proper seed)
|
||||||
// and that we're able to combine it with our new data.
|
// and that we're able to combine it with our new data.
|
||||||
diskMulti, err := s.Swapper.ExtractMulti(s.keyRing)
|
diskMulti, err := s.Swapper.ExtractMulti(s.keyRing)
|
||||||
if err != nil {
|
|
||||||
|
// If the file doesn't exist on disk, then that's OK as it was never
|
||||||
|
// created. In this case we'll continue onwards as it isn't a critical
|
||||||
|
// error.
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
return fmt.Errorf("unable to extract on disk encrypted "+
|
return fmt.Errorf("unable to extract on disk encrypted "+
|
||||||
"SCB: %v", err)
|
"SCB: %v", err)
|
||||||
}
|
}
|
||||||
@ -235,14 +251,6 @@ func (s *SubSwapper) backupUpdater() {
|
|||||||
|
|
||||||
log.Debugf("SubSwapper's backupUpdater is active!")
|
log.Debugf("SubSwapper's backupUpdater is active!")
|
||||||
|
|
||||||
// Before we enter our main loop, we'll update the on-disk state with
|
|
||||||
// the latest Single state, as nodes may have new advertised addresses.
|
|
||||||
//
|
|
||||||
// TODO(roasbeef): do in Start() so we don't start with an invalid SCB?
|
|
||||||
if err := s.updateBackupFile(); err != nil {
|
|
||||||
log.Errorf("Unable to refresh backup file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
// The channel state has been modified! We'll evaluate all
|
// The channel state has been modified! We'll evaluate all
|
||||||
|
@ -21,7 +21,7 @@ type mockSwapper struct {
|
|||||||
|
|
||||||
func newMockSwapper(keychain keychain.KeyRing) *mockSwapper {
|
func newMockSwapper(keychain keychain.KeyRing) *mockSwapper {
|
||||||
return &mockSwapper{
|
return &mockSwapper{
|
||||||
swaps: make(chan PackedMulti),
|
swaps: make(chan PackedMulti, 1),
|
||||||
keyChain: keychain,
|
keyChain: keychain,
|
||||||
swapState: &Multi{},
|
swapState: &Multi{},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user