better maxSize calculation.

This commit is contained in:
Christopher Jeffrey 2016-03-31 05:44:45 -07:00
parent 3242f39972
commit 6c69914da5

View File

@ -684,21 +684,37 @@ MTX.prototype.scriptOutput = function scriptOutput(index, options) {
output.script = Script.createOutputScript(options); output.script = Script.createOutputScript(options);
}; };
MTX.prototype.maxSize = function maxSize(maxM, maxN) { MTX.prototype.isScripted = function isScripted() {
var copy = this.clone(); if (this.inputs.length === 0)
return false;
if (this.outputs.length === 0)
return false;
return this.inputs.every(function(input) {
return input.script.code.length > 0 || input.witness.items.length > 0;
});
};
MTX.prototype.maxSize = function maxSize(maxM, maxN, force) {
var i, j, input, total, size, prev, m, n, witness; var i, j, input, total, size, prev, m, n, witness;
// Create copy with 0-script inputs if (!force && this.isScripted())
for (i = 0; i < copy.inputs.length; i++) { return this.getVirtualSize();
copy.inputs[i].script = new Script([]);
copy.inputs[i].witness = new Witness([]); // Calculate the size, minus the input scripts.
total = bcoin.protocol.framer.tx.size(this);
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
size = input.script.getSize();
total -= utils.sizeVarint(size) + size;
total += 1;
} }
total = bcoin.protocol.framer.tx.size(copy);
// Add size for signatures and public keys // Add size for signatures and public keys
for (i = 0; i < copy.inputs.length; i++) { for (i = 0; i < this.inputs.length; i++) {
input = copy.inputs[i]; input = this.inputs[i];
size = 0; size = 0;
witness = false; witness = false;
@ -712,12 +728,12 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
// If we have access to the redeem script, // If we have access to the redeem script,
// we can use it to calculate size much easier. // we can use it to calculate size much easier.
if (this.inputs[i].script.code.length && prev.isScripthash()) { if (input.script.code.length && prev.isScripthash()) {
// Need to add the redeem script size // Need to add the redeem script size
// here since it will be ignored by // here since it will be ignored by
// the isMultisig clause. // the isMultisig clause.
// OP_PUSHDATA2 [redeem] // OP_PUSHDATA2 [redeem]
prev = this.inputs[i].script.getRedeem(); prev = input.script.getRedeem();
size += 3 + prev.getSize(); size += 3 + prev.getSize();
} }
@ -727,8 +743,8 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
// redeem script (if there was one) // redeem script (if there was one)
// is now worth 4 points. // is now worth 4 points.
size *= 4; size *= 4;
if (this.inputs[i].witness.items.length && prev.isWitnessScripthash()) { if (input.witness.items.length && prev.isWitnessScripthash()) {
prev = this.inputs[i].witness.getRedeem(); prev = input.witness.getRedeem();
size += 3 + prev.getSize(); size += 3 + prev.getSize();
} else if (prev.isWitnessPubkeyhash()) { } else if (prev.isWitnessPubkeyhash()) {
prev = Script.createPubkeyhash(prev.code[1]); prev = Script.createPubkeyhash(prev.code[1]);
@ -889,7 +905,7 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
// bytes (10000 satoshi for every 1024 bytes). // bytes (10000 satoshi for every 1024 bytes).
do { do {
// Calculate max possible size after signing. // Calculate max possible size after signing.
size = tx.maxSize(options.m, options.n); size = tx.maxSize(options.m, options.n, true);
if (tryFree) { if (tryFree) {
if (tx.isFree(network.height + 1, size)) { if (tx.isFree(network.height + 1, size)) {