Skip to content

Commit fab4a64

Browse files
authored
Merge pull request #967 from starius/neutrino-fixes
staticaddr: neutrino fixes
2 parents 2538055 + 51b7451 commit fab4a64

File tree

5 files changed

+61
-37
lines changed

5 files changed

+61
-37
lines changed

go.mod

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/btcsuite/btcd/btcutil v1.1.5
77
github.com/btcsuite/btcd/btcutil/psbt v1.1.10
88
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
9-
github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c // indirect
9+
github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318
1010
github.com/btcsuite/btcwallet v0.16.13
1111
github.com/btcsuite/btcwallet/wtxmgr v1.5.6
1212
github.com/davecgh/go-spew v1.1.1
@@ -36,15 +36,14 @@ require (
3636
github.com/urfave/cli v1.22.14
3737
go.etcd.io/bbolt v1.3.11
3838
golang.org/x/net v0.38.0
39+
golang.org/x/sync v0.12.0
3940
google.golang.org/grpc v1.64.1
4041
google.golang.org/protobuf v1.34.2
4142
gopkg.in/macaroon-bakery.v2 v2.3.0
4243
gopkg.in/macaroon.v2 v2.1.0
4344
modernc.org/sqlite v1.34.5
4445
)
4546

46-
require github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318
47-
4847
require (
4948
dario.cat/mergo v1.0.1 // indirect
5049
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
@@ -56,6 +55,7 @@ require (
5655
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
5756
github.com/aead/siphash v1.0.1 // indirect
5857
github.com/beorn7/perks v1.0.1 // indirect
58+
github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c // indirect
5959
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 // indirect
6060
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 // indirect
6161
github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5 // indirect
@@ -185,7 +185,6 @@ require (
185185
golang.org/x/crypto v0.36.0 // indirect
186186
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
187187
golang.org/x/mod v0.21.0 // indirect
188-
golang.org/x/sync v0.12.0 // indirect
189188
golang.org/x/sys v0.31.0 // indirect
190189
golang.org/x/term v0.30.0 // indirect
191190
golang.org/x/text v0.23.0 // indirect

loopd/daemon.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,10 +922,15 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
922922
}
923923
}()
924924

925+
// We need a higher timeout here, because withdrawalManager
926+
// publishes transactions and each PublishTransaction call can
927+
// wait for getting inv messages from a peer (neutrino).
928+
const withdrawalManagerTimeout = time.Minute
929+
925930
// Wait for the static address withdrawal manager to be ready
926931
// before starting the grpc server.
927932
timeOutCtx, cancel := context.WithTimeout(
928-
d.mainCtx, initManagerTimeout,
933+
d.mainCtx, withdrawalManagerTimeout,
929934
)
930935
select {
931936
case <-timeOutCtx.Done():

staticaddr/deposit/fsm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ func (f *FSM) updateDeposit(ctx context.Context,
399399

400400
err := f.cfg.Store.UpdateDeposit(ctx, f.deposit)
401401
if err != nil {
402-
f.Errorf("unable to update deposit: %w", err)
402+
f.Errorf("unable to update deposit: %v", err)
403403
}
404404
}
405405

staticaddr/withdraw/interface.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"github.com/lightninglabs/loop/staticaddr/address"
99
"github.com/lightninglabs/loop/staticaddr/deposit"
1010
"github.com/lightninglabs/loop/staticaddr/script"
11-
"github.com/lightningnetwork/lnd/lnwallet"
1211
)
1312

1413
// Store is the database interface that is used to store and retrieve
@@ -32,10 +31,6 @@ type AddressManager interface {
3231
// GetStaticAddress returns the deposit address for the given
3332
// client and server public keys.
3433
GetStaticAddress(ctx context.Context) (*script.StaticAddress, error)
35-
36-
// ListUnspent returns a list of utxos at the static address.
37-
ListUnspent(ctx context.Context, minConfs,
38-
maxConfs int32) ([]*lnwallet.Utxo, error)
3934
}
4035

4136
type DepositManager interface {

staticaddr/withdraw/manager.go

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/lightningnetwork/lnd/lntypes"
2727
"github.com/lightningnetwork/lnd/lnwallet"
2828
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
29+
"golang.org/x/sync/errgroup"
2930
)
3031

3132
var (
@@ -226,44 +227,65 @@ func (m *Manager) recoverWithdrawals(ctx context.Context) error {
226227
}
227228

228229
// Group the deposits by their finalized withdrawal transaction.
229-
depositsByWithdrawalTx := make(map[*wire.MsgTx][]*deposit.Deposit)
230+
depositsByWithdrawalTx := make(map[chainhash.Hash][]*deposit.Deposit)
231+
hash2tx := make(map[chainhash.Hash]*wire.MsgTx)
230232
for _, d := range activeDeposits {
231233
withdrawalTx := d.FinalizedWithdrawalTx
232234
if withdrawalTx == nil {
233235
continue
234236
}
237+
txid := withdrawalTx.TxHash()
238+
hash2tx[txid] = withdrawalTx
235239

236-
depositsByWithdrawalTx[withdrawalTx] = append(
237-
depositsByWithdrawalTx[withdrawalTx], d,
240+
depositsByWithdrawalTx[txid] = append(
241+
depositsByWithdrawalTx[txid], d,
238242
)
239243
}
240244

245+
// Publishing a transaction can take a while in neutrino mode, so
246+
// do it in parallel.
247+
eg := &errgroup.Group{}
248+
241249
// We can now reinstate each cluster of deposits for a withdrawal.
242-
for finalizedWithdrawalTx, deposits := range depositsByWithdrawalTx {
243-
tx := finalizedWithdrawalTx
244-
err = m.cfg.DepositManager.TransitionDeposits(
245-
ctx, deposits, deposit.OnWithdrawInitiated,
246-
deposit.Withdrawing,
247-
)
248-
if err != nil {
249-
return err
250-
}
250+
for txid, deposits := range depositsByWithdrawalTx {
251+
eg.Go(func() error {
252+
err := m.cfg.DepositManager.TransitionDeposits(
253+
ctx, deposits, deposit.OnWithdrawInitiated,
254+
deposit.Withdrawing,
255+
)
256+
if err != nil {
257+
return err
258+
}
251259

252-
_, err = m.publishFinalizedWithdrawalTx(ctx, tx)
253-
if err != nil {
254-
return err
255-
}
260+
tx, ok := hash2tx[txid]
261+
if !ok {
262+
return fmt.Errorf("can't find tx %v", txid)
263+
}
256264

257-
err = m.handleWithdrawal(
258-
ctx, deposits, tx.TxHash(), tx.TxOut[0].PkScript,
259-
)
260-
if err != nil {
261-
return err
262-
}
265+
_, err = m.publishFinalizedWithdrawalTx(ctx, tx)
266+
if err != nil {
267+
return err
268+
}
263269

264-
m.mu.Lock()
265-
m.finalizedWithdrawalTxns[tx.TxHash()] = tx
266-
m.mu.Unlock()
270+
err = m.handleWithdrawal(
271+
ctx, deposits, tx.TxHash(),
272+
tx.TxOut[0].PkScript,
273+
)
274+
if err != nil {
275+
return err
276+
}
277+
278+
m.mu.Lock()
279+
m.finalizedWithdrawalTxns[tx.TxHash()] = tx
280+
m.mu.Unlock()
281+
282+
return nil
283+
})
284+
}
285+
286+
// Wait for all goroutines to report back.
287+
if err := eg.Wait(); err != nil {
288+
return fmt.Errorf("error recovering withdrawals: %w", err)
267289
}
268290

269291
return nil
@@ -558,6 +580,9 @@ func (m *Manager) publishFinalizedWithdrawalTx(ctx context.Context,
558580
"withdrawal tx is nil")
559581
}
560582

583+
log.Debugf("Publishing deposit withdrawal with txid: %v ...",
584+
tx.TxHash())
585+
561586
txLabel := fmt.Sprintf("deposit-withdrawal-%v", tx.TxHash())
562587

563588
// Publish the withdrawal sweep transaction.
@@ -577,7 +602,7 @@ func (m *Manager) publishFinalizedWithdrawalTx(ctx context.Context,
577602
return false, nil
578603
}
579604
} else {
580-
log.Debugf("published deposit withdrawal with txid: %v",
605+
log.Debugf("Published deposit withdrawal with txid: %v",
581606
tx.TxHash())
582607
}
583608

0 commit comments

Comments
 (0)