diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 623c811a..33c92d3a 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -53,7 +53,8 @@ function Chain(options) { this.fromJSON(require('./protocol/preload-full')); this.storage = null; //this.resetHeight(133000); - this.resetHeight(145000); + //this.resetHeight(145000); + this.resetHeight(350000); if (0) this.fromJSON({ @@ -444,7 +445,7 @@ Chain.prototype.byHeight = function byHeight(height) { }; Chain.prototype.byHash = function byHash(hash) { - if (Array.isArray(hash)) + if (utils.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) hash = hash.hash('hex'); @@ -479,7 +480,7 @@ Chain.prototype.getBlock = function getBlock(hash) { }; Chain.prototype.getOrphan = function getOrphan(hash) { - if (Array.isArray(hash)) + if (utils.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) hash = hash.hash('hex'); @@ -532,7 +533,7 @@ Chain.prototype.locatorHashes = function locatorHashes(start) { var i; if (start) { - if (Array.isArray(start)) + if (utils.isArray(start)) start = utils.toHex(start); else if (start.hash) start = start.hash('hex'); @@ -576,7 +577,7 @@ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) { var self = this; var root = hash; - if (Array.isArray(hash)) + if (utils.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) hash = hash.hash('hex'); diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index 1e958146..2e9b3746 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -204,7 +204,7 @@ Input.getData = function getData(input) { type: 'coinbase', height: data.height != null ? data.height : -1, flags: data.flags, - text: data.text.join('').replace(/[\r\n\t\v]/g, ''), + text: data.text, none: true }); } diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 4e3bad5f..221de5e2 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -427,12 +427,6 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) { for (i = 0; i < hashes.length; i++) { hash = hashes[i]; - // Request block if we don't have it - if (!this.chain.has(hash)) { - this._request(this.block.type, hash); - continue; - } - // Resolve orphan chain if (this.chain.hasOrphan(hash)) { peer.loadBlocks( @@ -441,6 +435,15 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) { ); continue; } + + // Request block if we don't have it or if + // this is the last hash: this is done as + // a failsafe because we _need_ to request + // the hashContinue no matter what. + if (!this.chain.has(hash) || i === hashes.length - 1) { + this._request(this.block.type, hash); + continue; + } } // Push our getdata packet diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 25a61d55..24f15ad2 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -47,14 +47,16 @@ Parser.prototype.feed = function feed(data) { while (this.pendingTotal >= this.waiting) { // Concat chunks - chunk = new Array(this.waiting); + // chunk = new Array(this.waiting); + chunk = new Buffer(this.waiting); i = 0; off = 0; len = 0; for (; off < chunk.length; i++) { - len = utils.copy(this.pending[0], chunk, off); + // len = utils.copy(this.pending[0], chunk, off); + len = this.pending[0].copy(chunk, off, 0, this.pending[0].length); if (len === this.pending[0].length) this.pending.shift(); else @@ -336,7 +338,8 @@ Parser.prototype.parseTXIn = function parseTXIn(p) { hash: p.slice(0, 32), index: readU32(p, 32) }, - script: bcoin.script.decode(p.slice(off, off + scriptLen)), + // script: bcoin.script.decode(p.slice(off, off + scriptLen)), + script: bcoin.script.decode(utils.toArray(p.slice(off, off + scriptLen))), seq: readU32(p, off + scriptLen) }; }; @@ -356,8 +359,10 @@ Parser.prototype.parseTXOut = function parseTXOut(p) { return { size: off + scriptLen, - value: new bn(p.slice(0, 8).reverse()), - script: bcoin.script.decode(p.slice(off, off + scriptLen)) + // value: new bn(p.slice(0, 8).reverse()), + // script: bcoin.script.decode(p.slice(off, off + scriptLen)) + value: new bn(utils.toArray(p.slice(0, 8)).reverse()), + script: bcoin.script.decode(utils.toArray(p.slice(off, off + scriptLen))) }; }; diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 0bcfa6e3..8da86c46 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -1234,7 +1234,7 @@ script.coinbaseBits = function coinbaseBits(s, block) { value = new bn(s[0].slice().reverse()).toNumber(); // Test for bits and ts - if (block) { + if (block && block.version < 2) { if (value === block.bits) return { type: 'bits', value: value }; @@ -1265,47 +1265,56 @@ script.coinbaseHeight = function coinbaseHeight(s, block) { }; script.coinbase = function coinbase(s, block) { - var coinbase, data, nonce, flags; + var coinbase, data, extraNonce, flags; s = s.filter(function(chunk) { return Array.isArray(chunk) && chunk.length !== 0; }); coinbase = { - script: s, - raw: s._raw || script.encode(s) + script: s }; data = script.coinbaseBits(s, block); if (Array.isArray(s[1])) - nonce = new bn(s[1]); + extraNonce = new bn(s[1]); flags = s.slice(2); coinbase[data.type] = data.value; - coinbase.nonce = nonce; + coinbase.extraNonce = extraNonce; coinbase.flags = flags; - coinbase.text = flags.map(utils.array2utf8); + coinbase.text = + flags.map(utils.array2utf8).join('') + .replace(/[\u0000-\u0019\u007f-\u00ff]/g, ''); return coinbase; }; -script.isCoinbase = function isCoinbase(s, block) { +script.isCoinbase = function isCoinbase(s, block, strict) { var coinbase = script.coinbase(s, block); + var size = script.size(s); - if (coinbase.raw.length > 100 || s.length < 2) + if (size < 2 || size > 100) return false; - if (coinbase.value != null) - return false; - - if (coinbase.nonce == null) - return false; - - if (block) { - if (coinbase.bits != null && coinbase.flags.length) + if (strict) { + if (s.length < 2) return false; + + if (coinbase.value != null) + return false; + + if (coinbase.extraNonce == null) + return false; + + if (block) { + // The early bitcoind miner (which used the bits + // as the first stack push) had no flags after it. + if (coinbase.bits != null && coinbase.flags.length) + return false; + } } return coinbase; @@ -1502,10 +1511,10 @@ script.sigopsScripthash = function sigopsScripthash(s) { if (!script.isScripthashInput(s)) return 0; - if (!script.pushOnly(input)) + if (!script.pushOnly(s)) return 0; - s = script.decode(input[input.length - 1]); + s = script.decode(s[s.length - 1]); return script.sigops(s, true); }; diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 53ed14f7..a0a9537a 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -887,7 +887,7 @@ TX.prototype.sigops = function sigops(scripthash, accurate) { n += bcoin.script.sigops(input.script, accurate); if (scripthash && !this.isCoinbase()) n += bcoin.script.sigopsScripthash(input.script); - }, true); + }, this); this.outputs.forEach(function(output) { n += bcoin.script.sigops(output.script, accurate); }, this); diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index a410e732..6adc9d37 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -9,12 +9,16 @@ var utils = exports; var bn = require('bn.js'); var hash = require('hash.js'); var util = require('util'); +var crypto = require('crypto'); /** * Utils */ function toArray(msg, enc) { + if (Buffer.isBuffer(msg)) + return Array.prototype.slice.call(msg); + if (Array.isArray(msg)) return msg.slice(); @@ -146,15 +150,20 @@ utils.isBase58 = function isBase58(msg) { }; utils.ripemd160 = function ripemd160(data, enc) { + if (Array.isArray(data)) + data = new Buffer(data); + return crypto.createHash('ripemd160').update(data, enc).digest(); return hash.ripemd160().update(data, enc).digest(); }; utils.sha1 = function sha1(data, enc) { + return crypto.createHash('sha1').update(data, enc).digest(); return hash.sha1().update(data, enc).digest(); }; utils.ripesha = function ripesha(data, enc) { - return hash.ripemd160().update(utils.sha256(data, enc)).digest(); + // return hash.ripemd160().update(utils.sha256(data, enc)).digest(); + return utils.ripemd160(utils.sha256(data, enc)); }; utils.checksum = function checksum(data, enc) { @@ -162,6 +171,9 @@ utils.checksum = function checksum(data, enc) { }; utils.sha256 = function sha256(data, enc) { + if (Array.isArray(data)) + data = new Buffer(data); + return crypto.createHash('sha256').update(data, enc).digest(); return hash.sha256().update(data, enc).digest(); }; @@ -377,6 +389,9 @@ function toHex(msg) { var res = ''; var i = 0; + if (Buffer.isBuffer(msg)) + return msg.toString('hex'); + if (typeof msg === 'string') return msg; @@ -642,6 +657,14 @@ utils.isArrayLike = function isArrayLike(msg) { && typeof msg.length === 'number'; }; +utils.isArray = function isArray(msg) { + if (Array.isArray(msg)) + return true; + if (Buffer.isBuffer(msg)) + return true; + return false; +}; + utils.toKeyArray = function toKeyArray(msg) { if (Array.isArray(msg)) return msg;