Browse Source

FIX: TX with extra small change output throws dust error

localNotifications
Overtorment 6 years ago
committed by Igor Korsakov
parent
commit
2a7236ada1
  1. 11
      HDWallet.test.js
  2. 15
      models/signer.js
  3. 15
      tests/unit/signer.js

11
HDWallet.test.js

@ -1,6 +1,7 @@
/* global it, jasmine */
import { SegwitP2SHWallet, SegwitBech32Wallet, HDSegwitP2SHWallet, HDLegacyBreadwalletWallet, HDLegacyP2PKHWallet } from './class';
let assert = require('assert');
let bitcoin = require('bitcoinjs-lib');
it('can convert witness to address', () => {
let address = SegwitP2SHWallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
@ -88,7 +89,6 @@ it('HD (BIP49) can create TX', async () => {
'010000000001029d98d81fe2b596fd79e845fa9f38d7e0b6fb73303c40fac604d04df1fa137aee00000000171600142f18e8406c9d210f30c901b24e5feeae78784eb7ffffffff67fb86f310df24e508d40fce9511c7fde4dd4ee91305fd08a074279a70e2cd22000000001716001468dde644410cc789d91a7f36b823f38369755a1cffffffff02780500000000000017a914a3a65daca3064280ae072b9d6773c027b30abace87dc0500000000000017a914850f4dbc255654de2c12c6f6d79cf9cb756cad038702483045022100dc8390a9fd34c31259fa47f9fc182f20d991110ecfd5b58af1cf542fe8de257a022004c2d110da7b8c4127675beccc63b46fd65c706951f090fd381fa3b21d3c5c08012102edd141c5a27a726dda66be10a38b0fd3ccbb40e7c380034aaa43a1656d5f4dd60247304402207c0aef8313d55e72474247daad955979f62e56d1cbac5f2d14b8b022c6ce112602205d9aa3804f04624b12ab8a5ab0214b529c531c2f71c27c6f18aba6502a6ea0a80121030db3c49461a5e539e97bab62ab2b8f88151d1c2376493cf73ef1d02ef60637fd00000000',
);
let bitcoin = require('bitcoinjs-lib');
txhex = hd.createTx(hd.utxo, 0.000005, 0.000001, '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK');
var tx = bitcoin.Transaction.fromHex(txhex);
assert.equal(tx.ins.length, 1);
@ -118,6 +118,15 @@ it('HD (BIP49) can create TX', async () => {
chunksIn = bitcoin.script.decompile(tx.outs[0].script);
toAddress = bitcoin.address.fromOutputScript(chunksIn);
assert.equal('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
// checking that change amount is at least 3x of fee, otherwise screw the change, just add it to fee.
// theres 0.00003 on UTXOs, lets transfer (0.00003 - 100sat), soo fee is equal to change (100 sat)
// which throws @dust error if broadcasted
txhex = hd.createTx(hd.utxo, 0.000028, 0.000001, '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK');
tx = bitcoin.Transaction.fromHex(txhex);
assert.equal(tx.ins.length, 2);
assert.equal(tx.outs.length, 1); // only 1 output, which means change is neglected
assert.equal(tx.outs[0].value, 2800);
});
it('Segwit HD (BIP49) can fetch UTXO', async function() {

15
models/signer.js

@ -32,7 +32,7 @@ exports.createHDSegwitTransaction = function(utxos, toAddress, amount, fixedFee,
ourOutputs[outputNum].amount = unspent.amount;
unspentAmountSatoshi += unspent.amount;
if (unspentAmountSatoshi >= amountToOutputSatoshi + feeInSatoshis) {
// found enough inputs su satisfy payee and pay fees
// found enough inputs to satisfy payee and pay fees
break;
}
outputNum++;
@ -47,7 +47,11 @@ exports.createHDSegwitTransaction = function(utxos, toAddress, amount, fixedFee,
txb.addOutput(toAddress, amountToOutputSatoshi);
if (amountToOutputSatoshi + feeInSatoshis < unspentAmountSatoshi) {
// sending less than we have, so the rest should go back
txb.addOutput(changeAddress, unspentAmountSatoshi - amountToOutputSatoshi - feeInSatoshis);
if (unspentAmountSatoshi - amountToOutputSatoshi - feeInSatoshis > 3 * feeInSatoshis) {
// to prevent @dust error change transferred amount should be at least 3xfee.
// if not - we just dont send change and it wil add to fee
txb.addOutput(changeAddress, unspentAmountSatoshi - amountToOutputSatoshi - feeInSatoshis);
}
}
// now, signing every input with a corresponding key
@ -86,7 +90,12 @@ exports.createSegwitTransaction = function(utxos, toAddress, amount, fixedFee, W
txb.addOutput(toAddress, amountToOutput);
if (amountToOutput + feeInSatoshis < unspentAmount) {
// sending less than we have, so the rest should go back
txb.addOutput(changeAddress, unspentAmount - amountToOutput - feeInSatoshis);
if (unspentAmount - amountToOutput - feeInSatoshis > 3 * feeInSatoshis) {
// to prevent @dust error change transferred amount should be at least 3xfee.
// if not - we just dont send change and it wil add to fee
txb.addOutput(changeAddress, unspentAmount - amountToOutput - feeInSatoshis);
}
}
for (let c = 0; c < utxos.length; c++) {

15
tests/unit/signer.js

@ -67,6 +67,21 @@ describe('unit - signer', function () {
assert.equal(tx, '0100000000010160d3d8d96a31d6bae5e2927bb4fe7be81702bb1787b3f9770a8084040359051601000000171600141e16a923b1a9e8d0c2a044030608a6aa13f97e9affffffff0230e60200000000001976a914f7c6c1f9f6142107ed293c8fbf85fbc49eb5f1b988ac400d03000000000017a914e0d81f03546ab8f29392b488ec62ab355ee7c573870247304402202c962e14ae6abd45dc9613d2f088ad487e805670548e244deb25d762b310a60002204f12c7f9b8da3567b39906ff6c46b27ce087e7ae91bbe34fb1cdee1b994b9d3001210314389c888e9669ae05739819fc7c43d7a50fdeabd2a8951f9607c8cad394fd4b00000000')
done()
})
it('should return valid tx hex for segwit transactions if change is too small so it causes @dust error', function (done) {
// checking that change amount is at least 3x of fee, otherwise screw the change, just add it to fee
let signer = require('../../models/signer')
let utxos = [ { 'txid': '160559030484800a77f9b38717bb0217e87bfeb47b92e2e5bad6316ad9d8d360', 'vout': 1, 'address': '3NBtBset4qPD8DZeLw4QbFi6SNjNL8hg7x', 'account': '3NBtBset4qPD8DZeLw4QbFi6SNjNL8hg7x', 'scriptPubKey': 'a914e0d81f03546ab8f29392b488ec62ab355ee7c57387', 'amount': 0.00400000, 'confirmations': 271, 'spendable': false, 'solvable': false, 'safe': true } ]
let txhex = signer.createSegwitTransaction(utxos, '1Pb81K1xJnMjUfFgKUbva6gr1HCHXxHVnr', 0.003998, 0.000001, 'L4iRvejJG9gRhKVc3rZm5haoyd4EuCi77G91DnXRrvNDqiXktkXh')
let bitcoin = require('bitcoinjs-lib')
let tx = bitcoin.Transaction.fromHex(txhex);
assert.equal(tx.ins.length, 1);
assert.equal(tx.outs.length, 1); // only 1 output, which means change is neglected
assert.equal(tx.outs[0].value, 399700);
done()
})
})
describe('WIF2address()', function () {

Loading…
Cancel
Save