watchtower: prevent removal of last tower addr

This addresses a potential panic when a tower has one of its candidate
sessions chosen, but its only reachable address was removed by a
user-initiated RPC before the fact.
This commit is contained in:
Wilmer Paulino committed 2020-11-04 15:43:18 -08:00
1 parent 3ae46d81f4
commit d3157bcaf8
5 files changed
+28 -5

No files matched your search

+10
View File
@@ -108,6 +108,10 @@ var (
// created because session key index differs from the reserved key
// index.
ErrIncorrectKeyIndex = errors.New("incorrect key index")
// ErrLastTowerAddr is an error returned when the last address of a
// watchtower is attempted to be removed.
ErrLastTowerAddr = errors.New("cannot remove last tower address")
)
// ClientDB is single database providing a persistent storage engine for the
@@ -333,7 +337,13 @@ func (c *ClientDB) RemoveTower(pubKey *btcec.PublicKey, addr net.Addr) error {
if err != nil {
return err
}
// Towers should always have at least one address saved.
tower.RemoveAddress(addr)
if len(tower.Addresses) == 0 {
return ErrLastTowerAddr
}
return putTower(towers, tower)
}
+1 -1
View File
@@ -445,7 +445,7 @@ func testRemoveTower(h *clientDBHarness) {
// We'll then remove the first address. We should now see that the tower
// has no addresses left.
h.removeTower(pk, addr1, false, nil)
h.removeTower(pk, addr1, false, wtdb.ErrLastTowerAddr)
// Removing the tower as a whole from the database should succeed since
// there aren't any active sessions for it.