Skip to content

Commit 8adf571

Browse files
committed
staticaddr: require positive heights at startup
Loop now guards all static-address managers against zero block heights: each constructor returns an error when invoked with a non-positive current height, and `loopd` validates the height from `GetInfo` before instantiating them. Tests and helper code were updated accordingly so we fail fast instead of registering chain notifications with invalid hints.
1 parent bde49d7 commit 8adf571

File tree

6 files changed

+67
-11
lines changed

6 files changed

+67
-11
lines changed

loopd/daemon.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
451451
return fmt.Errorf("failed to get current block height: %w", err)
452452
}
453453
blockHeight := getInfo.BlockHeight
454+
if blockHeight <= 0 {
455+
return fmt.Errorf("invalid block height reported by lnd: %d",
456+
blockHeight)
457+
}
454458

455459
// If we're running an asset client, we'll log something here.
456460
if d.assetClient != nil {
@@ -586,7 +590,13 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
586590
ChainParams: d.lnd.ChainParams,
587591
ChainNotifier: d.lnd.ChainNotifier,
588592
}
589-
staticAddressManager = address.NewManager(addrCfg, int32(blockHeight))
593+
staticAddressManager, err = address.NewManager(
594+
addrCfg, int32(blockHeight),
595+
)
596+
if err != nil {
597+
return fmt.Errorf("unable to create static address manager: %w",
598+
err)
599+
}
590600

591601
// Static address deposit manager setup.
592602
depositStore := deposit.NewSqlStore(baseDb)
@@ -617,7 +627,13 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
617627
Signer: d.lnd.Signer,
618628
Store: withdrawalStore,
619629
}
620-
withdrawalManager = withdraw.NewManager(withdrawalCfg, blockHeight)
630+
withdrawalManager, err = withdraw.NewManager(
631+
withdrawalCfg, blockHeight,
632+
)
633+
if err != nil {
634+
return fmt.Errorf("unable to create withdrawal manager: %w",
635+
err)
636+
}
621637

622638
// Static address loop-in manager setup.
623639
staticAddressLoopInStore := loopin.NewSqlStore(
@@ -645,7 +661,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
645661
return err
646662
}
647663

648-
staticLoopInManager = loopin.NewManager(&loopin.Config{
664+
staticLoopInManager, err = loopin.NewManager(&loopin.Config{
649665
Server: staticAddressClient,
650666
QuoteGetter: swapClient.Server,
651667
LndClient: d.lnd.Client,
@@ -663,6 +679,9 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
663679
MaxStaticAddrHtlcFeePercentage: d.cfg.MaxStaticAddrHtlcFeePercentage,
664680
MaxStaticAddrHtlcBackupFeePercentage: d.cfg.MaxStaticAddrHtlcBackupFeePercentage,
665681
}, blockHeight)
682+
if err != nil {
683+
return fmt.Errorf("unable to create loop-in manager: %w", err)
684+
}
666685

667686
var (
668687
reservationManager *reservation.Manager

loopd/swapclient_server_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,12 +1006,13 @@ func TestListUnspentDeposits(t *testing.T) {
10061006
addrStore := &mockAddressStore{params: []*address.Parameters{addrParams}}
10071007

10081008
// Build an address manager using our mock lnd and fake address store.
1009-
addrMgr := address.NewManager(&address.ManagerConfig{
1009+
addrMgr, err := address.NewManager(&address.ManagerConfig{
10101010
Store: addrStore,
10111011
WalletKit: mock.WalletKit,
10121012
ChainParams: mock.ChainParams,
10131013
// ChainNotifier and AddressClient are not needed for this test.
1014-
}, 0)
1014+
}, 1)
1015+
require.NoError(t, err)
10151016

10161017
// Construct several UTXOs with different confirmation counts.
10171018
makeUtxo := func(idx uint32, confs int64) *lnwallet.Utxo {

staticaddr/address/manager.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,18 @@ type Manager struct {
5757
}
5858

5959
// NewManager creates a new address manager.
60-
func NewManager(cfg *ManagerConfig, currentHeight int32) *Manager {
60+
func NewManager(cfg *ManagerConfig, currentHeight int32) (*Manager, error) {
61+
if currentHeight <= 0 {
62+
return nil, fmt.Errorf("invalid current height %d",
63+
currentHeight)
64+
}
65+
6166
m := &Manager{
6267
cfg: cfg,
6368
}
6469
m.currentHeight.Store(currentHeight)
6570

66-
return m
71+
return m, nil
6772
}
6873

6974
// Run runs the address manager.

staticaddr/loopin/manager.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ type Manager struct {
143143
}
144144

145145
// NewManager creates a new deposit withdrawal manager.
146-
func NewManager(cfg *Config, currentHeight uint32) *Manager {
146+
func NewManager(cfg *Config, currentHeight uint32) (*Manager, error) {
147+
if currentHeight == 0 {
148+
return nil, fmt.Errorf("invalid current height %d",
149+
currentHeight)
150+
}
151+
147152
m := &Manager{
148153
cfg: cfg,
149154
newLoopInChan: make(chan *newSwapRequest),
@@ -153,7 +158,7 @@ func NewManager(cfg *Config, currentHeight uint32) *Manager {
153158
}
154159
m.currentHeight.Store(currentHeight)
155160

156-
return m
161+
return m, nil
157162
}
158163

159164
// Run runs the static address loop-in manager.

staticaddr/withdraw/manager.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ type Manager struct {
138138
}
139139

140140
// NewManager creates a new deposit withdrawal manager.
141-
func NewManager(cfg *ManagerConfig, currentHeight uint32) *Manager {
141+
func NewManager(cfg *ManagerConfig, currentHeight uint32) (*Manager, error) {
142+
if currentHeight == 0 {
143+
return nil, fmt.Errorf("invalid current height %d",
144+
currentHeight)
145+
}
146+
142147
m := &Manager{
143148
cfg: cfg,
144149
finalizedWithdrawalTxns: make(map[chainhash.Hash]*wire.MsgTx),
@@ -148,7 +153,7 @@ func NewManager(cfg *ManagerConfig, currentHeight uint32) *Manager {
148153
}
149154
m.initiationHeight.Store(currentHeight)
150155

151-
return m
156+
return m, nil
152157
}
153158

154159
// Run runs the deposit withdrawal manager.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package withdraw
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
// TestNewManagerHeightValidation ensures the constructor rejects zero heights.
10+
func TestNewManagerHeightValidation(t *testing.T) {
11+
t.Parallel()
12+
13+
cfg := &ManagerConfig{}
14+
15+
_, err := NewManager(cfg, 0)
16+
require.ErrorContains(t, err, "invalid current height 0")
17+
18+
manager, err := NewManager(cfg, 1)
19+
require.NoError(t, err)
20+
require.NotNil(t, manager)
21+
}

0 commit comments

Comments
 (0)