From aa8fa9d0cf9f45038248b80dad7bf0cfdfdaaeac Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 6 Nov 2020 19:44:12 +0100 Subject: [PATCH] sweep: pass dustLimit to CreateSweepTx --- rpcserver.go | 3 ++- sweep/sweeper.go | 5 +++-- sweep/tx_input_set.go | 12 ++++++++---- sweep/txgenerator.go | 14 ++++++++------ sweep/walletsweep.go | 11 ++++++----- sweep/walletsweep_test.go | 6 +++--- 6 files changed, 30 insertions(+), 21 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 580c1500..dc9188f3 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1254,7 +1254,8 @@ func (r *rpcServer) SendCoins(ctx context.Context, // single transaction. This will be generated in a concurrent // safe manner, so no need to worry about locking. sweepTxPkg, err := sweep.CraftSweepAllTx( - feePerKw, uint32(bestHeight), targetAddr, wallet, + feePerKw, lnwallet.DefaultDustLimit(), + uint32(bestHeight), targetAddr, wallet, wallet.WalletController, wallet.WalletController, r.server.cc.FeeEstimator, r.server.cc.Signer, ) diff --git a/sweep/sweeper.go b/sweep/sweeper.go index 09eb5a02..a1b3cf16 100644 --- a/sweep/sweeper.go +++ b/sweep/sweeper.go @@ -1165,7 +1165,7 @@ func (s *UtxoSweeper) sweep(inputs inputSet, feeRate chainfee.SatPerKWeight, // Create sweep tx. tx, err := createSweepTx( inputs, s.currentOutputScript, uint32(currentHeight), feeRate, - s.cfg.Signer, + dustLimit(s.relayFeeRate), s.cfg.Signer, ) if err != nil { return fmt.Errorf("create sweep tx: %v", err) @@ -1455,7 +1455,8 @@ func (s *UtxoSweeper) CreateSweepTx(inputs []input.Input, feePref FeePreference, } return createSweepTx( - inputs, pkScript, currentBlockHeight, feePerKw, s.cfg.Signer, + inputs, pkScript, currentBlockHeight, feePerKw, + dustLimit(s.relayFeeRate), s.cfg.Signer, ) } diff --git a/sweep/tx_input_set.go b/sweep/tx_input_set.go index 70836900..59a587fc 100644 --- a/sweep/tx_input_set.go +++ b/sweep/tx_input_set.go @@ -83,14 +83,18 @@ type txInputSet struct { wallet Wallet } +func dustLimit(relayFee chainfee.SatPerKWeight) btcutil.Amount { + return txrules.GetDustThreshold( + input.P2WPKHSize, + btcutil.Amount(relayFee.FeePerKVByte()), + ) +} + // newTxInputSet constructs a new, empty input set. func newTxInputSet(wallet Wallet, feePerKW, relayFee chainfee.SatPerKWeight, maxInputs int) *txInputSet { - dustLimit := txrules.GetDustThreshold( - input.P2WPKHSize, - btcutil.Amount(relayFee.FeePerKVByte()), - ) + dustLimit := dustLimit(relayFee) state := txInputSetState{ weightEstimate: newWeightEstimator(feePerKW), diff --git a/sweep/txgenerator.go b/sweep/txgenerator.go index d0c71c49..3f456b29 100644 --- a/sweep/txgenerator.go +++ b/sweep/txgenerator.go @@ -132,7 +132,7 @@ func generateInputPartitionings(sweepableInputs []txInput, // createSweepTx builds a signed tx spending the inputs to a the output script. func createSweepTx(inputs []input.Input, outputPkScript []byte, currentBlockHeight uint32, feePerKw chainfee.SatPerKWeight, - signer input.Signer) (*wire.MsgTx, error) { + dustLimit btcutil.Amount, signer input.Signer) (*wire.MsgTx, error) { inputs, estimator := getWeightEstimate(inputs, feePerKw) @@ -169,14 +169,16 @@ func createSweepTx(inputs []input.Input, outputPkScript []byte, } // Sweep as much possible, after subtracting txn fees. - sweepAmt := int64(totalSum - txFee) + sweepAmt := totalSum - txFee // The txn will sweep the amount after fees to the pkscript generated // above. - sweepTx.AddTxOut(&wire.TxOut{ - PkScript: outputPkScript, - Value: sweepAmt, - }) + if sweepAmt >= dustLimit { + sweepTx.AddTxOut(&wire.TxOut{ + PkScript: outputPkScript, + Value: int64(sweepAmt), + }) + } // We'll default to using the current block height as locktime, if none // of the inputs commits to a different locktime. diff --git a/sweep/walletsweep.go b/sweep/walletsweep.go index aa6d658d..06c41e5a 100644 --- a/sweep/walletsweep.go +++ b/sweep/walletsweep.go @@ -153,10 +153,10 @@ type WalletSweepPackage struct { // by the delivery address. The sweep transaction will be crafted with the // target fee rate, and will use the utxoSource and outpointLocker as sources // for wallet funds. -func CraftSweepAllTx(feeRate chainfee.SatPerKWeight, blockHeight uint32, - deliveryAddr btcutil.Address, coinSelectLocker CoinSelectionLocker, - utxoSource UtxoSource, outpointLocker OutpointLocker, - feeEstimator chainfee.Estimator, +func CraftSweepAllTx(feeRate chainfee.SatPerKWeight, dustLimit btcutil.Amount, + blockHeight uint32, deliveryAddr btcutil.Address, + coinSelectLocker CoinSelectionLocker, utxoSource UtxoSource, + outpointLocker OutpointLocker, feeEstimator chainfee.Estimator, signer input.Signer) (*WalletSweepPackage, error) { // TODO(roasbeef): turn off ATPL as well when available? @@ -273,7 +273,8 @@ func CraftSweepAllTx(feeRate chainfee.SatPerKWeight, blockHeight uint32, // Finally, we'll ask the sweeper to craft a sweep transaction which // respects our fee preference and targets all the UTXOs of the wallet. sweepTx, err := createSweepTx( - inputsToSweep, deliveryPkScript, blockHeight, feeRate, signer, + inputsToSweep, deliveryPkScript, blockHeight, feeRate, + dustLimit, signer, ) if err != nil { unlockOutputs() diff --git a/sweep/walletsweep_test.go b/sweep/walletsweep_test.go index 4e098757..032f30c0 100644 --- a/sweep/walletsweep_test.go +++ b/sweep/walletsweep_test.go @@ -288,7 +288,7 @@ func TestCraftSweepAllTxCoinSelectFail(t *testing.T) { utxoLocker := newMockOutpointLocker() _, err := CraftSweepAllTx( - 0, 100, nil, coinSelectLocker, utxoSource, utxoLocker, nil, nil, + 0, 100, 10, nil, coinSelectLocker, utxoSource, utxoLocker, nil, nil, ) // Since we instructed the coin select locker to fail above, we should @@ -313,7 +313,7 @@ func TestCraftSweepAllTxUnknownWitnessType(t *testing.T) { utxoLocker := newMockOutpointLocker() _, err := CraftSweepAllTx( - 0, 100, nil, coinSelectLocker, utxoSource, utxoLocker, nil, nil, + 0, 100, 10, nil, coinSelectLocker, utxoSource, utxoLocker, nil, nil, ) // Since passed in a p2wsh output, which is unknown, we should fail to @@ -347,7 +347,7 @@ func TestCraftSweepAllTx(t *testing.T) { utxoLocker := newMockOutpointLocker() sweepPkg, err := CraftSweepAllTx( - 0, 100, deliveryAddr, coinSelectLocker, utxoSource, utxoLocker, + 0, 100, 10, deliveryAddr, coinSelectLocker, utxoSource, utxoLocker, feeEstimator, signer, ) if err != nil {