From 34c9193bfc25a1c4cade0253dbe6da81dc142200 Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Tue, 10 Dec 2019 15:32:57 +0100 Subject: [PATCH] sweep: create wallet interface We need access to additional wallet functionality. This commit creates an interface to prevent passing in multiple function pointers. --- server.go | 8 ++++---- sweep/backend_mock_test.go | 21 ++++++++++++++++++++- sweep/interface.go | 12 ++++++++++++ sweep/sweeper.go | 9 ++++----- sweep/sweeper_test.go | 16 +++------------- 5 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 sweep/interface.go diff --git a/server.go b/server.go index 4c89aa47d..9e27b9ce5 100644 --- a/server.go +++ b/server.go @@ -792,10 +792,10 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, } s.sweeper = sweep.New(&sweep.UtxoSweeperConfig{ - FeeEstimator: cc.feeEstimator, - GenSweepScript: newSweepPkScriptGen(cc.wallet), - Signer: cc.wallet.Cfg.Signer, - PublishTransaction: cc.wallet.PublishTransaction, + FeeEstimator: cc.feeEstimator, + GenSweepScript: newSweepPkScriptGen(cc.wallet), + Signer: cc.wallet.Cfg.Signer, + Wallet: cc.wallet, NewBatchTimer: func() <-chan time.Time { return time.NewTimer(sweep.DefaultBatchWindowDuration).C }, diff --git a/sweep/backend_mock_test.go b/sweep/backend_mock_test.go index 43699be30..88132192b 100644 --- a/sweep/backend_mock_test.go +++ b/sweep/backend_mock_test.go @@ -2,6 +2,8 @@ package sweep import ( "sync" + "testing" + "time" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" @@ -11,6 +13,8 @@ import ( // mockBackend simulates a chain backend for realistic behaviour in unit tests // around double spends. type mockBackend struct { + t *testing.T + lock sync.Mutex notifier *MockNotifier @@ -19,14 +23,18 @@ type mockBackend struct { unconfirmedTxes map[chainhash.Hash]*wire.MsgTx unconfirmedSpendInputs map[wire.OutPoint]struct{} + + publishChan chan wire.MsgTx } -func newMockBackend(notifier *MockNotifier) *mockBackend { +func newMockBackend(t *testing.T, notifier *MockNotifier) *mockBackend { return &mockBackend{ + t: t, notifier: notifier, unconfirmedTxes: make(map[chainhash.Hash]*wire.MsgTx), confirmedSpendInputs: make(map[wire.OutPoint]struct{}), unconfirmedSpendInputs: make(map[wire.OutPoint]struct{}), + publishChan: make(chan wire.MsgTx, 2), } } @@ -65,6 +73,17 @@ func (b *mockBackend) publishTransaction(tx *wire.MsgTx) error { return nil } +func (b *mockBackend) PublishTransaction(tx *wire.MsgTx) error { + log.Tracef("Publishing tx %v", tx.TxHash()) + err := b.publishTransaction(tx) + select { + case b.publishChan <- *tx: + case <-time.After(defaultTestTimeout): + b.t.Fatalf("unexpected tx published") + } + return err +} + func (b *mockBackend) deleteUnconfirmed(txHash chainhash.Hash) { b.lock.Lock() defer b.lock.Unlock() diff --git a/sweep/interface.go b/sweep/interface.go new file mode 100644 index 000000000..fa35288e0 --- /dev/null +++ b/sweep/interface.go @@ -0,0 +1,12 @@ +package sweep + +import ( + "github.com/btcsuite/btcd/wire" +) + +// Wallet contains all wallet related functionality required by sweeper. +type Wallet interface { + // PublishTransaction performs cursory validation (dust checks, etc) and + // broadcasts the passed transaction to the Bitcoin network. + PublishTransaction(tx *wire.MsgTx) error +} diff --git a/sweep/sweeper.go b/sweep/sweeper.go index ffcb7ed35..2abebbb86 100644 --- a/sweep/sweeper.go +++ b/sweep/sweeper.go @@ -210,9 +210,8 @@ type UtxoSweeperConfig struct { // transaction. FeeEstimator chainfee.Estimator - // PublishTransaction facilitates the process of broadcasting a signed - // transaction to the appropriate network. - PublishTransaction func(*wire.MsgTx) error + // Wallet contains the wallet functions that sweeper requires. + Wallet Wallet // NewBatchTimer creates a channel that will be sent on when a certain // time window has passed. During this time window, new inputs can still @@ -321,7 +320,7 @@ func (s *UtxoSweeper) Start() error { // Error can be ignored. Because we are starting up, there are // no pending inputs to update based on the publish result. - err := s.cfg.PublishTransaction(lastTx) + err := s.cfg.Wallet.PublishTransaction(lastTx) if err != nil && err != lnwallet.ErrDoubleSpend { log.Errorf("last tx publish: %v", err) } @@ -886,7 +885,7 @@ func (s *UtxoSweeper) sweep(inputs inputSet, feeRate chainfee.SatPerKWeight, }), ) - err = s.cfg.PublishTransaction(tx) + err = s.cfg.Wallet.PublishTransaction(tx) // In case of an unexpected error, don't try to recover. if err != nil && err != lnwallet.ErrDoubleSpend { diff --git a/sweep/sweeper_test.go b/sweep/sweeper_test.go index 8f9d3d7f3..9e5aa5f4b 100644 --- a/sweep/sweeper_test.go +++ b/sweep/sweeper_test.go @@ -98,14 +98,13 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext { store := NewMockSweeperStore() - backend := newMockBackend(notifier) + backend := newMockBackend(t, notifier) estimator := newMockFeeEstimator(10000, chainfee.FeePerKwFloor) - publishChan := make(chan wire.MsgTx, 2) ctx := &sweeperTestContext{ notifier: notifier, - publishChan: publishChan, + publishChan: backend.publishChan, t: t, estimator: estimator, backend: backend, @@ -116,16 +115,7 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext { var outputScriptCount byte ctx.sweeper = New(&UtxoSweeperConfig{ Notifier: notifier, - PublishTransaction: func(tx *wire.MsgTx) error { - log.Tracef("Publishing tx %v", tx.TxHash()) - err := backend.publishTransaction(tx) - select { - case publishChan <- *tx: - case <-time.After(defaultTestTimeout): - t.Fatalf("unexpected tx published") - } - return err - }, + Wallet: backend, NewBatchTimer: func() <-chan time.Time { c := make(chan time.Time, 1) ctx.timeoutChan <- c