From 3cb2c46b022df5b77e96e8536e4e1553d46f9ef5 Mon Sep 17 00:00:00 2001 From: eugene Date: Tue, 3 Aug 2021 16:40:17 -0400 Subject: [PATCH] mod+wallet: use btcd/mempool IsDust for calculating mempool dust We can now get rid of our incorrect dust calculation which did not give exact values for segwit outputs as it was based on spending a P2PKH output instead. --- go.mod | 2 +- go.sum | 3 +++ wallet/txauthor/author.go | 14 +++++++------- wallet/txrules/rules.go | 33 ++------------------------------- 4 files changed, 13 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 135f2c1..730dd0e 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/btcsuite/btcwallet require ( - github.com/btcsuite/btcd v0.21.0-beta.0.20210426180113-7eba688b65e5 + github.com/btcsuite/btcd v0.22.0-beta.0.20210803133449-f5a1fb9965e4 github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/btcsuite/btcutil/psbt v1.0.3-0.20201208143702-a53e38424cce diff --git a/go.sum b/go.sum index 2fa7da7..c5f3fce 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13P github.com/btcsuite/btcd v0.21.0-beta.0.20201208033208-6bd4c64a54fa/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= github.com/btcsuite/btcd v0.21.0-beta.0.20210426180113-7eba688b65e5 h1:Y0v9TA1ZLSs2TNFRSrpcGk00GWq1fenVL6FsuD3dCKI= github.com/btcsuite/btcd v0.21.0-beta.0.20210426180113-7eba688b65e5/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= +github.com/btcsuite/btcd v0.22.0-beta.0.20210803133449-f5a1fb9965e4 h1:EmyLrldY44jDVa3dQ2iscj1S6ExuVJhRzCZBOXo93r0= +github.com/btcsuite/btcd v0.22.0-beta.0.20210803133449-f5a1fb9965e4/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -24,6 +26,7 @@ github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/wallet/txauthor/author.go b/wallet/txauthor/author.go index dbeaa05..f291772 100644 --- a/wallet/txauthor/author.go +++ b/wallet/txauthor/author.go @@ -143,14 +143,14 @@ func NewUnsignedTransaction(outputs []*wire.TxOut, feeRatePerKb btcutil.Amount, changeIndex := -1 changeAmount := inputAmount - targetAmount - maxRequiredFee - if changeAmount != 0 && !txrules.IsDustAmount(changeAmount, - changeSource.ScriptSize, txrules.DefaultRelayFeePerKb) { + changeScript, err := changeSource.NewScript() + if err != nil { + return nil, err + } + change := wire.NewTxOut(int64(changeAmount), changeScript) + if changeAmount != 0 && !txrules.IsDustOutput(change, + txrules.DefaultRelayFeePerKb) { - changeScript, err := changeSource.NewScript() - if err != nil { - return nil, err - } - change := wire.NewTxOut(int64(changeAmount), changeScript) l := len(outputs) unsignedTransaction.TxOut = append(outputs[:l:l], change) changeIndex = l diff --git a/wallet/txrules/rules.go b/wallet/txrules/rules.go index f2df7b9..7739c2c 100644 --- a/wallet/txrules/rules.go +++ b/wallet/txrules/rules.go @@ -9,6 +9,7 @@ package txrules import ( "errors" + "github.com/btcsuite/btcd/mempool" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -17,30 +18,6 @@ import ( // DefaultRelayFeePerKb is the default minimum relay fee policy for a mempool. const DefaultRelayFeePerKb btcutil.Amount = 1e3 -// GetDustThreshold is used to define the amount below which output will be -// determined as dust. Threshold is determined as 3 times the relay fee. -func GetDustThreshold(scriptSize int, relayFeePerKb btcutil.Amount) btcutil.Amount { - // Calculate the total (estimated) cost to the network. This is - // calculated using the serialize size of the output plus the serial - // size of a transaction input which redeems it. The output is assumed - // to be compressed P2PKH as this is the most common script type. Use - // the average size of a compressed P2PKH redeem input (148) rather than - // the largest possible (txsizes.RedeemP2PKHInputSize). - totalSize := 8 + wire.VarIntSerializeSize(uint64(scriptSize)) + - scriptSize + 148 - - byteFee := relayFeePerKb / 1000 - relayFee := btcutil.Amount(totalSize) * byteFee - return 3 * relayFee -} - -// IsDustAmount determines whether a transaction output value and script length would -// cause the output to be considered dust. Transactions with dust outputs are -// not standard and are rejected by mempools with default policies. -func IsDustAmount(amount btcutil.Amount, scriptSize int, relayFeePerKb btcutil.Amount) bool { - return amount < GetDustThreshold(scriptSize, relayFeePerKb) -} - // IsDustOutput determines whether a transaction output is considered dust. // Transactions with dust outputs are not standard and are rejected by mempools // with default policies. @@ -50,13 +27,7 @@ func IsDustOutput(output *wire.TxOut, relayFeePerKb btcutil.Amount) bool { return false } - // All other unspendable outputs are considered dust. - if txscript.IsUnspendable(output.PkScript) { - return true - } - - return IsDustAmount(btcutil.Amount(output.Value), len(output.PkScript), - relayFeePerKb) + return mempool.IsDust(output, relayFeePerKb) } // Transaction rule violations