Browse Source

TransactionBuilder: change to ABSURD_FEERATE, not ABSURD_FEE

hk-custom-address
Daniel Cousens 8 years ago
committed by Thomas Kerin
parent
commit
62389ed247
  1. 17
      src/transaction_builder.js
  2. 20
      test/fixtures/transaction_builder.json
  3. 20
      test/transaction_builder.js

17
src/transaction_builder.js

@ -384,9 +384,6 @@ TransactionBuilder.prototype.__build = function (allowIncomplete) {
if (!allowIncomplete) { if (!allowIncomplete) {
if (!this.tx.ins.length) throw new Error('Transaction has no inputs') if (!this.tx.ins.length) throw new Error('Transaction has no inputs')
if (!this.tx.outs.length) throw new Error('Transaction has no outputs') if (!this.tx.outs.length) throw new Error('Transaction has no outputs')
// do not rely on this, its merely a last resort
if (this.__hasAbsurdFee()) throw new Error('Transaction has absurd fees')
} }
var tx = this.tx.clone() var tx = this.tx.clone()
@ -408,6 +405,13 @@ TransactionBuilder.prototype.__build = function (allowIncomplete) {
tx.setInputScript(i, scriptSig) tx.setInputScript(i, scriptSig)
}) })
if (!allowIncomplete) {
// do not rely on this, its merely a last resort
if (this.__hasAbsurdFeeRate(tx.byteLength())) {
throw new Error('Transaction has absurd fees')
}
}
return tx return tx
} }
@ -499,7 +503,7 @@ TransactionBuilder.prototype.__canModifyOutputs = function () {
}) })
} }
TransactionBuilder.prototype.__hasAbsurdFee = function () { TransactionBuilder.prototype.__hasAbsurdFeeRate = function (bytes) {
// not all inputs will have .value defined // not all inputs will have .value defined
var incoming = this.inputs.reduce(function (a, x) { return a + (x.value >>> 0) }, 0) var incoming = this.inputs.reduce(function (a, x) { return a + (x.value >>> 0) }, 0)
@ -507,10 +511,9 @@ TransactionBuilder.prototype.__hasAbsurdFee = function () {
// we can immediately determine if the outputs are too small // we can immediately determine if the outputs are too small
var outgoing = this.tx.outs.reduce(function (a, x) { return a + x.value }, 0) var outgoing = this.tx.outs.reduce(function (a, x) { return a + x.value }, 0)
var fee = incoming - outgoing var fee = incoming - outgoing
var feeRate = fee / bytes
// its not fool-proof, but, it might help somebody return feeRate > 1000
// fee > 0.2BTC
return fee > (0.2 * 1e8)
} }
module.exports = TransactionBuilder module.exports = TransactionBuilder

20
test/fixtures/transaction_builder.json

@ -666,14 +666,28 @@
"exception": "Transaction has absurd fees", "exception": "Transaction has absurd fees",
"inputs": [ "inputs": [
{ {
"txHex": "01000000000100e1f505000000000000000000", "txRaw": {
"vout": 0 "inputs": [],
"outputs": [
{
"address": "1C5XhB1UkFuyCV1CG9dmXaXGu3xDL4nAjv",
"value": 1000000000
}
],
"incomplete": true
},
"vout": 0,
"signs": [
{
"keyPair": "KzBQVXYUGDAvqG7VeU3C7ZMRYiwtsxSVVFcYGzKU9E4aUVDUquZU"
}
]
} }
], ],
"outputs": [ "outputs": [
{ {
"script": "OP_DUP OP_HASH160 ff99e06c1a4ac394b4e1cb3d3a4b2b47749e339a OP_EQUALVERIFY OP_CHECKSIG", "script": "OP_DUP OP_HASH160 ff99e06c1a4ac394b4e1cb3d3a4b2b47749e339a OP_EQUALVERIFY OP_CHECKSIG",
"value": 100000 "value": 200000
} }
] ]
}, },

20
test/transaction_builder.js

@ -21,17 +21,31 @@ function construct (f, sign) {
if (f.locktime !== undefined) txb.setLockTime(f.locktime) if (f.locktime !== undefined) txb.setLockTime(f.locktime)
f.inputs.forEach(function (input) { f.inputs.forEach(function (input) {
var prevTxScript var prevTx
if (input.txRaw) {
var constructed = construct(input.txRaw)
if (input.txRaw.incomplete) prevTx = constructed.buildIncomplete()
else prevTx = constructed.build()
} else if (input.txHex) {
prevTx = Transaction.fromHex(input.txHex)
} else {
prevTx = input.txId
}
if (!input.txHex && input.prevTxScript) { var prevTxScript
if (input.prevTxScript) {
prevTxScript = bscript.fromASM(input.prevTxScript) prevTxScript = bscript.fromASM(input.prevTxScript)
} }
txb.addInput(input.txId || Transaction.fromHex(input.txHex), input.vout, input.sequence, prevTxScript) txb.addInput(prevTx, input.vout, input.sequence, prevTxScript)
}) })
f.outputs.forEach(function (output) { f.outputs.forEach(function (output) {
if (output.address) {
txb.addOutput(output.address, output.value)
} else {
txb.addOutput(bscript.fromASM(output.script), output.value) txb.addOutput(bscript.fromASM(output.script), output.value)
}
}) })
if (sign === false) return txb if (sign === false) return txb

Loading…
Cancel
Save