Do not include zero value change outputs.

Due to the way dust is calculated, if the transaction relay fee is
zero, then a zero output amount is not considered dust.  As the
transaction authoring code used this dust check to determine whether a
change output can be included or not, it could create unnecessary
change outputs which return no value back to the wallet.  Prevent this
by including an explicit check for zero values.
This commit is contained in:
Josh Rickmar 2016-04-18 12:47:09 -04:00
parent f827743934
commit 7b2e1ac282
2 changed files with 17 additions and 1 deletions

View file

@ -107,7 +107,8 @@ func NewUnsignedTransaction(outputs []*wire.TxOut, relayFeePerKb btcutil.Amount,
}
changeIndex := -1
changeAmount := inputAmount - targetAmount - maxRequiredFee
if !txrules.IsDustAmount(changeAmount, txsizes.P2PKHPkScriptSize, relayFeePerKb) {
if changeAmount != 0 && !txrules.IsDustAmount(changeAmount,
txsizes.P2PKHPkScriptSize, relayFeePerKb) {
changeScript, err := fetchChange()
if err != nil {
return nil, err

View file

@ -160,6 +160,16 @@ func TestNewUnsignedTransaction(t *testing.T) {
txsizes.EstimateSerializeSize(2, p2pkhOutputs(1e8), true)),
InputCount: 2,
},
// Test that zero change outputs are not included
// (ChangeAmount=0 means don't include any change output).
12: {
UnspentOutputs: p2pkhOutputs(1e8),
Outputs: p2pkhOutputs(1e8),
RelayFee: 0,
ChangeAmount: 0,
InputCount: 1,
},
}
changeSource := func() ([]byte, error) {
@ -190,6 +200,11 @@ func TestNewUnsignedTransaction(t *testing.T) {
}
} else {
changeAmount := btcutil.Amount(tx.Tx.TxOut[tx.ChangeIndex].Value)
if test.ChangeAmount == 0 {
t.Errorf("Test %d: Included change output with value %v but expected no change",
i, changeAmount)
continue
}
if changeAmount != test.ChangeAmount {
t.Errorf("Test %d: Got change amount %v, Expected %v",
i, changeAmount, test.ChangeAmount)