diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 6edf09f9..3c3ba1c8 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -27,6 +27,7 @@ function Block(data) { this._witness = data._witness || false; this._cost = data._cost || 0; + this._witnessSize = data._witnessSize || 0; this.txs = data.txs || []; @@ -77,7 +78,23 @@ Block.prototype.renderWitness = function renderWitness() { }; Block.prototype.getSize = function getSize() { - return this.render().length; + var size = this._size; + var witnessSize = this._witnessSize; + var raw, base; + + if (!size) { + raw = bcoin.protocol.framer.witnessBlock(this); + size = raw.length; + witnessSize = raw._witnessSize; + } + + // Virtual size: + if (witnessSize > 0) { + base = size - witnessSize; + return (base * 4 + witnessSize + 3) / 4 | 0; + } + + return size; }; Block.prototype.getCost = function getCost() { diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index b07fdb1a..6bdfa4e5 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -458,7 +458,7 @@ Chain.prototype._verify = function _verify(block, prev) { var locktimeMedian, segwit; if (!block.verify()) - return flags; + return false; // Skip the genesis block if (block.isGenesis()) diff --git a/lib/bcoin/mtx.js b/lib/bcoin/mtx.js index 63321311..603b73e6 100644 --- a/lib/bcoin/mtx.js +++ b/lib/bcoin/mtx.js @@ -32,6 +32,8 @@ function MTX(options) { this.ts = 0; this.block = null; this.index = -1; + this.ps = this.ts === 0 ? utils.now() : 0; + this.changeIndex = options.changeIndex != null ? options.changeIndex : -1; this._hash = null; this._whash = null; @@ -39,6 +41,7 @@ function MTX(options) { this._size = 0; this._offset = 0; this._cost = 0; + this._witnessSize = 0; this.height = -1; @@ -55,9 +58,6 @@ function MTX(options) { this.addOutput(output); }, this); } - - this.changeIndex = options.changeIndex != null ? options.changeIndex : -1; - this.ps = this.ts === 0 ? utils.now() : 0; } utils.inherits(MTX, bcoin.tx); @@ -656,8 +656,10 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) { var i, j, input, total, size, prev, m, n; // Create copy with 0-script inputs - for (i = 0; i < copy.inputs.length; i++) + for (i = 0; i < copy.inputs.length; i++) { copy.inputs[i].script = []; + copy.inputs[i].witness = []; + } total = copy.render().length; @@ -682,6 +684,15 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) { size += 3 + bcoin.script.getSize(prev); } + if (this.inputs[i].witness.length) { + if (bcoin.script.isWitnessScripthash(prev)) { + prev = bcoin.script.getRedeem(this.inputs[i].witness); + size += 3 + bcoin.script.getSize(prev); + } else if (bcoin.script.isWitnessPubkeyhash(prev)) { + prev = bcoin.script.createPubkeyhash(prev[1]); + } + } + if (bcoin.script.isPubkey(prev)) { // P2PK // OP_PUSHDATA0 [signature] @@ -1151,6 +1162,7 @@ MTX.fromRaw = function fromRaw(data, enc) { MTX.fromTX = function fromTX(tx) { var mtx = new bcoin.tx({ ts: tx.ts, + ps: tx.ps, block: tx.block, height: tx.height, version: tx.version, @@ -1164,13 +1176,13 @@ MTX.fromTX = function fromTX(tx) { }), locktime: tx.locktime }); - mtx.ps = tx.ps; return mtx; }; MTX.prototype.toTX = function toTX() { var tx = new bcoin.tx({ ts: this.ts, + ps: this.ps, block: this.block, height: this.height, version: this.version, diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 0535851d..a292ec9e 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -179,6 +179,10 @@ Pool.prototype._init = function _init() { self._handleTX(tx, peer); }); } + if (peer === self.peers.load) { + self._startInterval(); + self._startTimer(); + } }); this.chain.on('fork', function(block, data, peer) { diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 12cc936a..3e3ac611 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -474,6 +474,7 @@ Framer.tx = function _tx(tx) { off += utils.writeU32(p, tx.locktime, off); p._cost = p.length * 4; + p._witnessSize = 0; return p; }; @@ -539,6 +540,7 @@ Framer.witnessTX = function _witnessTX(tx) { p._cost += 4 * 4; p._cost += witnessSize; + p._witnessSize = witnessSize; return p; }; @@ -582,6 +584,8 @@ Framer.witnessBlock = function _witnessBlock(block) { Framer._block = function _block(block, witness) { var off = 0; var txSize = 0; + var cost = 0; + var witnessSize = 0; var txs = []; var hasWitness; var i, tx, p; @@ -597,6 +601,8 @@ Framer._block = function _block(block, witness) { : Framer.tx(block.txs[i]); txs.push(tx); txSize += tx.length; + cost += tx._cost; + witnessSize += tx._witnessSize; } p = new Buffer(80 + utils.sizeIntv(block.txs.length) + txSize); @@ -624,10 +630,15 @@ Framer._block = function _block(block, witness) { // txn_count off += utils.writeIntv(p, block.txs.length, off); + cost += off * 4; + // txs for (i = 0; i < txs.length; i++) off += utils.copy(txs[i], p, off); + p._cost = cost; + p._witnessSize = witnessSize; + return p; }; diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 6a8c67ce..e4042ec5 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -332,6 +332,7 @@ Parser.parseHeaders = function parseHeaders(p) { Parser.parseBlock = function parseBlock(p) { var txs = []; var cost = 0; + var witnessSize = 0; var i, result, off, totalTX, tx; var witness; @@ -353,6 +354,7 @@ Parser.parseBlock = function parseBlock(p) { tx._offset = off; off += tx._size; cost += tx._cost; + witnessSize += tx._witnessSize; txs.push(tx); } @@ -368,7 +370,8 @@ Parser.parseBlock = function parseBlock(p) { _witness: witness, _raw: p, _size: p.length, - _cost: cost + _cost: cost, + _witnessSize: witnessSize }; }; @@ -593,6 +596,7 @@ Parser.parseTX = function parseTX(p) { locktime: locktime, _witness: false, _cost: off * 4, + _witnessSize: 0, _raw: p.length !== off ? p.slice(0, off) : p, _size: off }; @@ -612,6 +616,7 @@ Parser.parseWitnessTX = function parseWitnessTX(p) { var outCount, txOut; var marker, flag; var version, locktime, i; + var witnessSize = 0; if (p.length < 12) throw new Error('Invalid witness tx size'); @@ -690,6 +695,7 @@ Parser.parseWitnessTX = function parseWitnessTX(p) { txIn[i]._witnessOffset = off; off += tx._size; cost += tx._size; + witnessSize += tx._size; if (off + 4 > p.length) throw new Error('Invalid witness offset'); @@ -709,7 +715,8 @@ Parser.parseWitnessTX = function parseWitnessTX(p) { _witness: true, _raw: off !== p.length ? p.slice(0, off) : p, _size: off, - _cost: cost + _cost: cost, + _witnessSize: witnessSize }; }; diff --git a/lib/bcoin/tx-pool.js b/lib/bcoin/tx-pool.js index 46248a46..e9f4dd05 100644 --- a/lib/bcoin/tx-pool.js +++ b/lib/bcoin/tx-pool.js @@ -67,8 +67,8 @@ TXPool.prototype.add = function add(tx, noWrite) { if (!this._wallet.ownInput(tx) && !this._wallet.ownOutput(tx)) return false; - if (tx.type === 'tx') - tx = bcoin.mtx.fromTX(tx); + if (tx.type === 'mtx') + tx = tx.toTX(); // Ignore stale pending transactions if (tx.ts === 0 && tx.ps + 2 * 24 * 3600 < utils.now()) { diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index fd96f54f..d5e1d405 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -30,6 +30,7 @@ function TX(data, block, index) { this.ts = data.ts || 0; this.block = data.block || null; this.index = data.index || -1; + this.ps = this.ts === 0 ? utils.now() : 0; this._hash = null; this._whash = null; @@ -38,6 +39,7 @@ function TX(data, block, index) { this._offset = data._offset || 0; this._cost = data._cost || 0; this._witness = data._witness || false; + this._witnessSize = data._witnessSize || 0; this.height = data.height != null ? data.height : -1;