From 3c8442b1bb453ef8ccfd00b18939c4287bacd3a3 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 12 Jan 2016 03:47:12 -0800 Subject: [PATCH] improve fee calculation. --- lib/bcoin/tx.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 387aff58..44e7ed81 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -153,7 +153,6 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) { return -1; }; -// Build the scriptSigs for inputs, excluding the signatures TX.prototype.scriptInput = function scriptInput(index, pub, redeem) { var input, s, n, i; @@ -206,10 +205,12 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) { } // P2SH requires the redeem script after signatures - if (redeem) + if (redeem) { input.script.push(redeem); - - this._recalculateFee(); + // The fee can be calculated more accurately + // now that the redeem script is available. + this._recalculateFee(); + } }; // Sign the now-built scriptSigs @@ -702,6 +703,18 @@ TX.prototype.maxSize = function maxSize() { // Get the previous output's subscript s = input.out.tx.getSubscript(input.out.index); + // If we have access to the redeem script, + // we can use it to calculate size much easier. + if (this.inputs[i].script.length && bcoin.script.isScripthash(s)) { + s = this.inputs[i].script[this.inputs[i].script.length - 1]; + // Need to add the redeem script size + // here since it will be ignored by + // the isMultisig clause. + // OP_PUSHDATA2 [redeem] + size += 3 + s.length; + s = bcoin.script.normalize(s); + } + if (bcoin.script.isPubkey(s)) { // P2PK // OP_PUSHDATA0 [signature] @@ -718,7 +731,6 @@ TX.prototype.maxSize = function maxSize() { m = s[0]; if (Array.isArray(m)) m = m[0]; - assert(m >= 1 && m <= 3); // OP_0 size += 1; // OP_PUSHDATA0 [signature] ... @@ -880,7 +892,7 @@ TX.prototype._recalculateFee = function recalculateFee() { output = this.outputs[this.outputs.length - 1]; } - size = this.render().length; + size = this.maxSize(); real = Math.ceil(size / 1024) * constants.tx.fee; fee = this.getFee().toNumber();