use js numbers for values.
This commit is contained in:
parent
f38350ec14
commit
dd5c9096a7
@ -434,7 +434,7 @@ Block.prototype.getReward = function getReward(network) {
|
||||
var i;
|
||||
|
||||
for (i = 1; i < this.txs.length; i++)
|
||||
reward.iadd(this.txs[i].getFee());
|
||||
reward += this.txs[i].getFee();
|
||||
|
||||
return reward;
|
||||
};
|
||||
@ -463,13 +463,18 @@ Block.reward = function reward(height, network) {
|
||||
halvings = height / network.halvingInterval | 0;
|
||||
|
||||
if (height < 0)
|
||||
return new bn(0);
|
||||
return 0;
|
||||
|
||||
if (halvings >= 64)
|
||||
return new bn(0);
|
||||
return 0;
|
||||
|
||||
reward = new bn(5000000000);
|
||||
reward.iushrn(halvings);
|
||||
if (halvings === 0)
|
||||
return 5000000000;
|
||||
|
||||
reward = 2500000000 >>> (halvings - 1);
|
||||
|
||||
// reward = 5000000000;
|
||||
// reward = Math.floor(reward / Math.pow(2, halvings));
|
||||
|
||||
return reward;
|
||||
};
|
||||
|
||||
@ -909,7 +909,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, state, callbac
|
||||
}
|
||||
|
||||
// Make sure the miner isn't trying to conjure more coins.
|
||||
if (block.getClaimed().cmp(block.getReward(self.network)) > 0) {
|
||||
if (block.getClaimed() > block.getReward(self.network)) {
|
||||
return callback(new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-cb-amount',
|
||||
|
||||
@ -45,8 +45,6 @@ function Coin(tx, index) {
|
||||
this.version = tx.version;
|
||||
this.height = tx.height;
|
||||
this.value = tx.outputs[index].value;
|
||||
if (tx.mutable)
|
||||
this.value = this.value.clone();
|
||||
this.script = bcoin.script(tx.outputs[index].script, false);
|
||||
this.coinbase = tx.isCoinbase();
|
||||
this.hash = tx.hash('hex');
|
||||
@ -64,7 +62,7 @@ function Coin(tx, index) {
|
||||
|
||||
assert(typeof this.version === 'number');
|
||||
assert(utils.isNumber(this.height));
|
||||
assert(bn.isBN(this.value));
|
||||
assert(typeof this.value === 'number');
|
||||
assert(this.script instanceof bcoin.script);
|
||||
assert(typeof this.coinbase === 'boolean');
|
||||
assert(!this.hash || typeof this.hash === 'string');
|
||||
|
||||
@ -843,7 +843,7 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(entry, limit, callb
|
||||
self.total--;
|
||||
|
||||
if (limit) {
|
||||
rate = entry.fees.muln(1000).divn(entry.size).toNumber();
|
||||
rate = Math.floor(entry.fees * 1000 / entry.size);
|
||||
rate += self.minReasonableFee;
|
||||
if (rate > self.minFeeRate) {
|
||||
self.minFeeRate = rate;
|
||||
@ -952,14 +952,14 @@ Mempool.prototype.verify = function verify(entry, callback) {
|
||||
rejectFee = tx.getMinFee(size, minRate);
|
||||
minRelayFee = tx.getMinFee(size, self.minRelayFee);
|
||||
|
||||
if (rejectFee.cmpn(0) > 0 && modFee.cmp(rejectFee) < 0) {
|
||||
if (rejectFee > 0 && modFee < rejectFee) {
|
||||
return callback(new VerifyError(tx,
|
||||
'insufficientfee',
|
||||
'mempool min fee not met',
|
||||
0));
|
||||
}
|
||||
|
||||
if (self.relayPriority && modFee.cmp(minRelayFee) < 0) {
|
||||
if (self.relayPriority && modFee < minRelayFee) {
|
||||
if (!entry.isFree(height)) {
|
||||
return callback(new VerifyError(tx,
|
||||
'insufficientfee',
|
||||
@ -973,7 +973,7 @@ Mempool.prototype.verify = function verify(entry, callback) {
|
||||
// sending thousands of free transactions just to be
|
||||
// annoying or make others' transactions take longer
|
||||
// to confirm.
|
||||
if (self.limitFree && modFee.cmp(minRelayFee) < 0) {
|
||||
if (self.limitFree && modFee < minRelayFee) {
|
||||
now = utils.now();
|
||||
|
||||
if (!self.lastTime)
|
||||
@ -995,7 +995,7 @@ Mempool.prototype.verify = function verify(entry, callback) {
|
||||
self.freeCount += size;
|
||||
}
|
||||
|
||||
if (self.rejectAbsurdFees && fee.cmp(minRelayFee.muln(10000)) > 0)
|
||||
if (self.rejectAbsurdFees && fee > minRelayFee * 10000)
|
||||
return callback(new VerifyError(tx, 'highfee', 'absurdly-high-fee', 0));
|
||||
|
||||
if (!tx.checkInputs(height, ret))
|
||||
@ -1136,7 +1136,7 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx, callback, force) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getBalance = function getBalance(callback) {
|
||||
var total = new bn(0);
|
||||
var total = 0;
|
||||
var i;
|
||||
|
||||
return this.db.iterate({
|
||||
@ -1151,10 +1151,10 @@ Mempool.prototype.getBalance = function getBalance(callback) {
|
||||
return callback(err);
|
||||
|
||||
for (i = 0; i < coins.length; i++)
|
||||
total.iadd(coins[i].value);
|
||||
total += coins[i].value;
|
||||
|
||||
return callback(null, {
|
||||
confirmed: new bn(0),
|
||||
confirmed: 0,
|
||||
unconfirmed: total,
|
||||
total: total
|
||||
});
|
||||
@ -1876,12 +1876,12 @@ MempoolEntry.fromRaw = function fromRaw(data) {
|
||||
return new MempoolEntry({
|
||||
tx: bcoin.tx.fromRaw(p),
|
||||
height: p.readU32(),
|
||||
priority: p.readVarint(true),
|
||||
chainValue: p.readVarint(true),
|
||||
priority: p.readVarint(),
|
||||
chainValue: p.readVarint(),
|
||||
ts: p.readU32(),
|
||||
count: p.readU32(),
|
||||
size: p.readU32(),
|
||||
fees: p.readVarint(true)
|
||||
fees: p.readVarint()
|
||||
});
|
||||
};
|
||||
|
||||
@ -1894,12 +1894,12 @@ MempoolEntry.fromRaw = function fromRaw(data) {
|
||||
*/
|
||||
|
||||
MempoolEntry.prototype.getPriority = function getPriority(height) {
|
||||
var heightDelta = Math.max(0, height - this.height);
|
||||
var heightDelta = height - this.height;
|
||||
var modSize = this.tx.getModifiedSize(this.size);
|
||||
var deltaPriority = new bn(heightDelta).mul(this.chainValue).divn(modSize);
|
||||
var result = this.priority.add(deltaPriority);
|
||||
if (result.cmpn(0) < 0)
|
||||
result = new bn(0);
|
||||
var deltaPriority = heightDelta * this.chainValue / modSize;
|
||||
var result = this.priority * deltaPriority;
|
||||
if (result < 0)
|
||||
result = 0;
|
||||
return result;
|
||||
};
|
||||
|
||||
@ -1913,7 +1913,7 @@ MempoolEntry.prototype.getPriority = function getPriority(height) {
|
||||
|
||||
MempoolEntry.prototype.isFree = function isFree(height) {
|
||||
var priority = this.getPriority(height);
|
||||
return priority.cmp(constants.tx.FREE_THRESHOLD) > 0;
|
||||
return priority > constants.tx.FREE_THRESHOLD;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -392,7 +392,7 @@ function MinerBlock(options) {
|
||||
|
||||
this.coinbase.addOutput({
|
||||
address: options.address,
|
||||
value: new bn(0)
|
||||
value: 0
|
||||
});
|
||||
|
||||
// Create our block
|
||||
@ -416,7 +416,7 @@ function MinerBlock(options) {
|
||||
this.coinbase.inputs[0].witness.items[0] = this.witnessNonce;
|
||||
this.coinbase.addOutput({
|
||||
script: new bcoin.script(),
|
||||
value: new bn(0)
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1082,11 +1082,11 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
||||
function total() {
|
||||
if (options.subtractFee != null)
|
||||
return outputValue;
|
||||
return outputValue.add(fee);
|
||||
return outputValue + fee;
|
||||
}
|
||||
|
||||
function isFull() {
|
||||
return tx.getInputValue().cmp(total()) >= 0;
|
||||
return tx.getInputValue() >= total();
|
||||
}
|
||||
|
||||
function addCoins() {
|
||||
@ -1124,7 +1124,7 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
||||
// Transfer `total` funds maximum.
|
||||
addCoins();
|
||||
} else {
|
||||
fee = new bn(constants.tx.MIN_FEE);
|
||||
fee = constants.tx.MIN_FEE;
|
||||
|
||||
// Transfer `total` funds maximum.
|
||||
addCoins();
|
||||
@ -1136,7 +1136,7 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
||||
// In case we don't have a change address,
|
||||
// use a fake p2pkh output to gauge size.
|
||||
keyHash: constants.ZERO_HASH.slice(0, 20),
|
||||
value: new bn(0)
|
||||
value: 0
|
||||
});
|
||||
|
||||
// Change fee value if it is more than 1024
|
||||
@ -1151,7 +1151,7 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
||||
// fee is zero (i.e. the mempool is
|
||||
// not full).
|
||||
if (tx.isFree(options.height + 1, size)) {
|
||||
fee = new bn(0);
|
||||
fee = 0;
|
||||
break;
|
||||
}
|
||||
tryFree = false;
|
||||
@ -1175,11 +1175,11 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (fee.cmp(constants.tx.MAX_FEE) > 0)
|
||||
fee = constants.tx.MAX_FEE.clone();
|
||||
if (fee > constants.tx.MAX_FEE)
|
||||
fee = constants.tx.MAX_FEE;
|
||||
|
||||
// How much money is left after filling outputs.
|
||||
change = tx.getInputValue().sub(total());
|
||||
change = tx.getInputValue() - total();
|
||||
|
||||
// Attempt to subtract fee.
|
||||
if (options.subtractFee != null) {
|
||||
@ -1190,18 +1190,18 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
||||
if (!output)
|
||||
throw new Error('Subtraction index does not exist.');
|
||||
|
||||
min = fee.add(output.getDustThreshold());
|
||||
min = fee + output.getDustThreshold();
|
||||
|
||||
if (output.value.cmp(min) < 0)
|
||||
if (output.value < 0)
|
||||
throw new Error('Could not subtract fee.');
|
||||
|
||||
output.value.isub(fee);
|
||||
output.value -= fee;
|
||||
} else {
|
||||
for (i = 0; i < tx.outputs.length; i++) {
|
||||
output = tx.outputs[i];
|
||||
min = fee.add(output.getDustThreshold());
|
||||
if (output.value.cmp(min) >= 0) {
|
||||
output.value.isub(fee);
|
||||
min = fee + output.getDustThreshold();
|
||||
if (output.value >= min) {
|
||||
output.value -= fee;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1253,10 +1253,10 @@ MTX.prototype.fill = function fill(coins, options) {
|
||||
// Do nothing. Change is added to fee.
|
||||
this.outputs.pop();
|
||||
this.changeIndex = -1;
|
||||
assert(this.getFee().cmp(result.fee.add(result.change)) === 0);
|
||||
assert(this.getFee() === result.fee + result.change);
|
||||
} else {
|
||||
this.changeIndex = this.outputs.length - 1;
|
||||
assert(this.getFee().cmp(result.fee) === 0);
|
||||
assert(this.getFee() === result.fee);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1287,7 +1287,7 @@ MTX.prototype.sortMembers = function sortMembers() {
|
||||
});
|
||||
|
||||
this.outputs = this.outputs.slice().sort(function(a, b) {
|
||||
var res = a.value.cmp(b.value);
|
||||
var res = a.value - b.value;
|
||||
if (res !== 0)
|
||||
return res;
|
||||
return utils.cmp(a.encode(), b.encode());
|
||||
|
||||
@ -35,20 +35,15 @@ function Output(options, mutable) {
|
||||
|
||||
value = options.value;
|
||||
|
||||
if (typeof value === 'number') {
|
||||
assert(value % 1 === 0, 'Output value cannot be a float.');
|
||||
value = new bn(value);
|
||||
}
|
||||
|
||||
if (!value)
|
||||
value = new bn(0);
|
||||
value = 0;
|
||||
|
||||
this.mutable = !!mutable;
|
||||
this.value = value;
|
||||
this.script = bcoin.script(options.script, this.mutable);
|
||||
|
||||
assert(bn.isBN(this.value));
|
||||
assert(!this.mutable || !this.value.isNeg());
|
||||
assert(typeof this.value === 'number');
|
||||
assert(!this.mutable || this.value > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,12 +162,12 @@ Output.prototype.getDustThreshold = function getDustThreshold(rate) {
|
||||
rate = constants.tx.MIN_RELAY;
|
||||
|
||||
if (this.script.isUnspendable())
|
||||
return new bn(0);
|
||||
return 0;
|
||||
|
||||
size = Framer.output(this, new BufferWriter()).written;
|
||||
size += 148;
|
||||
|
||||
return bcoin.tx.getMinFee(size, rate).muln(3);
|
||||
return 3 * bcoin.tx.getMinFee(size, rate);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -182,7 +177,7 @@ Output.prototype.getDustThreshold = function getDustThreshold(rate) {
|
||||
*/
|
||||
|
||||
Output.prototype.isDust = function isDust(rate) {
|
||||
return this.value.cmp(this.getDustThreshold(rate)) < 0;
|
||||
return this.value < this.getDustThreshold(rate);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -306,7 +306,7 @@ exports.opcodesByVal = utils.revMap(exports.opcodes);
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.COIN = new bn(10000000).muln(10);
|
||||
exports.COIN = 100000000;
|
||||
|
||||
/**
|
||||
* One bitcoin / 100.
|
||||
@ -314,7 +314,7 @@ exports.COIN = new bn(10000000).muln(10);
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.CENT = new bn(1000000);
|
||||
exports.CENT = 1000000;
|
||||
|
||||
/**
|
||||
* Maximum amount of money in satoshis (1btc * 21million)
|
||||
@ -322,7 +322,7 @@ exports.CENT = new bn(1000000);
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.MAX_MONEY = new bn(21000000).mul(exports.COIN);
|
||||
exports.MAX_MONEY = 21000000 * exports.COIN;
|
||||
|
||||
/**
|
||||
* Sighash Types.
|
||||
@ -410,10 +410,10 @@ exports.tx = {
|
||||
MAX_SIZE: 100000,
|
||||
MAX_COST: 400000,
|
||||
MIN_FEE: 10000,
|
||||
MAX_FEE: exports.COIN.divn(10),
|
||||
MAX_FEE: exports.COIN / 10,
|
||||
MIN_RELAY: 10000,
|
||||
BARE_MULTISIG: true,
|
||||
FREE_THRESHOLD: exports.COIN.muln(144).divn(250),
|
||||
FREE_THRESHOLD: Math.floor(exports.COIN * 144 / 250),
|
||||
MAX_SIGOPS: exports.block.MAX_SIGOPS / 5,
|
||||
MAX_SIGOPS_COST: exports.block.MAX_SIGOPS_COST / 5,
|
||||
COINBASE_MATURITY: 100
|
||||
|
||||
@ -652,8 +652,6 @@ Framer.coin = function _coin(coin, extended, writer) {
|
||||
if (height === -1)
|
||||
height = 0x7fffffff;
|
||||
|
||||
assert(coin.value.byteLength() <= 8);
|
||||
|
||||
p.writeU32(coin.version);
|
||||
p.writeU32(height);
|
||||
p.write64(coin.value);
|
||||
@ -753,8 +751,6 @@ Framer.input = function _input(input, writer) {
|
||||
Framer.output = function _output(output, writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
|
||||
assert(output.value.byteLength() <= 8);
|
||||
|
||||
p.write64(output.value);
|
||||
Framer.script(output.script, p);
|
||||
|
||||
|
||||
@ -875,7 +875,7 @@ Parser.parseOutput = function parseOutput(p) {
|
||||
|
||||
p = new BufferReader(p);
|
||||
|
||||
value = p.read64();
|
||||
value = p.read64N();
|
||||
script = Parser.parseScript(p);
|
||||
|
||||
return {
|
||||
@ -898,7 +898,7 @@ Parser.parseCoin = function parseCoin(p, extended) {
|
||||
|
||||
version = p.readU32();
|
||||
height = p.readU32();
|
||||
value = p.read64();
|
||||
value = p.read64N();
|
||||
script = Parser.parseScript(p);
|
||||
coinbase = p.readU8() === 1;
|
||||
|
||||
|
||||
@ -2700,35 +2700,26 @@ Script.isUnknownInput = function isUnknownInput(code, isWitness) {
|
||||
* @example
|
||||
* Script.createOutputScript({ address: '1HT7xU2Ngenf7D4yocz2SAcnNLW7rK8d4E' });
|
||||
* @param {Object} options
|
||||
* @param {Base58Address?} options.address - Base58 address to send to.
|
||||
* @param {(Address|Base58Address)?} options.address - Address to send to.
|
||||
* @param {Buffer?} options.flags - Nulldata flags.
|
||||
* @param {Buffer?} options.key - Key for pay-to-pubkey.
|
||||
* @param {Buffer?} options.keyHash - Key has for pay-to-pubkeyhash.
|
||||
* @param {Buffer[]?} options.keys - Keys for pay-to-multisig.
|
||||
* @param {Boolean|Buffer[]} options.scriptHash - Whether to create a scripthash
|
||||
* @param {Buffer} options.scriptHash - Whether to create a scripthash
|
||||
* @returns {Script}
|
||||
*/
|
||||
|
||||
Script.createOutputScript = function createOutputScript(options) {
|
||||
var script, m, n, hash, flags, address, redeem;
|
||||
var m, n, flags, address;
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
if (options.address) {
|
||||
if (typeof options.address === 'string')
|
||||
address = bcoin.address.parseBase58(options.address);
|
||||
|
||||
if (address.type === 'pubkeyhash')
|
||||
script = Script.createPubkeyhash(address.hash);
|
||||
else if (address.type === 'scripthash')
|
||||
script = Script.createScripthash(address.hash);
|
||||
else if (address.version !== -1)
|
||||
script = Script.createWitnessProgram(address.version, address.hash);
|
||||
else
|
||||
assert(false, 'Unknown address type.');
|
||||
|
||||
return script;
|
||||
address = options.address;
|
||||
if (typeof address === 'string')
|
||||
address = bcoin.address.fromBase58(address);
|
||||
return address.toScript();
|
||||
}
|
||||
|
||||
if (options.flags) {
|
||||
@ -2738,19 +2729,23 @@ Script.createOutputScript = function createOutputScript(options) {
|
||||
return Script.createNulldata(flags);
|
||||
}
|
||||
|
||||
if (options.key) {
|
||||
script = Script.createPubkey(options.key);
|
||||
} else if (options.keyHash) {
|
||||
if (options.key)
|
||||
return Script.createPubkey(options.key);
|
||||
|
||||
if (options.keyHash) {
|
||||
assert(options.keyHash.length === 20);
|
||||
if (options.version != null)
|
||||
script = Script.createWitnessProgram(options.version, options.keyHash);
|
||||
else
|
||||
script = Script.createPubkeyhash(options.keyHash);
|
||||
} else if (options.keys) {
|
||||
return Script.createWitnessProgram(options.version, options.keyHash);
|
||||
return Script.createPubkeyhash(options.keyHash);
|
||||
}
|
||||
|
||||
if (options.keys) {
|
||||
m = options.m;
|
||||
n = options.n || options.keys.length;
|
||||
script = Script.createMultisig(options.keys, m, n);
|
||||
} else if (Buffer.isBuffer(options.scriptHash)) {
|
||||
return Script.createMultisig(options.keys, m, n);
|
||||
}
|
||||
|
||||
if (options.scriptHash) {
|
||||
if (options.version != null) {
|
||||
assert(options.scriptHash.length === 32);
|
||||
return Script.createWitnessProgram(options.version, options.scriptHash);
|
||||
@ -2759,28 +2754,7 @@ Script.createOutputScript = function createOutputScript(options) {
|
||||
return Script.createScripthash(options.scriptHash);
|
||||
}
|
||||
|
||||
if (!script)
|
||||
return new Script([]);
|
||||
|
||||
if (options.locktime != null) {
|
||||
script.code.unshift(opcodes.OP_DROP);
|
||||
script.code.unshift(opcodes.OP_CHECKLOCKTIMEVERIFY);
|
||||
script.code.unshift(Script.array(options.locktime));
|
||||
}
|
||||
|
||||
if (options.scriptHash) {
|
||||
redeem = script;
|
||||
if (options.version != null) {
|
||||
hash = utils.sha256(redeem.encode());
|
||||
script = Script.createWitnessProgram(options.version, hash);
|
||||
} else {
|
||||
hash = utils.ripesha(redeem.encode());
|
||||
script = Script.createScripthash(hash);
|
||||
}
|
||||
script.redeem = redeem;
|
||||
}
|
||||
|
||||
return script;
|
||||
return new Script();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -428,7 +428,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) {
|
||||
for (i = 0; i < copy.outputs.length; i++) {
|
||||
if (i !== index) {
|
||||
copy.outputs[i].script = new Script([]);
|
||||
copy.outputs[i].value = utils.U64;
|
||||
copy.outputs[i].value = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,9 +651,9 @@ TX.prototype.isCoinbase = function isCoinbase() {
|
||||
|
||||
TX.prototype.getFee = function getFee() {
|
||||
if (!this.hasCoins())
|
||||
return new bn(0);
|
||||
return 0;
|
||||
|
||||
return this.getInputValue().sub(this.getOutputValue());
|
||||
return this.getInputValue() - this.getOutputValue();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -662,14 +662,14 @@ TX.prototype.getFee = function getFee() {
|
||||
*/
|
||||
|
||||
TX.prototype.getInputValue = function getInputValue() {
|
||||
var total = new bn(0);
|
||||
var total = 0;
|
||||
var i;
|
||||
|
||||
if (!this.hasCoins())
|
||||
return total;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++)
|
||||
total.iadd(this.inputs[i].coin.value);
|
||||
total += this.inputs[i].coin.value;
|
||||
|
||||
return total;
|
||||
};
|
||||
@ -680,11 +680,11 @@ TX.prototype.getInputValue = function getInputValue() {
|
||||
*/
|
||||
|
||||
TX.prototype.getOutputValue = function getOutputValue() {
|
||||
var total = new bn(0);
|
||||
var total = 0;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.outputs.length; i++)
|
||||
total.iadd(this.outputs[i].value);
|
||||
total += this.outputs[i].value;
|
||||
|
||||
return total;
|
||||
};
|
||||
@ -1056,7 +1056,7 @@ TX.prototype.getSigops = function getSigops(flags) {
|
||||
|
||||
TX.prototype.isSane = function isSane(ret) {
|
||||
var prevout = {};
|
||||
var total = new bn(0);
|
||||
var total = 0;
|
||||
var i, input, output, size, key;
|
||||
|
||||
if (!ret)
|
||||
@ -1083,21 +1083,21 @@ TX.prototype.isSane = function isSane(ret) {
|
||||
for (i = 0; i < this.outputs.length; i++) {
|
||||
output = this.outputs[i];
|
||||
|
||||
if (output.value.cmpn(0) < 0) {
|
||||
if (output.value < 0) {
|
||||
ret.reason = 'bad-txns-vout-negative';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output.value.cmp(constants.MAX_MONEY) > 0) {
|
||||
if (output.value > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-vout-toolarge';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
total.iadd(output.value);
|
||||
total += output.value;
|
||||
|
||||
if (total.cmpn(0) < 0 || total.cmp(constants.MAX_MONEY) > 0) {
|
||||
if (total < 0 || total > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-txouttotal-toolarge';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
@ -1286,7 +1286,7 @@ TX.prototype.hasStandardInputs = function hasStandardInputs(flags) {
|
||||
*/
|
||||
|
||||
TX.prototype.checkInputs = function checkInputs(spendHeight, ret) {
|
||||
var total = new bn(0);
|
||||
var total = 0;
|
||||
var i, input, coin, fee, value;
|
||||
|
||||
if (!ret)
|
||||
@ -1304,16 +1304,16 @@ TX.prototype.checkInputs = function checkInputs(spendHeight, ret) {
|
||||
}
|
||||
}
|
||||
|
||||
if (coin.value.cmpn(0) < 0 || coin.value.cmp(constants.MAX_MONEY) > 0) {
|
||||
if (coin.value < 0 || coin.value > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-inputvalues-outofrange';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
total.iadd(coin.value);
|
||||
total += coin.value;
|
||||
}
|
||||
|
||||
if (total.cmpn(0) < 0 || total.cmp(constants.MAX_MONEY) > 0) {
|
||||
if (total < 0 || total > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-inputvalues-outofrange';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
@ -1321,21 +1321,21 @@ TX.prototype.checkInputs = function checkInputs(spendHeight, ret) {
|
||||
|
||||
value = this.getOutputValue();
|
||||
|
||||
if (value.cmp(total) > 0) {
|
||||
if (value > total) {
|
||||
ret.reason = 'bad-txns-in-belowout'
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
fee = total.sub(value);
|
||||
fee = total - value;
|
||||
|
||||
if (fee.cmpn(0) < 0) {
|
||||
if (fee < 0) {
|
||||
ret.reason = 'bad-txns-fee-negative';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fee.cmp(constants.MAX_MONEY) > 0) {
|
||||
if (fee > constants.MAX_MONEY) {
|
||||
ret.reason = 'bad-txns-fee-outofrange';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
@ -1392,7 +1392,7 @@ TX.prototype.getPriority = function getPriority(height, size) {
|
||||
var sum, i, input, age, value;
|
||||
|
||||
if (this.isCoinbase())
|
||||
return new bn(0);
|
||||
return 0;
|
||||
|
||||
if (height == null) {
|
||||
height = this.height;
|
||||
@ -1403,8 +1403,8 @@ TX.prototype.getPriority = function getPriority(height, size) {
|
||||
if (size == null)
|
||||
size = this.maxSize();
|
||||
|
||||
sum = new bn(0);
|
||||
value = new bn(0);
|
||||
sum = 0;
|
||||
value = 0;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
@ -1417,14 +1417,14 @@ TX.prototype.getPriority = function getPriority(height, size) {
|
||||
|
||||
if (input.coin.height <= height) {
|
||||
age = height - input.coin.height;
|
||||
value.iadd(input.coin.value);
|
||||
sum.iadd(input.coin.value.muln(age));
|
||||
value += input.coin.value;
|
||||
sum += input.coin.value * age;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value: value,
|
||||
priority: sum.divn(size)
|
||||
priority: sum / size
|
||||
};
|
||||
};
|
||||
|
||||
@ -1451,7 +1451,7 @@ TX.prototype.isFree = function isFree(height, size) {
|
||||
|
||||
priority = this.getPriority(height, size).priority;
|
||||
|
||||
return priority.cmp(constants.tx.FREE_THRESHOLD) > 0;
|
||||
return priority > constants.tx.FREE_THRESHOLD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1483,10 +1483,10 @@ TX.getMinFee = function getMinFee(size, rate) {
|
||||
if (rate == null)
|
||||
rate = constants.tx.MIN_RELAY;
|
||||
|
||||
fee = new bn(rate).muln(size).divn(1000);
|
||||
fee = Math.floor(rate * size / 1000);
|
||||
|
||||
if (fee.cmpn(0) === 0 && rate > 0)
|
||||
fee = new bn(rate);
|
||||
if (fee === 0 && rate > 0)
|
||||
fee = rate;
|
||||
|
||||
return fee;
|
||||
};
|
||||
@ -1510,10 +1510,10 @@ TX.prototype.getMaxFee = function getMaxFee(size, rate) {
|
||||
if (rate == null)
|
||||
rate = constants.tx.MIN_RELAY;
|
||||
|
||||
fee = new bn(rate).muln(Math.ceil(size / 1000));
|
||||
fee = rate * Math.ceil(size / 1000);
|
||||
|
||||
if (fee.cmpn(0) === 0 && rate > 0)
|
||||
fee = new bn(rate);
|
||||
if (fee === 0 && rate > 0)
|
||||
fee = rate;
|
||||
|
||||
return fee;
|
||||
};
|
||||
|
||||
@ -1609,8 +1609,8 @@ TXDB.prototype.hasCoin = function hasCoin(hash, index, callback) {
|
||||
*/
|
||||
|
||||
TXDB.prototype.getBalance = function getBalance(address, callback) {
|
||||
var confirmed = new bn(0);
|
||||
var unconfirmed = new bn(0);
|
||||
var confirmed = 0;
|
||||
var unconfirmed = 0;
|
||||
var i;
|
||||
|
||||
if (typeof address === 'function') {
|
||||
@ -1624,15 +1624,15 @@ TXDB.prototype.getBalance = function getBalance(address, callback) {
|
||||
|
||||
for (i = 0; i < coins.length; i++) {
|
||||
if (coins[i].height === -1)
|
||||
unconfirmed.iadd(coins[i].value);
|
||||
unconfirmed += coins[i].value;
|
||||
else
|
||||
confirmed.iadd(coins[i].value);
|
||||
confirmed += coins[i].value;
|
||||
}
|
||||
|
||||
return callback(null, {
|
||||
confirmed: confirmed,
|
||||
unconfirmed: unconfirmed,
|
||||
total: confirmed.add(unconfirmed)
|
||||
total: confirmed + unconfirmed
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -638,7 +638,7 @@ utils.assert.fatal = function fatal(value, message) {
|
||||
* @default
|
||||
*/
|
||||
|
||||
utils.COIN = new bn(10000000).muln(10);
|
||||
utils.COIN = 100000000;
|
||||
|
||||
/**
|
||||
* Convert satoshis to a BTC string. Note that
|
||||
@ -656,16 +656,13 @@ utils.btc = function btc(satoshi) {
|
||||
|
||||
assert(utils.isSatoshi(satoshi), 'Non-satoshi value for conversion.');
|
||||
|
||||
if (satoshi.isNeg()) {
|
||||
satoshi = satoshi.neg();
|
||||
if (satoshi < 0) {
|
||||
satoshi = -satoshi;
|
||||
neg = true;
|
||||
}
|
||||
|
||||
hi = satoshi.div(utils.COIN).toString(10);
|
||||
|
||||
lo = satoshi.mod(utils.COIN);
|
||||
|
||||
lo = lo.toString(10);
|
||||
hi = Math.floor(satoshi / utils.COIN).toString(10);
|
||||
lo = (satoshi % utils.COIN).toString(10);
|
||||
|
||||
while (lo.length < 8)
|
||||
lo = '0' + lo;
|
||||
@ -711,12 +708,14 @@ utils.satoshi = function satoshi(btc) {
|
||||
while (lo.length < 8)
|
||||
lo += '0';
|
||||
|
||||
assert(lo.length === 8);
|
||||
|
||||
satoshi = (hi + lo).replace(/^0+/, '');
|
||||
|
||||
satoshi = new bn(satoshi, 10);
|
||||
satoshi = parseInt(satoshi, 10);
|
||||
|
||||
if (neg)
|
||||
satoshi.ineg();
|
||||
satoshi = -satoshi;
|
||||
|
||||
return satoshi;
|
||||
};
|
||||
@ -738,7 +737,7 @@ utils.isNumber = function isNumber(val) {
|
||||
*/
|
||||
|
||||
utils.isSatoshi = function isSatoshi(val) {
|
||||
return bn.isBN(val);
|
||||
return utils.isNumber(val) && val % 1 === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1733,20 +1732,54 @@ utils.readU64NBE = function readU64NBE(data, off, force53) {
|
||||
*/
|
||||
|
||||
utils.read64N = function read64N(data, off, force53) {
|
||||
var hi, lo, result, one, b, v;
|
||||
|
||||
off = off >>> 0;
|
||||
var hi = utils.readU32(data, off + 4);
|
||||
var lo = utils.readU32(data, off);
|
||||
if (hi & 0x80000000) {
|
||||
hi = ~hi + 1;
|
||||
lo = ~lo + 1;
|
||||
if (force53)
|
||||
hi &= utils.MAX_SAFE_HI;
|
||||
assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1');
|
||||
return -(hi * 0x100000000 + lo);
|
||||
|
||||
if (data[off + 7] & 0x80) {
|
||||
result = 0;
|
||||
one = 1;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
b = (data[i + off] ^ 0xff) + one;
|
||||
v = b & 0xff;
|
||||
|
||||
// We can't have any bits in the msb.
|
||||
if (i === 7 && v !== 0) {
|
||||
assert(force53, 'Number exceeds 2^53-1');
|
||||
v = 0;
|
||||
}
|
||||
|
||||
// We can only have 5 bits in the second msb.
|
||||
if (i === 6 && v > 0x1f) {
|
||||
assert(force53, 'Number exceeds 2^53-1');
|
||||
v &= 0x1f;
|
||||
}
|
||||
|
||||
// We need to shift left by `i` bytes,
|
||||
// but we can't because this will
|
||||
// exceed 32 bits. So we multiply by
|
||||
// `Math.pow(2, shiftBits)` instead.
|
||||
// Equivalent to `v <<= 8 * i`.
|
||||
v *= Math.pow(2, 8 * i);
|
||||
|
||||
// We can't OR so we add.
|
||||
result += v;
|
||||
|
||||
one = b >>> 8;
|
||||
}
|
||||
|
||||
return -result;
|
||||
}
|
||||
|
||||
hi = utils.readU32(data, off + 4);
|
||||
lo = utils.readU32(data, off);
|
||||
|
||||
if (force53)
|
||||
hi &= utils.MAX_SAFE_HI;
|
||||
|
||||
assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1');
|
||||
|
||||
return (hi * 0x100000000) + lo;
|
||||
};
|
||||
|
||||
@ -1760,20 +1793,54 @@ utils.read64N = function read64N(data, off, force53) {
|
||||
*/
|
||||
|
||||
utils.read64NBE = function read64NBE(data, off, force53) {
|
||||
var hi, lo, result, one, b, v;
|
||||
|
||||
off = off >>> 0;
|
||||
var hi = utils.readU32BE(data, off);
|
||||
var lo = utils.readU32BE(data, off + 4);
|
||||
if (hi & 0x80000000) {
|
||||
hi = ~hi + 1;
|
||||
lo = ~lo + 1;
|
||||
if (force53)
|
||||
hi &= utils.MAX_SAFE_HI;
|
||||
assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1');
|
||||
return -(hi * 0x100000000 + lo);
|
||||
|
||||
if (data[off] & 0x80) {
|
||||
result = 0;
|
||||
one = 1;
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
b = (data[i + off] ^ 0xff) + one;
|
||||
v = b & 0xff;
|
||||
|
||||
// We can't have any bits on the msb.
|
||||
if (i === 0 && v !== 0) {
|
||||
assert(force53, 'Number exceeds 2^53-1');
|
||||
v = 0;
|
||||
}
|
||||
|
||||
// We can only have 5 bits on the second msb.
|
||||
if (i === 1 && v > 0x1f) {
|
||||
assert(force53, 'Number exceeds 2^53-1');
|
||||
v &= 0x1f;
|
||||
}
|
||||
|
||||
// We need to shift left by `7 - i` bytes,
|
||||
// but we can't because this will exceed
|
||||
// 32 bits. So we multiply by
|
||||
// `Math.pow(2, shiftBits)` instead.
|
||||
// Equivalent to `v <<= 8 * (7 - i)`.
|
||||
v *= Math.pow(2, 8 * (7 - i));
|
||||
|
||||
// We can't OR so we add.
|
||||
result += v;
|
||||
|
||||
one = b >>> 8;
|
||||
}
|
||||
|
||||
return -result;
|
||||
}
|
||||
|
||||
hi = utils.readU32(data, off);
|
||||
lo = utils.readU32(data, off + 4);
|
||||
|
||||
if (force53)
|
||||
hi &= utils.MAX_SAFE_HI;
|
||||
|
||||
assert(hi <= utils.MAX_SAFE_HI, 'Number exceeds 2^53-1');
|
||||
|
||||
return (hi * 0x100000000) + lo;
|
||||
};
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ describe('Mempool', function() {
|
||||
coin: {
|
||||
version: 1,
|
||||
height: 0,
|
||||
value: new bn(70000),
|
||||
value: 70000,
|
||||
script: prev,
|
||||
coinbase: false,
|
||||
hash: constants.ONE_HASH.toString('hex'),
|
||||
|
||||
@ -302,7 +302,7 @@ describe('Script', function() {
|
||||
}],
|
||||
outputs: [{
|
||||
script: output,
|
||||
value: new bn(0)
|
||||
value: 0
|
||||
}],
|
||||
locktime: 0
|
||||
});
|
||||
@ -320,7 +320,7 @@ describe('Script', function() {
|
||||
}],
|
||||
outputs: [{
|
||||
script: new bcoin.script(),
|
||||
value: new bn(0)
|
||||
value: 0
|
||||
}],
|
||||
locktime: 0
|
||||
});
|
||||
|
||||
@ -161,7 +161,7 @@ describe('TX', function() {
|
||||
hash: utils.revHex(hash),
|
||||
index: index,
|
||||
script: script,
|
||||
value: value != null ? new bn(value) : new bn(0)
|
||||
value: value != null ? parseInt(value, 10) : 0
|
||||
});
|
||||
tx.fillCoins(coin);
|
||||
});
|
||||
|
||||
@ -22,20 +22,20 @@ describe('Utils', function() {
|
||||
});
|
||||
|
||||
it('should convert satoshi to btc', function() {
|
||||
var btc = utils.btc(new bn(5460));
|
||||
var btc = utils.btc(5460);
|
||||
assert.equal(btc, '0.0000546');
|
||||
btc = utils.btc(new bn(54678).mul(new bn(1000000)));
|
||||
btc = utils.btc(54678 * 1000000);
|
||||
assert.equal(btc, '546.78');
|
||||
btc = utils.btc(new bn(5460).mul(new bn(10000000)));
|
||||
btc = utils.btc(5460 * 10000000);
|
||||
assert.equal(btc, '546.0');
|
||||
});
|
||||
|
||||
it('should convert btc to satoshi', function() {
|
||||
var btc = utils.satoshi('0.0000546');
|
||||
assert(btc.cmp(new bn(5460)) === 0);
|
||||
assert(btc === 5460);
|
||||
btc = utils.satoshi('546.78');
|
||||
assert(btc.cmp(new bn(54678).mul(new bn(1000000))) === 0);
|
||||
assert(btc === 54678 * 1000000);
|
||||
btc = utils.satoshi('546.0');
|
||||
assert(btc.cmp(new bn(5460).mul(new bn(10000000))) === 0);
|
||||
assert(btc === 5460 * 10000000);
|
||||
});
|
||||
});
|
||||
|
||||
@ -13,7 +13,7 @@ var dummyInput = {
|
||||
coin: {
|
||||
version: 1,
|
||||
height: 0,
|
||||
value: constants.MAX_MONEY.clone(),
|
||||
value: constants.MAX_MONEY,
|
||||
script: new bcoin.script([]),
|
||||
coinbase: false,
|
||||
hash: constants.NULL_HASH,
|
||||
@ -342,7 +342,7 @@ describe('Wallet', function() {
|
||||
tx.addOutput(to, 5460);
|
||||
|
||||
var cost = tx.getOutputValue();
|
||||
var total = cost.add(new bn(constants.tx.MIN_FEE));
|
||||
var total = cost * constants.tx.MIN_FEE;
|
||||
|
||||
w1.getCoins(function(err, coins1) {
|
||||
assert.ifError(err);
|
||||
@ -350,19 +350,19 @@ describe('Wallet', function() {
|
||||
assert.ifError(err);
|
||||
|
||||
// Add dummy output (for `left`) to calculate maximum TX size
|
||||
tx.addOutput(w1, new bn(0));
|
||||
tx.addOutput(w1, 0);
|
||||
|
||||
// Add our unspent inputs to sign
|
||||
tx.addInput(coins1[0]);
|
||||
tx.addInput(coins1[1]);
|
||||
tx.addInput(coins2[0]);
|
||||
|
||||
var left = tx.getInputValue().sub(total);
|
||||
if (left.cmpn(constants.tx.DUST_THRESHOLD) < 0) {
|
||||
tx.outputs[tx.outputs.length - 2].value.iadd(left);
|
||||
left = new bn(0);
|
||||
var left = tx.getInputValue() - total;
|
||||
if (left < constants.tx.DUST_THRESHOLD) {
|
||||
tx.outputs[tx.outputs.length - 2].value += left;
|
||||
left = 0;
|
||||
}
|
||||
if (left.cmpn(0) === 0)
|
||||
if (left === 0)
|
||||
tx.outputs.pop();
|
||||
else
|
||||
tx.outputs[tx.outputs.length - 1].value = left;
|
||||
@ -527,7 +527,7 @@ describe('Wallet', function() {
|
||||
send.inputs[0].script.code[2] = 0;
|
||||
|
||||
assert(!send.verify(null, true, flags));
|
||||
assert.equal(send.getFee().toNumber(), 10000);
|
||||
assert.equal(send.getFee(), 10000);
|
||||
|
||||
w3 = bcoin.wallet.fromJSON(w3.toJSON());
|
||||
assert.equal(w3.receiveDepth, 2);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user