From 79a17d67ecfdb2ac3554d3fec80deab9ad0030c5 Mon Sep 17 00:00:00 2001
From: Wei Lu <luwei.here@gmail.com>
Date: Wed, 18 Jun 2014 21:16:17 +0800
Subject: [PATCH] wallet: do not overestimate fees when network has
 dustSoftThreshold

---
 src/wallet.js  |  2 +-
 test/wallet.js | 54 +++++++++++++++++++++++++++++++++++---------------
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/src/wallet.js b/src/wallet.js
index 78be584..d3c3fbe 100644
--- a/src/wallet.js
+++ b/src/wallet.js
@@ -235,7 +235,7 @@ function Wallet(seed, network) {
 
   function estimateFeePadChangeOutput(tx) {
     var tmpTx = tx.clone()
-    tmpTx.addOutput(getChangeAddress(), 0)
+    tmpTx.addOutput(getChangeAddress(), network.dustSoftThreshold || 0)
 
     return network.estimateFee(tmpTx)
   }
diff --git a/test/wallet.js b/test/wallet.js
index a1f0905..58a0283 100644
--- a/test/wallet.js
+++ b/test/wallet.js
@@ -397,25 +397,12 @@ describe('Wallet', function() {
       wallet.setUnspentOutputs(utxo)
     })
 
-    describe('choosing utxo', function(){
-      it('calculates fees', function(){
-        var tx = wallet.createTx(to, value)
-
-        assert.equal(tx.ins.length, 1)
-        assert.deepEqual(tx.ins[0].hash, fakeTxHash(3))
-        assert.equal(tx.ins[0].index, 0)
-      })
-
+    describe('transaction fee', function(){
       it('allows fee to be specified', function(){
         var fee = 30000
         var tx = wallet.createTx(to, value, fee)
 
-        assert.equal(tx.ins.length, 2)
-
-        assert.deepEqual(tx.ins[0].hash, fakeTxHash(3))
-        assert.equal(tx.ins[0].index, 0)
-        assert.deepEqual(tx.ins[1].hash, fakeTxHash(2))
-        assert.equal(tx.ins[1].index, 1)
+        assert.equal(getFee(wallet, tx), fee)
       })
 
       it('allows fee to be set to zero', function(){
@@ -423,6 +410,41 @@ describe('Wallet', function() {
         var fee = 0
         var tx = wallet.createTx(to, value, fee)
 
+        assert.equal(getFee(wallet, tx), fee)
+      })
+
+      it('does not overestimate fees when network has dustSoftThreshold', function(){
+        var wallet = new Wallet(seed, networks.litecoin)
+        var address = wallet.generateAddress()
+        wallet.setUnspentOutputs([{
+          hash: fakeTxId(0),
+          outputIndex: 0,
+          address: address,
+          value: 500000
+        }])
+
+        value = 200000
+        var tx = wallet.createTx(address, value)
+
+        assert.equal(getFee(wallet, tx), 100000)
+      })
+
+      function getFee(wallet, tx) {
+        var inputValue = tx.ins.reduce(function(memo, input){
+          var id = Array.prototype.reverse.call(input.hash).toString('hex')
+          return memo + wallet.outputs[id + ':' + input.index].value
+        }, 0)
+
+        return tx.outs.reduce(function(memo, output){
+          return memo - output.value
+        }, inputValue)
+      }
+    })
+
+    describe('choosing utxo', function(){
+      it('takes fees into account', function(){
+        var tx = wallet.createTx(to, value)
+
         assert.equal(tx.ins.length, 1)
         assert.deepEqual(tx.ins[0].hash, fakeTxHash(3))
         assert.equal(tx.ins[0].index, 0)
@@ -448,7 +470,7 @@ describe('Wallet', function() {
       })
     })
 
-    describe(networks.testnet, function(){
+    describe('works for testnet', function(){
       it('should create transaction', function(){
         var wallet = new Wallet(seed, networks.testnet)
         var address = wallet.generateAddress()