github.com/decred/dcrlnd@v0.7.6/sweep/sweeper_test.go (about)

     1  package sweep
     2  
     3  import (
     4  	"os"
     5  	"reflect"
     6  	"runtime/debug"
     7  	"runtime/pprof"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/davecgh/go-spew/spew"
    12  	"github.com/decred/dcrd/chaincfg/chainhash"
    13  	"github.com/decred/dcrd/chaincfg/v3"
    14  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
    15  	"github.com/decred/dcrd/dcrutil/v4"
    16  	"github.com/decred/dcrd/txscript/v4"
    17  	"github.com/decred/dcrd/wire"
    18  	"github.com/decred/dcrlnd/build"
    19  	"github.com/decred/dcrlnd/input"
    20  	"github.com/decred/dcrlnd/keychain"
    21  	"github.com/decred/dcrlnd/lntest/mock"
    22  	"github.com/decred/dcrlnd/lnwallet"
    23  	"github.com/decred/dcrlnd/lnwallet/chainfee"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  var (
    28  	testLog = build.NewSubLogger("SWPR_TEST", nil)
    29  
    30  	testMaxSweepAttempts = 3
    31  
    32  	testMaxInputsPerTx = 3
    33  
    34  	defaultFeePref = Params{Fee: FeePreference{ConfTarget: 1}}
    35  )
    36  
    37  type sweeperTestContext struct {
    38  	t *testing.T
    39  
    40  	sweeper   *UtxoSweeper
    41  	notifier  *MockNotifier
    42  	estimator *mockFeeEstimator
    43  	backend   *mockBackend
    44  	store     *MockSweeperStore
    45  
    46  	timeoutChan chan chan time.Time
    47  	publishChan chan wire.MsgTx
    48  }
    49  
    50  var (
    51  	spendableInputs []*input.BaseInput
    52  	testInputCount  int
    53  
    54  	testPubKey, _ = secp256k1.ParsePubKey([]byte{
    55  		0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    56  		0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    57  		0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    58  		0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    59  		0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    60  		0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    61  		0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
    62  		0xb4, 0x12, 0xa3,
    63  	})
    64  )
    65  
    66  func createTestInput(value int64, witnessType input.WitnessType) input.BaseInput {
    67  	hash := chainhash.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    68  		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    69  		byte(testInputCount + 1)}
    70  
    71  	input := input.MakeBaseInput(
    72  		&wire.OutPoint{
    73  			Hash: hash,
    74  		},
    75  		witnessType,
    76  		&input.SignDescriptor{
    77  			Output: &wire.TxOut{
    78  				Value: value,
    79  			},
    80  			KeyDesc: keychain.KeyDescriptor{
    81  				PubKey: testPubKey,
    82  			},
    83  		},
    84  		0,
    85  		nil,
    86  	)
    87  
    88  	testInputCount++
    89  
    90  	return input
    91  }
    92  
    93  func init() {
    94  	// Create a set of test spendable inputs.
    95  	for i := 0; i < 20; i++ {
    96  		input := createTestInput(int64(10000+i*500),
    97  			input.CommitmentTimeLock)
    98  
    99  		spendableInputs = append(spendableInputs, &input)
   100  	}
   101  }
   102  
   103  func createSweeperTestContext(t *testing.T) *sweeperTestContext {
   104  	notifier := NewMockNotifier(t)
   105  
   106  	store := NewMockSweeperStore()
   107  
   108  	backend := newMockBackend(t, notifier)
   109  	backend.walletUtxos = []*lnwallet.Utxo{
   110  		{
   111  			Value:       dcrutil.Amount(1_000_000),
   112  			AddressType: lnwallet.PubKeyHash,
   113  		},
   114  	}
   115  
   116  	estimator := newMockFeeEstimator(10000, chainfee.FeePerKBFloor)
   117  
   118  	ctx := &sweeperTestContext{
   119  		notifier:    notifier,
   120  		publishChan: backend.publishChan,
   121  		t:           t,
   122  		estimator:   estimator,
   123  		backend:     backend,
   124  		store:       store,
   125  		timeoutChan: make(chan chan time.Time, 1),
   126  	}
   127  
   128  	var outputScriptCount byte
   129  	ctx.sweeper = New(&UtxoSweeperConfig{
   130  		Notifier: notifier,
   131  		Wallet:   backend,
   132  		NewBatchTimer: func() <-chan time.Time {
   133  			c := make(chan time.Time, 1)
   134  			ctx.timeoutChan <- c
   135  			return c
   136  		},
   137  		Store:  store,
   138  		Signer: &mock.DummySigner{},
   139  		GenSweepScript: func() ([]byte, error) {
   140  			outputScriptCount++
   141  			return input.GenerateP2PKH([]byte{outputScriptCount})
   142  		},
   143  		FeeEstimator:     estimator,
   144  		MaxInputsPerTx:   testMaxInputsPerTx,
   145  		MaxSweepAttempts: testMaxSweepAttempts,
   146  		NextAttemptDeltaFunc: func(attempts int) int32 {
   147  			// Use delta func without random factor.
   148  			return 1 << uint(attempts-1)
   149  		},
   150  		NetParams:         chaincfg.RegNetParams(),
   151  		MaxFeeRate:        DefaultMaxFeeRate,
   152  		FeeRateBucketSize: DefaultFeeRateBucketSize,
   153  	})
   154  
   155  	ctx.sweeper.Start()
   156  
   157  	return ctx
   158  }
   159  
   160  func (ctx *sweeperTestContext) restartSweeper() {
   161  	ctx.t.Helper()
   162  
   163  	ctx.sweeper.Stop()
   164  	ctx.sweeper = New(ctx.sweeper.cfg)
   165  	ctx.sweeper.Start()
   166  }
   167  
   168  func (ctx *sweeperTestContext) tick() {
   169  	testLog.Trace("Waiting for tick to be consumed")
   170  	select {
   171  	case c := <-ctx.timeoutChan:
   172  		select {
   173  		case c <- time.Time{}:
   174  			testLog.Trace("Tick")
   175  		case <-time.After(defaultTestTimeout):
   176  			debug.PrintStack()
   177  			ctx.t.Fatal("tick timeout - tick not consumed")
   178  		}
   179  	case <-time.After(defaultTestTimeout):
   180  		debug.PrintStack()
   181  		ctx.t.Fatal("tick timeout - no new timer created")
   182  	}
   183  }
   184  
   185  // assertNoTick asserts that the sweeper does not wait for a tick.
   186  func (ctx *sweeperTestContext) assertNoTick() {
   187  	ctx.t.Helper()
   188  
   189  	select {
   190  	case <-ctx.timeoutChan:
   191  		ctx.t.Fatal("unexpected tick")
   192  
   193  	case <-time.After(processingDelay):
   194  	}
   195  }
   196  
   197  func (ctx *sweeperTestContext) assertNoNewTimer() {
   198  	select {
   199  	case <-ctx.timeoutChan:
   200  		ctx.t.Fatal("no new timer expected")
   201  	default:
   202  	}
   203  }
   204  
   205  func (ctx *sweeperTestContext) finish(expectedGoroutineCount int) {
   206  	// We assume that when finish is called, sweeper has finished all its
   207  	// goroutines. This implies that the waitgroup is empty.
   208  	signalChan := make(chan struct{})
   209  	go func() {
   210  		ctx.sweeper.wg.Wait()
   211  		close(signalChan)
   212  	}()
   213  
   214  	// Simulate exits of the expected number of running goroutines.
   215  	for i := 0; i < expectedGoroutineCount; i++ {
   216  		ctx.sweeper.wg.Done()
   217  	}
   218  
   219  	// We now expect the Wait to succeed.
   220  	select {
   221  	case <-signalChan:
   222  	case <-time.After(time.Second):
   223  		pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
   224  
   225  		ctx.t.Fatalf("lingering goroutines detected after test " +
   226  			"is finished")
   227  	}
   228  
   229  	// Restore waitgroup state to what it was before.
   230  	ctx.sweeper.wg.Add(expectedGoroutineCount)
   231  
   232  	// Stop sweeper.
   233  	ctx.sweeper.Stop()
   234  
   235  	// We should have consumed and asserted all published transactions in
   236  	// our unit tests.
   237  	ctx.assertNoTx()
   238  	ctx.assertNoNewTimer()
   239  	if !ctx.backend.isDone() {
   240  		ctx.t.Fatal("unconfirmed txes remaining")
   241  	}
   242  }
   243  
   244  func (ctx *sweeperTestContext) assertNoTx() {
   245  	ctx.t.Helper()
   246  	select {
   247  	case <-ctx.publishChan:
   248  		ctx.t.Fatalf("unexpected transactions published")
   249  	default:
   250  	}
   251  }
   252  
   253  func (ctx *sweeperTestContext) receiveTx() wire.MsgTx {
   254  	ctx.t.Helper()
   255  	var tx wire.MsgTx
   256  	select {
   257  	case tx = <-ctx.publishChan:
   258  		return tx
   259  	case <-time.After(5 * time.Second):
   260  		pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
   261  
   262  		ctx.t.Fatalf("tx not published")
   263  	}
   264  	return tx
   265  }
   266  
   267  func (ctx *sweeperTestContext) expectResult(c chan Result, expected error) {
   268  	ctx.t.Helper()
   269  	select {
   270  	case result := <-c:
   271  		if result.Err != expected {
   272  			ctx.t.Fatalf("expected %v result, but got %v",
   273  				expected, result.Err,
   274  			)
   275  		}
   276  	case <-time.After(defaultTestTimeout):
   277  		ctx.t.Fatalf("no result received")
   278  	}
   279  }
   280  
   281  func (ctx *sweeperTestContext) assertPendingInputs(inputs ...input.Input) {
   282  	ctx.t.Helper()
   283  
   284  	inputSet := make(map[wire.OutPoint]struct{}, len(inputs))
   285  	for _, input := range inputs {
   286  		inputSet[*input.OutPoint()] = struct{}{}
   287  	}
   288  
   289  	pendingInputs, err := ctx.sweeper.PendingInputs()
   290  	if err != nil {
   291  		ctx.t.Fatal(err)
   292  	}
   293  	if len(pendingInputs) != len(inputSet) {
   294  		ctx.t.Fatalf("expected %d pending inputs, got %d",
   295  			len(inputSet), len(pendingInputs))
   296  	}
   297  	for input := range pendingInputs {
   298  		if _, ok := inputSet[input]; !ok {
   299  			ctx.t.Fatalf("found unexpected input %v", input)
   300  		}
   301  	}
   302  }
   303  
   304  // assertTxSweepsInputs ensures that the transaction returned within the value
   305  // received from resultChan spends the given inputs.
   306  func assertTxSweepsInputs(t *testing.T, sweepTx *wire.MsgTx,
   307  	inputs ...input.Input) {
   308  
   309  	t.Helper()
   310  
   311  	if len(sweepTx.TxIn) != len(inputs) {
   312  		t.Fatalf("expected sweep tx to contain %d inputs, got %d",
   313  			len(inputs), len(sweepTx.TxIn))
   314  	}
   315  	m := make(map[wire.OutPoint]struct{}, len(inputs))
   316  	for _, input := range inputs {
   317  		m[*input.OutPoint()] = struct{}{}
   318  	}
   319  	for _, txIn := range sweepTx.TxIn {
   320  		if _, ok := m[txIn.PreviousOutPoint]; !ok {
   321  			t.Fatalf("expected tx %v to spend input %v",
   322  				txIn.PreviousOutPoint, sweepTx.TxHash())
   323  		}
   324  	}
   325  }
   326  
   327  // assertTxFeeRate asserts that the transaction was created with the given
   328  // inputs and fee rate.
   329  //
   330  // NOTE: This assumes that transactions only have one output, as this is the
   331  // only type of transaction the UtxoSweeper can create at the moment.
   332  func assertTxFeeRate(t *testing.T, tx *wire.MsgTx,
   333  	expectedFeeRate chainfee.AtomPerKByte, inputs ...input.Input) {
   334  
   335  	t.Helper()
   336  
   337  	if len(tx.TxIn) != len(inputs) {
   338  		t.Fatalf("expected %d inputs, got %d", len(tx.TxIn), len(inputs))
   339  	}
   340  
   341  	m := make(map[wire.OutPoint]input.Input, len(inputs))
   342  	for _, input := range inputs {
   343  		m[*input.OutPoint()] = input
   344  	}
   345  
   346  	var inputAmt int64
   347  	for _, txIn := range tx.TxIn {
   348  		input, ok := m[txIn.PreviousOutPoint]
   349  		if !ok {
   350  			t.Fatalf("expected input %v to be provided",
   351  				txIn.PreviousOutPoint)
   352  		}
   353  		inputAmt += input.SignDesc().Output.Value
   354  	}
   355  	outputAmt := tx.TxOut[0].Value
   356  
   357  	fee := dcrutil.Amount(inputAmt - outputAmt)
   358  	_, estimator := getSizeEstimate(inputs, nil, 0)
   359  	txSize := estimator.size()
   360  
   361  	expectedFee := expectedFeeRate.FeeForSize(int64(txSize))
   362  	if fee != expectedFee {
   363  		t.Fatalf("expected fee rate %v results in %v fee, got %v fee",
   364  			expectedFeeRate, expectedFee, fee)
   365  	}
   366  }
   367  
   368  // TestSuccess tests the sweeper happy flow.
   369  func TestSuccess(t *testing.T) {
   370  	ctx := createSweeperTestContext(t)
   371  
   372  	// Sweeping an input without a fee preference should result in an error.
   373  	_, err := ctx.sweeper.SweepInput(spendableInputs[0], Params{})
   374  	if err != ErrNoFeePreference {
   375  		t.Fatalf("expected ErrNoFeePreference, got %v", err)
   376  	}
   377  
   378  	resultChan, err := ctx.sweeper.SweepInput(
   379  		spendableInputs[0], defaultFeePref,
   380  	)
   381  	if err != nil {
   382  		t.Fatal(err)
   383  	}
   384  
   385  	ctx.tick()
   386  
   387  	sweepTx := ctx.receiveTx()
   388  
   389  	ctx.backend.mine()
   390  
   391  	select {
   392  	case result := <-resultChan:
   393  		if result.Err != nil {
   394  			t.Fatalf("expected successful spend, but received "+
   395  				"error %v instead", result.Err)
   396  		}
   397  		if result.Tx.TxHash() != sweepTx.TxHash() {
   398  			t.Fatalf("expected sweep tx ")
   399  		}
   400  	case <-time.After(5 * time.Second):
   401  		t.Fatalf("no result received")
   402  	}
   403  
   404  	ctx.finish(1)
   405  
   406  	// Assert that last tx is stored in the database so we can republish
   407  	// on restart.
   408  	lastTx, err := ctx.store.GetLastPublishedTx()
   409  	if err != nil {
   410  		t.Fatal(err)
   411  	}
   412  	if lastTx == nil || sweepTx.TxHash() != lastTx.TxHash() {
   413  		t.Fatalf("last tx not stored")
   414  	}
   415  }
   416  
   417  // TestDust asserts that inputs that are not big enough to raise above the dust
   418  // limit, are held back until the total set does surpass the limit.
   419  func TestDust(t *testing.T) {
   420  	ctx := createSweeperTestContext(t)
   421  
   422  	// Calculate the dust limit for the test relay fee (1000 atoms/kB).
   423  	dustLimit := int64(lnwallet.DustThresholdForRelayFee(1000))
   424  
   425  	// Estimate the size of a transaction that will sweep a
   426  	// CommitmentTimeLock output and pay to a P2PKH output.
   427  	var se input.TxSizeEstimator
   428  	se.AddP2PKHOutput()
   429  	se.AddCustomInput(input.ToLocalTimeoutSigScriptSize)
   430  	txSize := se.Size()
   431  
   432  	// Calculate the fee to relay this tx, given the test relay fee of
   433  	// 10000 atoms/kB.
   434  	txFee := int64(chainfee.AtomPerKByte(10000).FeeForSize(txSize))
   435  
   436  	// Calculate the maximum value an output in this type of tx can have,
   437  	// after which it will no longer be considered dust.
   438  	maxDustOutputValue := txFee + dustLimit - 1
   439  
   440  	// Now create an input exactly at this dust limit. While positive, this
   441  	// won't be swept immediately due to the resulting tx having an output
   442  	// value lower than the dust limit.
   443  	dustInput := createTestInput(maxDustOutputValue, input.CommitmentTimeLock)
   444  	_, err := ctx.sweeper.SweepInput(&dustInput, defaultFeePref)
   445  	if err != nil {
   446  		t.Fatal(err)
   447  	}
   448  
   449  	// No sweep transaction is expected now. The sweeper should recognize
   450  	// that the sweep output will not be relayed and not generate the tx.
   451  	// It isn't possible to attach a wallet utxo either, because the added
   452  	// size would create a negatively yielding transaction at this fee
   453  	// rate.
   454  
   455  	// Sweep another input that brings the tx output above the dust limit.
   456  	// We'll create an output with 10 times the maximum considered dust -
   457  	// more than enough to sweep both the earlier dust input and this new
   458  	// one.
   459  	largeInput := createTestInput(maxDustOutputValue*10,
   460  		input.CommitmentTimeLock)
   461  
   462  	_, err = ctx.sweeper.SweepInput(&largeInput, defaultFeePref)
   463  	if err != nil {
   464  		t.Fatal(err)
   465  	}
   466  
   467  	ctx.tick()
   468  
   469  	// The second input brings the sweep output above the dust limit. We
   470  	// expect a sweep tx now.
   471  
   472  	sweepTx := ctx.receiveTx()
   473  	if len(sweepTx.TxIn) != 2 {
   474  		t.Fatalf("Expected tx to sweep 2 inputs, but contains %v "+
   475  			"inputs instead", len(sweepTx.TxIn))
   476  	}
   477  
   478  	ctx.backend.mine()
   479  
   480  	ctx.finish(1)
   481  }
   482  
   483  // TestWalletUtxo asserts that inputs that are not big enough to raise above the
   484  // dust limit are accompanied by a wallet utxo to make them sweepable.
   485  func TestWalletUtxo(t *testing.T) {
   486  	ctx := createSweeperTestContext(t)
   487  
   488  	// Sweeping a single output produces a tx of 217 bytes. At the fee
   489  	// floor, the sweep tx will pay 217*1e4/1000 = 2070 atoms in fees.
   490  	//
   491  	// Create an input so that the output after paying fees is still
   492  	// positive (1730 atoms), but less than the dust limit (6030 atoms) for
   493  	// the sweep tx output script (P2PKH).
   494  	//
   495  	// What we now expect is that the sweeper will attach a utxo from the
   496  	// wallet. This increases the tx size to 383 bytes with a fee of 3830
   497  	// atoms.  The tx yield becomes then 3900+10000-3830 = 10070 atoms.
   498  	dustInput := createTestInput(3900, input.PublicKeyHash)
   499  
   500  	_, err := ctx.sweeper.SweepInput(
   501  		&dustInput,
   502  		Params{Fee: FeePreference{FeeRate: chainfee.FeePerKBFloor}},
   503  	)
   504  	if err != nil {
   505  		t.Fatal(err)
   506  	}
   507  
   508  	ctx.tick()
   509  
   510  	sweepTx := ctx.receiveTx()
   511  	if len(sweepTx.TxIn) != 2 {
   512  		t.Fatalf("Expected tx to sweep 2 inputs, but contains %v "+
   513  			"inputs instead", len(sweepTx.TxIn))
   514  	}
   515  
   516  	// Calculate expected output value based on wallet utxo of 10000 sats.
   517  	expectedOutputValue := int64(3900 + 1_000_000 - 3830)
   518  	if sweepTx.TxOut[0].Value != expectedOutputValue {
   519  		t.Fatalf("Expected output value of %v, but got %v",
   520  			expectedOutputValue, sweepTx.TxOut[0].Value)
   521  	}
   522  
   523  	ctx.backend.mine()
   524  	ctx.finish(1)
   525  }
   526  
   527  // TestNegativeInput asserts that no inputs with a negative yield are swept.
   528  // Negative yield means that the value minus the added fee is negative.
   529  func TestNegativeInput(t *testing.T) {
   530  	ctx := createSweeperTestContext(t)
   531  
   532  	// Increase the default fee rate so that we can perform the test. This
   533  	// is necessary in decred due to lower minimum relay fee.
   534  	ctx.estimator.updateFees(25000, 10000)
   535  
   536  	// Sweep an input large enough to cover fees, so in any case the tx
   537  	// output will be above the dust limit.
   538  	largeInput := createTestInput(20000000, input.CommitmentNoDelay)
   539  	largeInputResult, err := ctx.sweeper.SweepInput(
   540  		&largeInput, defaultFeePref,
   541  	)
   542  	if err != nil {
   543  		t.Fatal(err)
   544  	}
   545  
   546  	// Sweep an additional input with a negative net yield. The size of the
   547  	// HtlcOfferedRemoteTimeout input type adds more in fees than its value
   548  	// at the current fee level.
   549  	negInput := createTestInput(5500, input.HtlcOfferedRemoteTimeout)
   550  	negInputResult, err := ctx.sweeper.SweepInput(&negInput, defaultFeePref)
   551  	if err != nil {
   552  		t.Fatal(err)
   553  	}
   554  
   555  	// Sweep a third input that has a smaller output than the previous one,
   556  	// but yields positively because of its lower size.
   557  	positiveInput := createTestInput(5000, input.CommitmentNoDelay)
   558  	positiveInputResult, err := ctx.sweeper.SweepInput(
   559  		&positiveInput, defaultFeePref,
   560  	)
   561  	if err != nil {
   562  		t.Fatal(err)
   563  	}
   564  
   565  	ctx.tick()
   566  
   567  	// We expect that a sweep tx is published now, but it should only
   568  	// contain the large input. The negative input should stay out of sweeps
   569  	// until fees come down to get a positive net yield.
   570  	sweepTx1 := ctx.receiveTx()
   571  	assertTxSweepsInputs(t, &sweepTx1, &largeInput, &positiveInput)
   572  
   573  	ctx.backend.mine()
   574  
   575  	ctx.expectResult(largeInputResult, nil)
   576  	ctx.expectResult(positiveInputResult, nil)
   577  
   578  	// Lower fee rate so that the negative input is no longer negative.
   579  	ctx.estimator.updateFees(10000, 10000)
   580  
   581  	// Create another large input.
   582  	secondLargeInput := createTestInput(100000, input.CommitmentNoDelay)
   583  	secondLargeInputResult, err := ctx.sweeper.SweepInput(
   584  		&secondLargeInput, defaultFeePref,
   585  	)
   586  	if err != nil {
   587  		t.Fatal(err)
   588  	}
   589  
   590  	ctx.tick()
   591  
   592  	sweepTx2 := ctx.receiveTx()
   593  	assertTxSweepsInputs(t, &sweepTx2, &secondLargeInput, &negInput)
   594  
   595  	ctx.backend.mine()
   596  
   597  	ctx.expectResult(secondLargeInputResult, nil)
   598  	ctx.expectResult(negInputResult, nil)
   599  
   600  	ctx.finish(1)
   601  }
   602  
   603  // TestChunks asserts that large sets of inputs are split into multiple txes.
   604  func TestChunks(t *testing.T) {
   605  	ctx := createSweeperTestContext(t)
   606  
   607  	// Sweep five inputs.
   608  	for _, input := range spendableInputs[:5] {
   609  		_, err := ctx.sweeper.SweepInput(input, defaultFeePref)
   610  		if err != nil {
   611  			t.Fatal(err)
   612  		}
   613  	}
   614  
   615  	ctx.tick()
   616  
   617  	// We expect two txes to be published because of the max input count of
   618  	// three.
   619  	sweepTx1 := ctx.receiveTx()
   620  	if len(sweepTx1.TxIn) != 3 {
   621  		t.Fatalf("Expected first tx to sweep 3 inputs, but contains %v "+
   622  			"inputs instead", len(sweepTx1.TxIn))
   623  	}
   624  
   625  	sweepTx2 := ctx.receiveTx()
   626  	if len(sweepTx2.TxIn) != 2 {
   627  		t.Fatalf("Expected first tx to sweep 2 inputs, but contains %v "+
   628  			"inputs instead", len(sweepTx1.TxIn))
   629  	}
   630  
   631  	ctx.backend.mine()
   632  
   633  	ctx.finish(1)
   634  }
   635  
   636  // TestRemoteSpend asserts that remote spends are properly detected and handled
   637  // both before the sweep is published as well as after.
   638  func TestRemoteSpend(t *testing.T) {
   639  	t.Run("pre-sweep", func(t *testing.T) {
   640  		testRemoteSpend(t, false)
   641  	})
   642  	t.Run("post-sweep", func(t *testing.T) {
   643  		testRemoteSpend(t, true)
   644  	})
   645  }
   646  
   647  func testRemoteSpend(t *testing.T, postSweep bool) {
   648  	ctx := createSweeperTestContext(t)
   649  
   650  	resultChan1, err := ctx.sweeper.SweepInput(
   651  		spendableInputs[0], defaultFeePref,
   652  	)
   653  	if err != nil {
   654  		t.Fatal(err)
   655  	}
   656  
   657  	resultChan2, err := ctx.sweeper.SweepInput(
   658  		spendableInputs[1], defaultFeePref,
   659  	)
   660  	if err != nil {
   661  		t.Fatal(err)
   662  	}
   663  
   664  	// Spend the input with an unknown tx.
   665  	remoteTx := &wire.MsgTx{
   666  		TxIn: []*wire.TxIn{
   667  			{
   668  				PreviousOutPoint: *(spendableInputs[0].OutPoint()),
   669  			},
   670  		},
   671  	}
   672  	err = ctx.backend.publishTransaction(remoteTx)
   673  	if err != nil {
   674  		t.Fatal(err)
   675  	}
   676  
   677  	if postSweep {
   678  		ctx.tick()
   679  
   680  		// Tx publication by sweeper returns ErrDoubleSpend. Sweeper
   681  		// will retry the inputs without reporting a result. It could be
   682  		// spent by the remote party.
   683  		ctx.receiveTx()
   684  	}
   685  
   686  	ctx.backend.mine()
   687  
   688  	select {
   689  	case result := <-resultChan1:
   690  		if result.Err != ErrRemoteSpend {
   691  			t.Fatalf("expected remote spend")
   692  		}
   693  		if result.Tx.TxHash() != remoteTx.TxHash() {
   694  			t.Fatalf("expected remote spend tx")
   695  		}
   696  	case <-time.After(5 * time.Second):
   697  		t.Fatalf("no result received")
   698  	}
   699  
   700  	if !postSweep {
   701  		// Assert that the sweeper sweeps the remaining input.
   702  		ctx.tick()
   703  		sweepTx := ctx.receiveTx()
   704  
   705  		if len(sweepTx.TxIn) != 1 {
   706  			t.Fatal("expected sweep to only sweep the one remaining output")
   707  		}
   708  
   709  		ctx.backend.mine()
   710  
   711  		ctx.expectResult(resultChan2, nil)
   712  
   713  		ctx.finish(1)
   714  	} else {
   715  		// Expected sweeper to be still listening for spend of the
   716  		// error input.
   717  		ctx.finish(2)
   718  
   719  		select {
   720  		case <-resultChan2:
   721  			t.Fatalf("no result expected for error input")
   722  		default:
   723  		}
   724  	}
   725  }
   726  
   727  // TestIdempotency asserts that offering the same input multiple times is
   728  // handled correctly.
   729  func TestIdempotency(t *testing.T) {
   730  	ctx := createSweeperTestContext(t)
   731  
   732  	input := spendableInputs[0]
   733  	resultChan1, err := ctx.sweeper.SweepInput(input, defaultFeePref)
   734  	if err != nil {
   735  		t.Fatal(err)
   736  	}
   737  
   738  	resultChan2, err := ctx.sweeper.SweepInput(input, defaultFeePref)
   739  	if err != nil {
   740  		t.Fatal(err)
   741  	}
   742  
   743  	ctx.tick()
   744  
   745  	ctx.receiveTx()
   746  
   747  	resultChan3, err := ctx.sweeper.SweepInput(input, defaultFeePref)
   748  	if err != nil {
   749  		t.Fatal(err)
   750  	}
   751  
   752  	// Spend the input of the sweep tx.
   753  	ctx.backend.mine()
   754  
   755  	ctx.expectResult(resultChan1, nil)
   756  	ctx.expectResult(resultChan2, nil)
   757  	ctx.expectResult(resultChan3, nil)
   758  
   759  	// Offer the same input again. The sweeper will register a spend ntfn
   760  	// for this input. Because the input has already been spent, it will
   761  	// immediately receive the spend notification with a spending tx hash.
   762  	// Because the sweeper kept track of all of its sweep txes, it will
   763  	// recognize the spend as its own.
   764  	resultChan4, err := ctx.sweeper.SweepInput(input, defaultFeePref)
   765  	if err != nil {
   766  		t.Fatal(err)
   767  	}
   768  	ctx.expectResult(resultChan4, nil)
   769  
   770  	// Timer is still running, but spend notification was delivered before
   771  	// it expired.
   772  	ctx.tick()
   773  
   774  	ctx.finish(1)
   775  }
   776  
   777  // TestNoInputs asserts that nothing happens if nothing happens.
   778  func TestNoInputs(t *testing.T) {
   779  	ctx := createSweeperTestContext(t)
   780  
   781  	// No tx should appear. This is asserted in finish().
   782  	ctx.finish(1)
   783  }
   784  
   785  // TestRestart asserts that the sweeper picks up sweeping properly after
   786  // a restart.
   787  func TestRestart(t *testing.T) {
   788  	ctx := createSweeperTestContext(t)
   789  
   790  	// Sweep input and expect sweep tx.
   791  	input1 := spendableInputs[0]
   792  	if _, err := ctx.sweeper.SweepInput(input1, defaultFeePref); err != nil {
   793  		t.Fatal(err)
   794  	}
   795  	ctx.tick()
   796  
   797  	ctx.receiveTx()
   798  
   799  	// Restart sweeper.
   800  	ctx.restartSweeper()
   801  
   802  	// Expect last tx to be republished.
   803  	ctx.receiveTx()
   804  
   805  	// Simulate other subsystem (e.g. contract resolver) re-offering inputs.
   806  	spendChan1, err := ctx.sweeper.SweepInput(input1, defaultFeePref)
   807  	if err != nil {
   808  		t.Fatal(err)
   809  	}
   810  
   811  	input2 := spendableInputs[1]
   812  	spendChan2, err := ctx.sweeper.SweepInput(input2, defaultFeePref)
   813  	if err != nil {
   814  		t.Fatal(err)
   815  	}
   816  
   817  	// Spend inputs of sweep txes and verify that spend channels signal
   818  	// spends.
   819  	ctx.backend.mine()
   820  
   821  	// Sweeper should recognize that its sweep tx of the previous run is
   822  	// spending the input.
   823  	select {
   824  	case result := <-spendChan1:
   825  		if result.Err != nil {
   826  			t.Fatalf("expected successful sweep")
   827  		}
   828  	case <-time.After(defaultTestTimeout):
   829  		t.Fatalf("no result received")
   830  	}
   831  
   832  	// Timer tick should trigger republishing a sweep for the remaining
   833  	// input.
   834  	ctx.tick()
   835  
   836  	ctx.receiveTx()
   837  
   838  	ctx.backend.mine()
   839  
   840  	select {
   841  	case result := <-spendChan2:
   842  		if result.Err != nil {
   843  			t.Fatalf("expected successful sweep")
   844  		}
   845  	case <-time.After(defaultTestTimeout):
   846  		t.Fatalf("no result received")
   847  	}
   848  
   849  	// Restart sweeper again. No action is expected.
   850  	ctx.restartSweeper()
   851  
   852  	// Expect last tx to be republished.
   853  	ctx.receiveTx()
   854  
   855  	ctx.finish(1)
   856  }
   857  
   858  // TestRestartRemoteSpend asserts that the sweeper picks up sweeping properly after
   859  // a restart with remote spend.
   860  func TestRestartRemoteSpend(t *testing.T) {
   861  
   862  	ctx := createSweeperTestContext(t)
   863  
   864  	// Sweep input.
   865  	input1 := spendableInputs[0]
   866  	if _, err := ctx.sweeper.SweepInput(input1, defaultFeePref); err != nil {
   867  		t.Fatal(err)
   868  	}
   869  
   870  	// Sweep another input.
   871  	input2 := spendableInputs[1]
   872  	if _, err := ctx.sweeper.SweepInput(input2, defaultFeePref); err != nil {
   873  		t.Fatal(err)
   874  	}
   875  
   876  	ctx.tick()
   877  
   878  	sweepTx := ctx.receiveTx()
   879  
   880  	// Restart sweeper.
   881  	ctx.restartSweeper()
   882  
   883  	// Expect last tx to be republished.
   884  	ctx.receiveTx()
   885  
   886  	// Replace the sweep tx with a remote tx spending input 1.
   887  	ctx.backend.deleteUnconfirmed(sweepTx.TxHash())
   888  
   889  	remoteTx := &wire.MsgTx{
   890  		TxIn: []*wire.TxIn{
   891  			{
   892  				PreviousOutPoint: *(input2.OutPoint()),
   893  			},
   894  		},
   895  	}
   896  	if err := ctx.backend.publishTransaction(remoteTx); err != nil {
   897  		t.Fatal(err)
   898  	}
   899  
   900  	// Mine remote spending tx.
   901  	ctx.backend.mine()
   902  
   903  	// Simulate other subsystem (e.g. contract resolver) re-offering input 0.
   904  	spendChan, err := ctx.sweeper.SweepInput(input1, defaultFeePref)
   905  	if err != nil {
   906  		t.Fatal(err)
   907  	}
   908  
   909  	// Notify of a new block so the sweeper re-attempts an input from its
   910  	// last tx.
   911  	ctx.notifier.NotifyEpoch(1000)
   912  
   913  	// Expect sweeper to construct a new tx, because input 1 was spend
   914  	// remotely.
   915  	ctx.tick()
   916  
   917  	ctx.receiveTx()
   918  
   919  	ctx.backend.mine()
   920  
   921  	ctx.expectResult(spendChan, nil)
   922  
   923  	ctx.finish(1)
   924  }
   925  
   926  // TestRestartConfirmed asserts that the sweeper picks up sweeping properly after
   927  // a restart with a confirm of our own sweep tx.
   928  func TestRestartConfirmed(t *testing.T) {
   929  	ctx := createSweeperTestContext(t)
   930  
   931  	// Sweep input.
   932  	input := spendableInputs[0]
   933  	if _, err := ctx.sweeper.SweepInput(input, defaultFeePref); err != nil {
   934  		t.Fatal(err)
   935  	}
   936  
   937  	ctx.tick()
   938  
   939  	ctx.receiveTx()
   940  
   941  	// Restart sweeper.
   942  	ctx.restartSweeper()
   943  
   944  	// Expect last tx to be republished.
   945  	ctx.receiveTx()
   946  
   947  	// Mine the sweep tx.
   948  	ctx.backend.mine()
   949  
   950  	// Simulate other subsystem (e.g. contract resolver) re-offering input 0.
   951  	spendChan, err := ctx.sweeper.SweepInput(input, defaultFeePref)
   952  	if err != nil {
   953  		t.Fatal(err)
   954  	}
   955  
   956  	// Here we expect again a successful sweep.
   957  	ctx.expectResult(spendChan, nil)
   958  
   959  	ctx.finish(1)
   960  }
   961  
   962  // TestRestartRepublish asserts that sweeper republishes the last published
   963  // tx on restart.
   964  func TestRestartRepublish(t *testing.T) {
   965  	ctx := createSweeperTestContext(t)
   966  
   967  	_, err := ctx.sweeper.SweepInput(spendableInputs[0], defaultFeePref)
   968  	if err != nil {
   969  		t.Fatal(err)
   970  	}
   971  
   972  	ctx.tick()
   973  
   974  	sweepTx := ctx.receiveTx()
   975  
   976  	// Restart sweeper again. No action is expected.
   977  	ctx.restartSweeper()
   978  
   979  	republishedTx := ctx.receiveTx()
   980  
   981  	if sweepTx.TxHash() != republishedTx.TxHash() {
   982  		t.Fatalf("last tx not republished")
   983  	}
   984  
   985  	// Mine the tx to conclude the test properly.
   986  	ctx.backend.mine()
   987  
   988  	ctx.finish(1)
   989  }
   990  
   991  // TestRetry tests the sweeper retry flow.
   992  func TestRetry(t *testing.T) {
   993  	ctx := createSweeperTestContext(t)
   994  
   995  	resultChan0, err := ctx.sweeper.SweepInput(
   996  		spendableInputs[0], defaultFeePref,
   997  	)
   998  	if err != nil {
   999  		t.Fatal(err)
  1000  	}
  1001  
  1002  	ctx.tick()
  1003  
  1004  	// We expect a sweep to be published.
  1005  	ctx.receiveTx()
  1006  
  1007  	// New block arrives. This should trigger a new sweep attempt timer
  1008  	// start.
  1009  	ctx.notifier.NotifyEpoch(1000)
  1010  
  1011  	// Offer a fresh input.
  1012  	resultChan1, err := ctx.sweeper.SweepInput(
  1013  		spendableInputs[1], defaultFeePref,
  1014  	)
  1015  	if err != nil {
  1016  		t.Fatal(err)
  1017  	}
  1018  
  1019  	ctx.tick()
  1020  
  1021  	// Two txes are expected to be published, because new and retry inputs
  1022  	// are separated.
  1023  	ctx.receiveTx()
  1024  	ctx.receiveTx()
  1025  
  1026  	ctx.backend.mine()
  1027  
  1028  	ctx.expectResult(resultChan0, nil)
  1029  	ctx.expectResult(resultChan1, nil)
  1030  
  1031  	ctx.finish(1)
  1032  }
  1033  
  1034  // TestGiveUp asserts that the sweeper gives up on an input if it can't be swept
  1035  // after a configured number of attempts.a
  1036  func TestGiveUp(t *testing.T) {
  1037  	ctx := createSweeperTestContext(t)
  1038  
  1039  	resultChan0, err := ctx.sweeper.SweepInput(
  1040  		spendableInputs[0], defaultFeePref,
  1041  	)
  1042  	if err != nil {
  1043  		t.Fatal(err)
  1044  	}
  1045  
  1046  	ctx.tick()
  1047  
  1048  	// We expect a sweep to be published at height 100 (mockChainIOHeight).
  1049  	ctx.receiveTx()
  1050  
  1051  	// Because of MaxSweepAttemps, two more sweeps will be attempted. We
  1052  	// configured exponential back-off without randomness for the test. The
  1053  	// second attempt, we expect to happen at 101. The third attempt at 103.
  1054  	// At that point, the input is expected to be failed.
  1055  
  1056  	// Second attempt
  1057  	ctx.notifier.NotifyEpoch(101)
  1058  	ctx.tick()
  1059  	ctx.receiveTx()
  1060  
  1061  	// Third attempt
  1062  	ctx.notifier.NotifyEpoch(103)
  1063  	ctx.tick()
  1064  	ctx.receiveTx()
  1065  
  1066  	ctx.expectResult(resultChan0, ErrTooManyAttempts)
  1067  
  1068  	ctx.backend.mine()
  1069  
  1070  	ctx.finish(1)
  1071  }
  1072  
  1073  // TestDifferentFeePreferences ensures that the sweeper can have different
  1074  // transactions for different fee preferences. These transactions should be
  1075  // broadcast from highest to lowest fee rate.
  1076  func TestDifferentFeePreferences(t *testing.T) {
  1077  	ctx := createSweeperTestContext(t)
  1078  
  1079  	// Throughout this test, we'll be attempting to sweep three inputs, two
  1080  	// with the higher fee preference, and the last with the lower. We do
  1081  	// this to ensure the sweeper can broadcast distinct transactions for
  1082  	// each sweep with a different fee preference.
  1083  	lowFeePref := FeePreference{ConfTarget: 12}
  1084  	lowFeeRate := chainfee.AtomPerKByte(10000)
  1085  	ctx.estimator.blocksToFee[lowFeePref.ConfTarget] = lowFeeRate
  1086  
  1087  	highFeePref := FeePreference{ConfTarget: 6}
  1088  	highFeeRate := chainfee.AtomPerKByte(20000)
  1089  	ctx.estimator.blocksToFee[highFeePref.ConfTarget] = highFeeRate
  1090  
  1091  	input1 := spendableInputs[0]
  1092  	resultChan1, err := ctx.sweeper.SweepInput(
  1093  		input1, Params{Fee: highFeePref},
  1094  	)
  1095  	if err != nil {
  1096  		t.Fatal(err)
  1097  	}
  1098  	input2 := spendableInputs[1]
  1099  	resultChan2, err := ctx.sweeper.SweepInput(
  1100  		input2, Params{Fee: highFeePref},
  1101  	)
  1102  	if err != nil {
  1103  		t.Fatal(err)
  1104  	}
  1105  	input3 := spendableInputs[2]
  1106  	resultChan3, err := ctx.sweeper.SweepInput(
  1107  		input3, Params{Fee: lowFeePref},
  1108  	)
  1109  	if err != nil {
  1110  		t.Fatal(err)
  1111  	}
  1112  
  1113  	// Start the sweeper's batch ticker, which should cause the sweep
  1114  	// transactions to be broadcast in order of high to low fee preference.
  1115  	ctx.tick()
  1116  
  1117  	// The first transaction broadcast should be the one spending the higher
  1118  	// fee rate inputs.
  1119  	sweepTx1 := ctx.receiveTx()
  1120  	assertTxFeeRate(t, &sweepTx1, highFeeRate, input1, input2)
  1121  
  1122  	// The second should be the one spending the lower fee rate inputs.
  1123  	sweepTx2 := ctx.receiveTx()
  1124  	assertTxFeeRate(t, &sweepTx2, lowFeeRate, input3)
  1125  
  1126  	// With the transactions broadcast, we'll mine a block to so that the
  1127  	// result is delivered to each respective client.
  1128  	ctx.backend.mine()
  1129  	resultChans := []chan Result{resultChan1, resultChan2, resultChan3}
  1130  	for _, resultChan := range resultChans {
  1131  		ctx.expectResult(resultChan, nil)
  1132  	}
  1133  
  1134  	ctx.finish(1)
  1135  }
  1136  
  1137  // TestPendingInputs ensures that the sweeper correctly determines the inputs
  1138  // pending to be swept.
  1139  func TestPendingInputs(t *testing.T) {
  1140  	ctx := createSweeperTestContext(t)
  1141  
  1142  	// Throughout this test, we'll be attempting to sweep three inputs, two
  1143  	// with the higher fee preference, and the last with the lower. We do
  1144  	// this to ensure the sweeper can return all pending inputs, even those
  1145  	// with different fee preferences.
  1146  	const (
  1147  		lowFeeRate  = 10000
  1148  		highFeeRate = 20000
  1149  	)
  1150  
  1151  	lowFeePref := FeePreference{
  1152  		ConfTarget: 12,
  1153  	}
  1154  	ctx.estimator.blocksToFee[lowFeePref.ConfTarget] = lowFeeRate
  1155  
  1156  	highFeePref := FeePreference{
  1157  		ConfTarget: 6,
  1158  	}
  1159  	ctx.estimator.blocksToFee[highFeePref.ConfTarget] = highFeeRate
  1160  
  1161  	input1 := spendableInputs[0]
  1162  	resultChan1, err := ctx.sweeper.SweepInput(
  1163  		input1, Params{Fee: highFeePref},
  1164  	)
  1165  	if err != nil {
  1166  		t.Fatal(err)
  1167  	}
  1168  	input2 := spendableInputs[1]
  1169  	_, err = ctx.sweeper.SweepInput(
  1170  		input2, Params{Fee: highFeePref},
  1171  	)
  1172  	if err != nil {
  1173  		t.Fatal(err)
  1174  	}
  1175  	input3 := spendableInputs[2]
  1176  	resultChan3, err := ctx.sweeper.SweepInput(
  1177  		input3, Params{Fee: lowFeePref},
  1178  	)
  1179  	if err != nil {
  1180  		t.Fatal(err)
  1181  	}
  1182  
  1183  	// We should expect to see all inputs pending.
  1184  	ctx.assertPendingInputs(input1, input2, input3)
  1185  
  1186  	// We should expect to see both sweep transactions broadcast. The higher
  1187  	// fee rate sweep should be broadcast first. We'll remove the lower fee
  1188  	// rate sweep to ensure we can detect pending inputs after a sweep.
  1189  	// Once the higher fee rate sweep confirms, we should no longer see
  1190  	// those inputs pending.
  1191  	ctx.tick()
  1192  	ctx.receiveTx()
  1193  	lowFeeRateTx := ctx.receiveTx()
  1194  	ctx.backend.deleteUnconfirmed(lowFeeRateTx.TxHash())
  1195  	ctx.backend.mine()
  1196  	ctx.expectResult(resultChan1, nil)
  1197  	ctx.assertPendingInputs(input3)
  1198  
  1199  	// We'll then trigger a new block to rebroadcast the lower fee rate
  1200  	// sweep. Once again we'll ensure those inputs are no longer pending
  1201  	// once the sweep transaction confirms.
  1202  	ctx.backend.notifier.NotifyEpoch(101)
  1203  	ctx.tick()
  1204  	ctx.receiveTx()
  1205  	ctx.backend.mine()
  1206  	ctx.expectResult(resultChan3, nil)
  1207  	ctx.assertPendingInputs()
  1208  
  1209  	ctx.finish(1)
  1210  }
  1211  
  1212  // TestBumpFeeRBF ensures that the UtxoSweeper can properly handle a fee bump
  1213  // request for an input it is currently attempting to sweep. When sweeping the
  1214  // input with the higher fee rate, a replacement transaction is created.
  1215  func TestBumpFeeRBF(t *testing.T) {
  1216  	ctx := createSweeperTestContext(t)
  1217  
  1218  	lowFeePref := FeePreference{ConfTarget: 144}
  1219  	lowFeeRate := chainfee.FeePerKBFloor
  1220  	ctx.estimator.blocksToFee[lowFeePref.ConfTarget] = lowFeeRate
  1221  
  1222  	// We'll first try to bump the fee of an output currently unknown to the
  1223  	// UtxoSweeper. Doing so should result in a lnwallet.ErrNotMine error.
  1224  	_, err := ctx.sweeper.UpdateParams(
  1225  		wire.OutPoint{}, ParamsUpdate{Fee: lowFeePref},
  1226  	)
  1227  	if err != lnwallet.ErrNotMine {
  1228  		t.Fatalf("expected error lnwallet.ErrNotMine, got \"%v\"", err)
  1229  	}
  1230  
  1231  	// We'll then attempt to sweep an input, which we'll use to bump its fee
  1232  	// later on.
  1233  	input := createTestInput(
  1234  		dcrutil.AtomsPerCoin, input.CommitmentTimeLock,
  1235  	)
  1236  	sweepResult, err := ctx.sweeper.SweepInput(
  1237  		&input, Params{Fee: lowFeePref},
  1238  	)
  1239  	if err != nil {
  1240  		t.Fatal(err)
  1241  	}
  1242  
  1243  	// Ensure that a transaction is broadcast with the lower fee preference.
  1244  	ctx.tick()
  1245  	lowFeeTx := ctx.receiveTx()
  1246  	assertTxFeeRate(t, &lowFeeTx, lowFeeRate, &input)
  1247  
  1248  	// We'll then attempt to bump its fee rate.
  1249  	highFeePref := FeePreference{ConfTarget: 6}
  1250  	highFeeRate := DefaultMaxFeeRate
  1251  	ctx.estimator.blocksToFee[highFeePref.ConfTarget] = highFeeRate
  1252  
  1253  	// We should expect to see an error if a fee preference isn't provided.
  1254  	_, err = ctx.sweeper.UpdateParams(*input.OutPoint(), ParamsUpdate{})
  1255  	if err != ErrNoFeePreference {
  1256  		t.Fatalf("expected ErrNoFeePreference, got %v", err)
  1257  	}
  1258  
  1259  	bumpResult, err := ctx.sweeper.UpdateParams(
  1260  		*input.OutPoint(), ParamsUpdate{Fee: highFeePref},
  1261  	)
  1262  	if err != nil {
  1263  		t.Fatalf("unable to bump input's fee: %v", err)
  1264  	}
  1265  
  1266  	// A higher fee rate transaction should be immediately broadcast.
  1267  	ctx.tick()
  1268  	highFeeTx := ctx.receiveTx()
  1269  	assertTxFeeRate(t, &highFeeTx, highFeeRate, &input)
  1270  
  1271  	// We'll finish our test by mining the sweep transaction.
  1272  	ctx.backend.mine()
  1273  	ctx.expectResult(sweepResult, nil)
  1274  	ctx.expectResult(bumpResult, nil)
  1275  
  1276  	ctx.finish(1)
  1277  }
  1278  
  1279  // TestExclusiveGroup tests the sweeper exclusive group functionality.
  1280  func TestExclusiveGroup(t *testing.T) {
  1281  	ctx := createSweeperTestContext(t)
  1282  
  1283  	// Sweep three inputs in the same exclusive group.
  1284  	var results []chan Result
  1285  	for i := 0; i < 3; i++ {
  1286  		exclusiveGroup := uint64(1)
  1287  		result, err := ctx.sweeper.SweepInput(
  1288  			spendableInputs[i], Params{
  1289  				Fee:            FeePreference{ConfTarget: 6},
  1290  				ExclusiveGroup: &exclusiveGroup,
  1291  			},
  1292  		)
  1293  		if err != nil {
  1294  			t.Fatal(err)
  1295  		}
  1296  		results = append(results, result)
  1297  	}
  1298  
  1299  	// We expect all inputs to be published in separate transactions, even
  1300  	// though they share the same fee preference.
  1301  	ctx.tick()
  1302  	for i := 0; i < 3; i++ {
  1303  		sweepTx := ctx.receiveTx()
  1304  		if len(sweepTx.TxOut) != 1 {
  1305  			t.Fatal("expected a single tx out in the sweep tx")
  1306  		}
  1307  
  1308  		// Remove all txes except for the one that sweeps the first
  1309  		// input. This simulates the sweeps being conflicting.
  1310  		if sweepTx.TxIn[0].PreviousOutPoint !=
  1311  			*spendableInputs[0].OutPoint() {
  1312  
  1313  			ctx.backend.deleteUnconfirmed(sweepTx.TxHash())
  1314  		}
  1315  	}
  1316  
  1317  	// Mine the first sweep tx.
  1318  	ctx.backend.mine()
  1319  
  1320  	// Expect the first input to be swept by the confirmed sweep tx.
  1321  	result0 := <-results[0]
  1322  	if result0.Err != nil {
  1323  		t.Fatal("expected first input to be swept")
  1324  	}
  1325  
  1326  	// Expect the other two inputs to return an error. They have no chance
  1327  	// of confirming.
  1328  	result1 := <-results[1]
  1329  	if result1.Err != ErrExclusiveGroupSpend {
  1330  		t.Fatal("expected second input to be canceled")
  1331  	}
  1332  
  1333  	result2 := <-results[2]
  1334  	if result2.Err != ErrExclusiveGroupSpend {
  1335  		t.Fatal("expected third input to be canceled")
  1336  	}
  1337  }
  1338  
  1339  // TestCpfp tests that the sweeper spends cpfp inputs at a fee rate that exceeds
  1340  // the parent tx fee rate.
  1341  func TestCpfp(t *testing.T) {
  1342  	ctx := createSweeperTestContext(t)
  1343  
  1344  	ctx.estimator.updateFees(10000, chainfee.FeePerKBFloor)
  1345  
  1346  	// Offer an input with an unconfirmed parent tx to the sweeper. The
  1347  	// parent tx pays 3000 sat/kw.
  1348  	hash := chainhash.Hash{1}
  1349  	input := input.MakeBaseInput(
  1350  		&wire.OutPoint{Hash: hash},
  1351  		input.CommitmentTimeLock,
  1352  		&input.SignDescriptor{
  1353  			Output: &wire.TxOut{
  1354  				Value: 25000,
  1355  			},
  1356  			KeyDesc: keychain.KeyDescriptor{
  1357  				PubKey: testPubKey,
  1358  			},
  1359  		},
  1360  		0,
  1361  		&input.TxInfo{
  1362  			Size: 300,
  1363  			Fee:  9000,
  1364  		},
  1365  	)
  1366  
  1367  	feePref := FeePreference{ConfTarget: 6}
  1368  	result, err := ctx.sweeper.SweepInput(
  1369  		&input, Params{Fee: feePref, Force: true},
  1370  	)
  1371  	require.NoError(t, err)
  1372  
  1373  	// Because we sweep at 1000 sat/kw, the parent cannot be paid for. We
  1374  	// expect the sweeper to remain idle.
  1375  	ctx.assertNoTick()
  1376  
  1377  	// Increase the fee estimate to above the parent tx fee rate.
  1378  	ctx.estimator.updateFees(50000, chainfee.FeePerKBFloor)
  1379  
  1380  	// Signal a new block. This is a trigger for the sweeper to refresh fee
  1381  	// estimates.
  1382  	ctx.notifier.NotifyEpoch(1000)
  1383  
  1384  	// Now we do expect a sweep transaction to be published with our input
  1385  	// and an attached wallet utxo.
  1386  	ctx.tick()
  1387  	tx := ctx.receiveTx()
  1388  	require.Len(t, tx.TxIn, 2)
  1389  	require.Len(t, tx.TxOut, 1)
  1390  
  1391  	// As inputs we have 1000000 atoms from the wallet and 25000 atoms from
  1392  	// the cpfp input. The sweep tx size is expected to be 432 bytes. There
  1393  	// is an additional 300 bytes from the parent to include in the package,
  1394  	// making a total of 732 bytes. At 50000 atoms/kB, the required fee for
  1395  	// the package is 36600 atoms. The parent already paid 9000 atoms, so
  1396  	// there is 27600 atoms remaining to be paid. The expected output value
  1397  	// is therefore 1000000 + 25000  - 27600 = 7400.
  1398  	require.Equal(t, int64(997400), tx.TxOut[0].Value)
  1399  
  1400  	// Mine the tx and assert that the result is passed back.
  1401  	ctx.backend.mine()
  1402  	ctx.expectResult(result, nil)
  1403  
  1404  	ctx.finish(1)
  1405  }
  1406  
  1407  var (
  1408  	testInputsA = pendingInputs{
  1409  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 0}: &pendingInput{},
  1410  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 1}: &pendingInput{},
  1411  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 2}: &pendingInput{},
  1412  	}
  1413  
  1414  	testInputsB = pendingInputs{
  1415  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 10}: &pendingInput{},
  1416  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 11}: &pendingInput{},
  1417  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 12}: &pendingInput{},
  1418  	}
  1419  
  1420  	testInputsC = pendingInputs{
  1421  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 0}:  &pendingInput{},
  1422  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 1}:  &pendingInput{},
  1423  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 2}:  &pendingInput{},
  1424  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 10}: &pendingInput{},
  1425  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 11}: &pendingInput{},
  1426  		wire.OutPoint{Hash: chainhash.Hash{}, Index: 12}: &pendingInput{},
  1427  	}
  1428  )
  1429  
  1430  // TestMergeClusters check that we properly can merge clusters together,
  1431  // according to their required locktime.
  1432  func TestMergeClusters(t *testing.T) {
  1433  	t.Parallel()
  1434  
  1435  	lockTime1 := uint32(100)
  1436  	lockTime2 := uint32(200)
  1437  
  1438  	testCases := []struct {
  1439  		name string
  1440  		a    inputCluster
  1441  		b    inputCluster
  1442  		res  []inputCluster
  1443  	}{
  1444  		{
  1445  			name: "max fee rate",
  1446  			a: inputCluster{
  1447  				sweepFeeRate: 5000,
  1448  				inputs:       testInputsA,
  1449  			},
  1450  			b: inputCluster{
  1451  				sweepFeeRate: 7000,
  1452  				inputs:       testInputsB,
  1453  			},
  1454  			res: []inputCluster{
  1455  				{
  1456  					sweepFeeRate: 7000,
  1457  					inputs:       testInputsC,
  1458  				},
  1459  			},
  1460  		},
  1461  		{
  1462  			name: "same locktime",
  1463  			a: inputCluster{
  1464  				lockTime:     &lockTime1,
  1465  				sweepFeeRate: 5000,
  1466  				inputs:       testInputsA,
  1467  			},
  1468  			b: inputCluster{
  1469  				lockTime:     &lockTime1,
  1470  				sweepFeeRate: 7000,
  1471  				inputs:       testInputsB,
  1472  			},
  1473  			res: []inputCluster{
  1474  				{
  1475  					lockTime:     &lockTime1,
  1476  					sweepFeeRate: 7000,
  1477  					inputs:       testInputsC,
  1478  				},
  1479  			},
  1480  		},
  1481  		{
  1482  			name: "diff locktime",
  1483  			a: inputCluster{
  1484  				lockTime:     &lockTime1,
  1485  				sweepFeeRate: 5000,
  1486  				inputs:       testInputsA,
  1487  			},
  1488  			b: inputCluster{
  1489  				lockTime:     &lockTime2,
  1490  				sweepFeeRate: 7000,
  1491  				inputs:       testInputsB,
  1492  			},
  1493  			res: []inputCluster{
  1494  				{
  1495  					lockTime:     &lockTime1,
  1496  					sweepFeeRate: 5000,
  1497  					inputs:       testInputsA,
  1498  				},
  1499  				{
  1500  					lockTime:     &lockTime2,
  1501  					sweepFeeRate: 7000,
  1502  					inputs:       testInputsB,
  1503  				},
  1504  			},
  1505  		},
  1506  	}
  1507  
  1508  	for _, test := range testCases {
  1509  		merged := mergeClusters(test.a, test.b)
  1510  		if !reflect.DeepEqual(merged, test.res) {
  1511  			t.Fatalf("[%s] unexpected result: %v",
  1512  				test.name, spew.Sdump(merged))
  1513  		}
  1514  	}
  1515  }
  1516  
  1517  // TestZipClusters tests that we can merge lists of inputs clusters correctly.
  1518  func TestZipClusters(t *testing.T) {
  1519  	t.Parallel()
  1520  
  1521  	createCluster := func(inp pendingInputs, f chainfee.AtomPerKByte) inputCluster {
  1522  		return inputCluster{
  1523  			sweepFeeRate: f,
  1524  			inputs:       inp,
  1525  		}
  1526  	}
  1527  
  1528  	testCases := []struct {
  1529  		name string
  1530  		as   []inputCluster
  1531  		bs   []inputCluster
  1532  		res  []inputCluster
  1533  	}{
  1534  		{
  1535  			name: "merge A into B",
  1536  			as: []inputCluster{
  1537  				createCluster(testInputsA, 5000),
  1538  			},
  1539  			bs: []inputCluster{
  1540  				createCluster(testInputsB, 7000),
  1541  			},
  1542  			res: []inputCluster{
  1543  				createCluster(testInputsC, 7000),
  1544  			},
  1545  		},
  1546  		{
  1547  			name: "A can't merge with B",
  1548  			as: []inputCluster{
  1549  				createCluster(testInputsA, 7000),
  1550  			},
  1551  			bs: []inputCluster{
  1552  				createCluster(testInputsB, 5000),
  1553  			},
  1554  			res: []inputCluster{
  1555  				createCluster(testInputsA, 7000),
  1556  				createCluster(testInputsB, 5000),
  1557  			},
  1558  		},
  1559  		{
  1560  			name: "empty bs",
  1561  			as: []inputCluster{
  1562  				createCluster(testInputsA, 7000),
  1563  			},
  1564  			bs: []inputCluster{},
  1565  			res: []inputCluster{
  1566  				createCluster(testInputsA, 7000),
  1567  			},
  1568  		},
  1569  		{
  1570  			name: "empty as",
  1571  			as:   []inputCluster{},
  1572  			bs: []inputCluster{
  1573  				createCluster(testInputsB, 5000),
  1574  			},
  1575  			res: []inputCluster{
  1576  				createCluster(testInputsB, 5000),
  1577  			},
  1578  		},
  1579  
  1580  		{
  1581  			name: "zip 3xA into 3xB",
  1582  			as: []inputCluster{
  1583  				createCluster(testInputsA, 5000),
  1584  				createCluster(testInputsA, 5000),
  1585  				createCluster(testInputsA, 5000),
  1586  			},
  1587  			bs: []inputCluster{
  1588  				createCluster(testInputsB, 7000),
  1589  				createCluster(testInputsB, 7000),
  1590  				createCluster(testInputsB, 7000),
  1591  			},
  1592  			res: []inputCluster{
  1593  				createCluster(testInputsC, 7000),
  1594  				createCluster(testInputsC, 7000),
  1595  				createCluster(testInputsC, 7000),
  1596  			},
  1597  		},
  1598  		{
  1599  			name: "zip A into 3xB",
  1600  			as: []inputCluster{
  1601  				createCluster(testInputsA, 2500),
  1602  			},
  1603  			bs: []inputCluster{
  1604  				createCluster(testInputsB, 3000),
  1605  				createCluster(testInputsB, 2000),
  1606  				createCluster(testInputsB, 1000),
  1607  			},
  1608  			res: []inputCluster{
  1609  				createCluster(testInputsC, 3000),
  1610  				createCluster(testInputsB, 2000),
  1611  				createCluster(testInputsB, 1000),
  1612  			},
  1613  		},
  1614  	}
  1615  
  1616  	for _, test := range testCases {
  1617  		zipped := zipClusters(test.as, test.bs)
  1618  		if !reflect.DeepEqual(zipped, test.res) {
  1619  			t.Fatalf("[%s] unexpected result: %v",
  1620  				test.name, spew.Sdump(zipped))
  1621  		}
  1622  	}
  1623  }
  1624  
  1625  type testInput struct {
  1626  	*input.BaseInput
  1627  
  1628  	locktime *uint32
  1629  	reqTxOut *wire.TxOut
  1630  }
  1631  
  1632  func (i *testInput) RequiredLockTime() (uint32, bool) {
  1633  	if i.locktime != nil {
  1634  		return *i.locktime, true
  1635  	}
  1636  
  1637  	return 0, false
  1638  }
  1639  
  1640  func (i *testInput) RequiredTxOut() *wire.TxOut {
  1641  	return i.reqTxOut
  1642  }
  1643  
  1644  // CraftInputScript is a custom sign method for the testInput type that will
  1645  // encode the spending outpoint and the tx input index as part of the returned
  1646  // witness.
  1647  func (i *testInput) CraftInputScript(_ input.Signer, txn *wire.MsgTx,
  1648  	txinIdx int) (*input.Script, error) {
  1649  
  1650  	// We'll encode the outpoint in the witness, so we can assert that the
  1651  	// expected input was signed at the correct index.
  1652  	//
  1653  	// Note(decred) OP_1 + <int> is used instead of int directly because
  1654  	// SigScriptToWitnessStack converts OP_0 to a nil byte slice, making it
  1655  	// harder to verify. Thus we add OP_1 to ensure a data push actually
  1656  	// happens.
  1657  	op := i.OutPoint()
  1658  	return &input.Script{
  1659  		Witness: [][]byte{
  1660  			// We encode the hash of the outpoint...
  1661  			op.Hash[:],
  1662  			// ..the outpoint index...
  1663  			//{byte(op.Index)},
  1664  			{txscript.OP_1 + byte(op.Index)},
  1665  			// ..and finally the tx input index.
  1666  			{txscript.OP_1 + byte(txinIdx)},
  1667  		},
  1668  	}, nil
  1669  }
  1670  
  1671  // assertSignedIndex goes through all inputs to the tx and checks that all
  1672  // testInputs have witnesses corresponding to the outpoints they are spending,
  1673  // and are signed at the correct tx input index. All found testInputs are
  1674  // returned such that we can sum up and sanity check that all testInputs were
  1675  // part of the sweep.
  1676  func assertSignedIndex(t *testing.T, tx *wire.MsgTx,
  1677  	testInputs map[wire.OutPoint]*testInput) map[wire.OutPoint]struct{} {
  1678  
  1679  	found := make(map[wire.OutPoint]struct{})
  1680  	for idx, txIn := range tx.TxIn {
  1681  		op := txIn.PreviousOutPoint
  1682  
  1683  		// Not a testInput, it won't have the test encoding we require
  1684  		// to check outpoint and index.
  1685  		if _, ok := testInputs[op]; !ok {
  1686  			continue
  1687  		}
  1688  
  1689  		if _, ok := found[op]; ok {
  1690  			t.Fatalf("input already used")
  1691  		}
  1692  
  1693  		// Check it was signes spending the correct outpoint, and at
  1694  		// the expected tx input index.
  1695  		witness, err := input.SigScriptToWitnessStack(txIn.SignatureScript)
  1696  		require.NoError(t, err)
  1697  		require.Equal(t, witness[0], op.Hash[:])
  1698  		require.Equal(t, witness[1], []byte{txscript.OP_1 + byte(op.Index)})
  1699  		require.Equal(t, witness[2], []byte{txscript.OP_1 + byte(idx)})
  1700  		found[op] = struct{}{}
  1701  	}
  1702  
  1703  	return found
  1704  }
  1705  
  1706  // TestLockTimes checks that the sweeper properly groups inputs requiring the
  1707  // same locktime together into sweep transactions.
  1708  func TestLockTimes(t *testing.T) {
  1709  	ctx := createSweeperTestContext(t)
  1710  
  1711  	// We increase the number of max inputs to a tx so that won't
  1712  	// impact our test.
  1713  	ctx.sweeper.cfg.MaxInputsPerTx = 100
  1714  
  1715  	// We will set up the lock times in such a way that we expect the
  1716  	// sweeper to divide the inputs into 4 diffeerent transactions.
  1717  	const numSweeps = 4
  1718  
  1719  	// Sweep 8 inputs, using 4 different lock times.
  1720  	var (
  1721  		results []chan Result
  1722  		inputs  = make(map[wire.OutPoint]input.Input)
  1723  	)
  1724  	for i := 0; i < numSweeps*2; i++ {
  1725  		lt := uint32(10 + (i % numSweeps))
  1726  		inp := &testInput{
  1727  			BaseInput: spendableInputs[i],
  1728  			locktime:  &lt,
  1729  		}
  1730  
  1731  		result, err := ctx.sweeper.SweepInput(
  1732  			inp, Params{
  1733  				Fee: FeePreference{ConfTarget: 6},
  1734  			},
  1735  		)
  1736  		if err != nil {
  1737  			t.Fatal(err)
  1738  		}
  1739  		results = append(results, result)
  1740  
  1741  		op := inp.OutPoint()
  1742  		inputs[*op] = inp
  1743  	}
  1744  
  1745  	// We also add 3 regular inputs that don't require any specific lock
  1746  	// time.
  1747  	for i := 0; i < 3; i++ {
  1748  		inp := spendableInputs[i+numSweeps*2]
  1749  		result, err := ctx.sweeper.SweepInput(
  1750  			inp, Params{
  1751  				Fee: FeePreference{ConfTarget: 6},
  1752  			},
  1753  		)
  1754  		if err != nil {
  1755  			t.Fatal(err)
  1756  		}
  1757  
  1758  		results = append(results, result)
  1759  
  1760  		op := inp.OutPoint()
  1761  		inputs[*op] = inp
  1762  	}
  1763  
  1764  	// We expect all inputs to be published in separate transactions, even
  1765  	// though they share the same fee preference.
  1766  	ctx.tick()
  1767  
  1768  	// Check the sweeps transactions, ensuring all inputs are there, and
  1769  	// all the locktimes are satisfied.
  1770  	for i := 0; i < numSweeps; i++ {
  1771  		sweepTx := ctx.receiveTx()
  1772  		if len(sweepTx.TxOut) != 1 {
  1773  			t.Fatal("expected a single tx out in the sweep tx")
  1774  		}
  1775  
  1776  		for _, txIn := range sweepTx.TxIn {
  1777  			op := txIn.PreviousOutPoint
  1778  			inp, ok := inputs[op]
  1779  			if !ok {
  1780  				t.Fatalf("Unexpected outpoint: %v", op)
  1781  			}
  1782  
  1783  			delete(inputs, op)
  1784  
  1785  			// If this input had a required locktime, ensure the tx
  1786  			// has that set correctly.
  1787  			lt, ok := inp.RequiredLockTime()
  1788  			if !ok {
  1789  				continue
  1790  			}
  1791  
  1792  			if lt != sweepTx.LockTime {
  1793  				t.Fatalf("Input required locktime %v, sweep "+
  1794  					"tx had locktime %v", lt, sweepTx.LockTime)
  1795  			}
  1796  
  1797  		}
  1798  	}
  1799  
  1800  	// The should be no inputs not foud in any of the sweeps.
  1801  	if len(inputs) != 0 {
  1802  		t.Fatalf("had unsweeped inputs")
  1803  	}
  1804  
  1805  	// Mine the first sweeps
  1806  	ctx.backend.mine()
  1807  
  1808  	// Results should all come back.
  1809  	for i := range results {
  1810  		result := <-results[i]
  1811  		if result.Err != nil {
  1812  			t.Fatal("expected input to be swept")
  1813  		}
  1814  	}
  1815  }
  1816  
  1817  // TestRequiredTxOuts checks that inputs having a required TxOut gets swept with
  1818  // sweep transactions paying into these outputs.
  1819  func TestRequiredTxOuts(t *testing.T) {
  1820  	// Create some test inputs and locktime vars.
  1821  	var inputs []*input.BaseInput
  1822  	for i := 0; i < 20; i++ {
  1823  		input := createTestInput(
  1824  			int64(dcrutil.AtomsPerCoin+i*500),
  1825  			input.CommitmentTimeLock,
  1826  		)
  1827  
  1828  		inputs = append(inputs, &input)
  1829  	}
  1830  
  1831  	locktime1 := uint32(51)
  1832  	locktime2 := uint32(52)
  1833  	locktime3 := uint32(53)
  1834  
  1835  	aPkScript := make([]byte, input.P2PKHPkScriptSize)
  1836  	aPkScript[0] = 'a'
  1837  
  1838  	bPkScript := make([]byte, input.P2SHPkScriptSize)
  1839  	bPkScript[0] = 'b'
  1840  
  1841  	ePkScript := make([]byte, 25)
  1842  	ePkScript[0] = 'e'
  1843  
  1844  	testCases := []struct {
  1845  		name         string
  1846  		inputs       []*testInput
  1847  		assertSweeps func(*testing.T, map[wire.OutPoint]*testInput,
  1848  			[]*wire.MsgTx)
  1849  	}{
  1850  		{
  1851  			// Single input with a required TX out that is smaller.
  1852  			// We expect a change output to be added.
  1853  			name: "single input, leftover change",
  1854  			inputs: []*testInput{
  1855  				{
  1856  					BaseInput: inputs[0],
  1857  					reqTxOut: &wire.TxOut{
  1858  						PkScript: aPkScript,
  1859  						Value:    100000,
  1860  					},
  1861  				},
  1862  			},
  1863  
  1864  			// Since the required output value is small, we expect
  1865  			// the rest after fees to go into a change output.
  1866  			assertSweeps: func(t *testing.T,
  1867  				_ map[wire.OutPoint]*testInput,
  1868  				txs []*wire.MsgTx) {
  1869  
  1870  				require.Equal(t, 1, len(txs))
  1871  
  1872  				tx := txs[0]
  1873  				require.Equal(t, 1, len(tx.TxIn))
  1874  
  1875  				// We should have two outputs, the required
  1876  				// output must be the first one.
  1877  				require.Equal(t, 2, len(tx.TxOut))
  1878  				out := tx.TxOut[0]
  1879  				require.Equal(t, aPkScript, out.PkScript)
  1880  				require.Equal(t, int64(100000), out.Value)
  1881  			},
  1882  		},
  1883  		{
  1884  			// An input committing to a slightly smaller output, so
  1885  			// it will pay its own fees.
  1886  			name: "single input, no change",
  1887  			inputs: []*testInput{
  1888  				{
  1889  					BaseInput: inputs[0],
  1890  					reqTxOut: &wire.TxOut{
  1891  						PkScript: aPkScript,
  1892  
  1893  						// Fee will be about 5340 sats.
  1894  						// Subtract a bit more to
  1895  						// ensure no dust change output
  1896  						// is manifested.
  1897  						Value: inputs[0].SignDesc().Output.Value - 6300,
  1898  					},
  1899  				},
  1900  			},
  1901  
  1902  			// We expect this single input/output pair.
  1903  			assertSweeps: func(t *testing.T,
  1904  				_ map[wire.OutPoint]*testInput,
  1905  				txs []*wire.MsgTx) {
  1906  
  1907  				require.Equal(t, 1, len(txs))
  1908  
  1909  				tx := txs[0]
  1910  				require.Equal(t, 1, len(tx.TxIn))
  1911  
  1912  				require.Equal(t, 1, len(tx.TxOut))
  1913  				out := tx.TxOut[0]
  1914  				require.Equal(t, aPkScript, out.PkScript)
  1915  				require.Equal(
  1916  					t,
  1917  					inputs[0].SignDesc().Output.Value-6300,
  1918  					out.Value,
  1919  				)
  1920  			},
  1921  		},
  1922  		{
  1923  			// Two inputs, where the first one required no tx out.
  1924  			name: "two inputs, one with required tx out",
  1925  			inputs: []*testInput{
  1926  				{
  1927  
  1928  					// We add a normal, non-requiredTxOut
  1929  					// input. We use test input 10, to make
  1930  					// sure this has a higher yield than
  1931  					// the other input, and will be
  1932  					// attempted added first to the sweep
  1933  					// tx.
  1934  					BaseInput: inputs[10],
  1935  				},
  1936  				{
  1937  					// The second input requires a TxOut.
  1938  					BaseInput: inputs[0],
  1939  					reqTxOut: &wire.TxOut{
  1940  						PkScript: aPkScript,
  1941  						Value:    inputs[0].SignDesc().Output.Value,
  1942  					},
  1943  				},
  1944  			},
  1945  
  1946  			// We expect the inputs to have been reordered.
  1947  			assertSweeps: func(t *testing.T,
  1948  				_ map[wire.OutPoint]*testInput,
  1949  				txs []*wire.MsgTx) {
  1950  
  1951  				require.Equal(t, 1, len(txs))
  1952  
  1953  				tx := txs[0]
  1954  				require.Equal(t, 2, len(tx.TxIn))
  1955  				require.Equal(t, 2, len(tx.TxOut))
  1956  
  1957  				// The required TxOut should be the first one.
  1958  				out := tx.TxOut[0]
  1959  				require.Equal(t, aPkScript, out.PkScript)
  1960  				require.Equal(
  1961  					t, inputs[0].SignDesc().Output.Value,
  1962  					out.Value,
  1963  				)
  1964  
  1965  				// The first input should be the one having the
  1966  				// required TxOut.
  1967  				require.Len(t, tx.TxIn, 2)
  1968  				require.Equal(
  1969  					t, inputs[0].OutPoint(),
  1970  					&tx.TxIn[0].PreviousOutPoint,
  1971  				)
  1972  
  1973  				// Second one is the one without a required tx
  1974  				// out.
  1975  				require.Equal(
  1976  					t, inputs[10].OutPoint(),
  1977  					&tx.TxIn[1].PreviousOutPoint,
  1978  				)
  1979  			},
  1980  		},
  1981  
  1982  		{
  1983  			// An input committing to an output of equal value, just
  1984  			// add input to pay fees.
  1985  			name: "single input, extra fee input",
  1986  			inputs: []*testInput{
  1987  				{
  1988  					BaseInput: inputs[0],
  1989  					reqTxOut: &wire.TxOut{
  1990  						PkScript: aPkScript,
  1991  						Value:    inputs[0].SignDesc().Output.Value,
  1992  					},
  1993  				},
  1994  			},
  1995  
  1996  			// We expect an extra input and output.
  1997  			assertSweeps: func(t *testing.T,
  1998  				_ map[wire.OutPoint]*testInput,
  1999  				txs []*wire.MsgTx) {
  2000  
  2001  				require.Equal(t, 1, len(txs))
  2002  
  2003  				tx := txs[0]
  2004  				require.Equal(t, 2, len(tx.TxIn))
  2005  
  2006  				require.Equal(t, 2, len(tx.TxOut))
  2007  				out := tx.TxOut[0]
  2008  				require.Equal(t, aPkScript, out.PkScript)
  2009  				require.Equal(
  2010  					t, inputs[0].SignDesc().Output.Value,
  2011  					out.Value,
  2012  				)
  2013  			},
  2014  		},
  2015  		{
  2016  			// Three inputs added, should be combined into a single
  2017  			// sweep.
  2018  			name: "three inputs",
  2019  			inputs: []*testInput{
  2020  				{
  2021  					BaseInput: inputs[0],
  2022  					reqTxOut: &wire.TxOut{
  2023  						PkScript: aPkScript,
  2024  						Value:    inputs[0].SignDesc().Output.Value,
  2025  					},
  2026  				},
  2027  				{
  2028  					BaseInput: inputs[1],
  2029  					reqTxOut: &wire.TxOut{
  2030  						PkScript: bPkScript,
  2031  						Value:    inputs[1].SignDesc().Output.Value,
  2032  					},
  2033  				},
  2034  				{
  2035  					BaseInput: inputs[2],
  2036  					reqTxOut: &wire.TxOut{
  2037  						PkScript: ePkScript,
  2038  						Value:    inputs[2].SignDesc().Output.Value,
  2039  					},
  2040  				},
  2041  			},
  2042  
  2043  			// We expect an extra input and output to pay fees.
  2044  			assertSweeps: func(t *testing.T,
  2045  				testInputs map[wire.OutPoint]*testInput,
  2046  				txs []*wire.MsgTx) {
  2047  
  2048  				require.Equal(t, 1, len(txs))
  2049  
  2050  				tx := txs[0]
  2051  				require.Equal(t, 4, len(tx.TxIn))
  2052  				require.Equal(t, 4, len(tx.TxOut))
  2053  
  2054  				// The inputs and outputs must be in the same
  2055  				// order.
  2056  				for i, in := range tx.TxIn {
  2057  					// Last one is the change input/output
  2058  					// pair, so we'll skip it.
  2059  					if i == 3 {
  2060  						continue
  2061  					}
  2062  
  2063  					// Get this input to ensure the output
  2064  					// on index i coresponsd to this one.
  2065  					inp := testInputs[in.PreviousOutPoint]
  2066  					require.NotNil(t, inp)
  2067  
  2068  					require.Equal(
  2069  						t, tx.TxOut[i].Value,
  2070  						inp.SignDesc().Output.Value,
  2071  					)
  2072  				}
  2073  			},
  2074  		},
  2075  		{
  2076  			// Six inputs added, which 3 different locktimes.
  2077  			// Should result in 3 sweeps.
  2078  			name: "six inputs",
  2079  			inputs: []*testInput{
  2080  				{
  2081  					BaseInput: inputs[0],
  2082  					locktime:  &locktime1,
  2083  					reqTxOut: &wire.TxOut{
  2084  						PkScript: aPkScript,
  2085  						Value:    inputs[0].SignDesc().Output.Value,
  2086  					},
  2087  				},
  2088  				{
  2089  					BaseInput: inputs[1],
  2090  					locktime:  &locktime1,
  2091  					reqTxOut: &wire.TxOut{
  2092  						PkScript: bPkScript,
  2093  						Value:    inputs[1].SignDesc().Output.Value,
  2094  					},
  2095  				},
  2096  				{
  2097  					BaseInput: inputs[2],
  2098  					locktime:  &locktime2,
  2099  					reqTxOut: &wire.TxOut{
  2100  						PkScript: ePkScript,
  2101  						Value:    inputs[2].SignDesc().Output.Value,
  2102  					},
  2103  				},
  2104  				{
  2105  					BaseInput: inputs[3],
  2106  					locktime:  &locktime2,
  2107  					reqTxOut: &wire.TxOut{
  2108  						PkScript: aPkScript,
  2109  						Value:    inputs[3].SignDesc().Output.Value,
  2110  					},
  2111  				},
  2112  				{
  2113  					BaseInput: inputs[4],
  2114  					locktime:  &locktime3,
  2115  					reqTxOut: &wire.TxOut{
  2116  						PkScript: bPkScript,
  2117  						Value:    inputs[4].SignDesc().Output.Value,
  2118  					},
  2119  				},
  2120  				{
  2121  					BaseInput: inputs[5],
  2122  					locktime:  &locktime3,
  2123  					reqTxOut: &wire.TxOut{
  2124  						PkScript: ePkScript,
  2125  						Value:    inputs[5].SignDesc().Output.Value,
  2126  					},
  2127  				},
  2128  			},
  2129  
  2130  			// We expect three sweeps, each having two of our
  2131  			// inputs, one extra input and output to pay fees.
  2132  			assertSweeps: func(t *testing.T,
  2133  				testInputs map[wire.OutPoint]*testInput,
  2134  				txs []*wire.MsgTx) {
  2135  
  2136  				require.Equal(t, 3, len(txs))
  2137  
  2138  				for _, tx := range txs {
  2139  					require.Equal(t, 3, len(tx.TxIn))
  2140  					require.Equal(t, 3, len(tx.TxOut))
  2141  
  2142  					// The inputs and outputs must be in
  2143  					// the same order.
  2144  					for i, in := range tx.TxIn {
  2145  						// Last one is the change
  2146  						// output, so we'll skip it.
  2147  						if i == 2 {
  2148  							continue
  2149  						}
  2150  
  2151  						// Get this input to ensure the
  2152  						// output on index i coresponsd
  2153  						// to this one.
  2154  						inp := testInputs[in.PreviousOutPoint]
  2155  						require.NotNil(t, inp)
  2156  
  2157  						require.Equal(
  2158  							t, tx.TxOut[i].Value,
  2159  							inp.SignDesc().Output.Value,
  2160  						)
  2161  
  2162  						// Check that the locktimes are
  2163  						// kept intact.
  2164  						require.Equal(
  2165  							t, tx.LockTime,
  2166  							*inp.locktime,
  2167  						)
  2168  					}
  2169  				}
  2170  			},
  2171  		},
  2172  	}
  2173  
  2174  	for _, testCase := range testCases {
  2175  		testCase := testCase
  2176  
  2177  		t.Run(testCase.name, func(t *testing.T) {
  2178  			ctx := createSweeperTestContext(t)
  2179  
  2180  			// We increase the number of max inputs to a tx so that
  2181  			// won't impact our test.
  2182  			ctx.sweeper.cfg.MaxInputsPerTx = 100
  2183  
  2184  			// Sweep all test inputs.
  2185  			var (
  2186  				inputs  = make(map[wire.OutPoint]*testInput)
  2187  				results = make(map[wire.OutPoint]chan Result)
  2188  			)
  2189  			for _, inp := range testCase.inputs {
  2190  				result, err := ctx.sweeper.SweepInput(
  2191  					inp, Params{
  2192  						Fee: FeePreference{ConfTarget: 6},
  2193  					},
  2194  				)
  2195  				if err != nil {
  2196  					t.Fatal(err)
  2197  				}
  2198  
  2199  				op := inp.OutPoint()
  2200  				results[*op] = result
  2201  				inputs[*op] = inp
  2202  			}
  2203  
  2204  			// Tick, which should trigger a sweep of all inputs.
  2205  			ctx.tick()
  2206  
  2207  			// Check the sweeps transactions, ensuring all inputs
  2208  			// are there, and all the locktimes are satisfied.
  2209  			var sweeps []*wire.MsgTx
  2210  		Loop:
  2211  			for {
  2212  				select {
  2213  				case tx := <-ctx.publishChan:
  2214  					sweeps = append(sweeps, &tx)
  2215  				case <-time.After(200 * time.Millisecond):
  2216  					break Loop
  2217  				}
  2218  			}
  2219  
  2220  			// Mine the sweeps.
  2221  			ctx.backend.mine()
  2222  
  2223  			// Results should all come back.
  2224  			for _, resultChan := range results {
  2225  				result := <-resultChan
  2226  				if result.Err != nil {
  2227  					t.Fatalf("expected input to be "+
  2228  						"swept: %v", result.Err)
  2229  				}
  2230  			}
  2231  
  2232  			// Assert the transactions are what we expect.
  2233  			testCase.assertSweeps(t, inputs, sweeps)
  2234  
  2235  			// Finally we assert that all our test inputs were part
  2236  			// of the sweeps, and that they were signed correctly.
  2237  			sweptInputs := make(map[wire.OutPoint]struct{})
  2238  			for _, sweep := range sweeps {
  2239  				swept := assertSignedIndex(t, sweep, inputs)
  2240  				for op := range swept {
  2241  					if _, ok := sweptInputs[op]; ok {
  2242  						t.Fatalf("outpoint %v part of "+
  2243  							"previous sweep", op)
  2244  					}
  2245  
  2246  					sweptInputs[op] = struct{}{}
  2247  				}
  2248  			}
  2249  
  2250  			require.Equal(t, len(inputs), len(sweptInputs))
  2251  			for op := range sweptInputs {
  2252  				_, ok := inputs[op]
  2253  				if !ok {
  2254  					t.Fatalf("swept input %v not part of "+
  2255  						"test inputs", op)
  2256  				}
  2257  			}
  2258  		})
  2259  	}
  2260  }
  2261  
  2262  // TestSweeperShutdownHandling tests that we notify callers when the sweeper
  2263  // cannot handle requests since it's in the process of shutting down.
  2264  func TestSweeperShutdownHandling(t *testing.T) {
  2265  	ctx := createSweeperTestContext(t)
  2266  
  2267  	// Make the backing notifier break down. This is what happens during
  2268  	// lnd shut down, since the notifier is stopped before the sweeper.
  2269  	require.Len(t, ctx.notifier.epochChan, 1)
  2270  	for epochChan := range ctx.notifier.epochChan {
  2271  		close(epochChan)
  2272  	}
  2273  
  2274  	// Give the collector some time to exit.
  2275  	time.Sleep(50 * time.Millisecond)
  2276  
  2277  	// Now trying to sweep inputs should return an error on the error
  2278  	// channel.
  2279  	resultChan, err := ctx.sweeper.SweepInput(
  2280  		spendableInputs[0], defaultFeePref,
  2281  	)
  2282  	require.NoError(t, err)
  2283  
  2284  	select {
  2285  	case res := <-resultChan:
  2286  		require.Equal(t, ErrSweeperShuttingDown, res.Err)
  2287  
  2288  	case <-time.After(defaultTestTimeout):
  2289  		t.Fatalf("no result arrived")
  2290  	}
  2291  
  2292  	// Stop the sweeper properly.
  2293  	err = ctx.sweeper.Stop()
  2294  	require.NoError(t, err)
  2295  
  2296  	// Now attempting to sweep an input should error out immediately.
  2297  	_, err = ctx.sweeper.SweepInput(
  2298  		spendableInputs[0], defaultFeePref,
  2299  	)
  2300  	require.Error(t, err)
  2301  }