getutxos. arg parsing.
This commit is contained in:
parent
4b20a87b4f
commit
d423e33e03
@ -77,9 +77,8 @@ function Peer(pool, options) {
|
|||||||
|
|
||||||
this._request = {
|
this._request = {
|
||||||
timeout: this.options.requestTimeout || 10000,
|
timeout: this.options.requestTimeout || 10000,
|
||||||
cont: {},
|
|
||||||
skip: {},
|
skip: {},
|
||||||
queue: []
|
queue: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
this._ping = {
|
this._ping = {
|
||||||
@ -316,13 +315,17 @@ Peer.prototype.updateWatch = function updateWatch() {
|
|||||||
if (!this.pool.options.spv)
|
if (!this.pool.options.spv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.ack)
|
if (this.ack) {
|
||||||
this._write(this.framer.filterLoad(this.bloom, 'none'));
|
this._write(this.framer.filterLoad({
|
||||||
|
filter: this.bloom.toBuffer(),
|
||||||
|
n: this.bloom.n,
|
||||||
|
tweak: this.bloom.tweak,
|
||||||
|
update: 'none'
|
||||||
|
}));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype.destroy = function destroy() {
|
Peer.prototype.destroy = function destroy() {
|
||||||
var i;
|
|
||||||
|
|
||||||
if (this.destroyed)
|
if (this.destroyed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -340,8 +343,13 @@ Peer.prototype.destroy = function destroy() {
|
|||||||
clearInterval(this._ping.timer);
|
clearInterval(this._ping.timer);
|
||||||
this._ping.timer = null;
|
this._ping.timer = null;
|
||||||
|
|
||||||
for (i = 0; i < this._request.queue.length; i++)
|
Object.keys(this._request).forEach(function(cmd) {
|
||||||
clearTimeout(this._request.queue[i].timer);
|
var queue = this._request[cmd];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < queue.length; i++)
|
||||||
|
clearTimeout(queue[i].timer);
|
||||||
|
}, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype._write = function write(chunk) {
|
Peer.prototype._write = function write(chunk) {
|
||||||
@ -375,9 +383,16 @@ Peer.prototype._req = function _req(cmd, cb) {
|
|||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
cb: cb,
|
cb: cb,
|
||||||
ontimeout: function() {
|
ontimeout: function() {
|
||||||
var i = self._request.queue.indexOf(entry);
|
var queue = self._request.queue[cmd];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
if (!queue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
i = queue.indexOf(entry);
|
||||||
|
|
||||||
if (i !== -1) {
|
if (i !== -1) {
|
||||||
self._request.queue.splice(i, 1);
|
queue.splice(i, 1);
|
||||||
cb(new Error('Timed out: ' + cmd), null);
|
cb(new Error('Timed out: ' + cmd), null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -386,35 +401,35 @@ Peer.prototype._req = function _req(cmd, cb) {
|
|||||||
|
|
||||||
entry.timer = setTimeout(entry.ontimeout, this._request.timeout);
|
entry.timer = setTimeout(entry.ontimeout, this._request.timeout);
|
||||||
|
|
||||||
this._request.queue.push(entry);
|
if (!this._request.queue[cmd])
|
||||||
|
this._request.queue[cmd] = [];
|
||||||
|
|
||||||
|
this._request.queue[cmd].push(entry);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype._res = function _res(cmd, payload) {
|
Peer.prototype._res = function _res(cmd, payload) {
|
||||||
var i, entry, res;
|
var queue = this._request.queue[cmd];
|
||||||
|
var entry, res;
|
||||||
|
|
||||||
for (i = 0; i < this._request.queue.length; i++) {
|
if (!queue)
|
||||||
entry = this._request.queue[i];
|
return false;
|
||||||
|
|
||||||
if (!entry || (entry.cmd && entry.cmd !== cmd))
|
entry = queue[0];
|
||||||
return false;
|
|
||||||
|
|
||||||
res = entry.cb(null, payload, cmd);
|
if (!entry)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (res === this._request.cont) {
|
res = entry.cb(null, payload, cmd);
|
||||||
assert(!entry.cmd);
|
|
||||||
|
|
||||||
// Restart timer
|
if (res !== this._request.skip) {
|
||||||
if (!this.destroyed)
|
queue.shift();
|
||||||
entry.timer = setTimeout(entry.ontimeout, this._request.timeout);
|
if (queue.length === 0)
|
||||||
return true;
|
delete this._request.queue[cmd];
|
||||||
} else if (res !== this._request.skip) {
|
clearTimeout(entry.timer);
|
||||||
this._request.queue.shift();
|
entry.timer = null;
|
||||||
clearTimeout(entry.timer);
|
return true;
|
||||||
entry.timer = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -543,13 +558,71 @@ Peer.prototype._handleUTXOs = function _handleUTXOs(payload) {
|
|||||||
return new bcoin.coin(coin);
|
return new bcoin.coin(coin);
|
||||||
});
|
});
|
||||||
utils.debug('Received %d utxos from %s.', payload.coins.length, this.host);
|
utils.debug('Received %d utxos from %s.', payload.coins.length, this.host);
|
||||||
this.emit('utxos', payload);
|
this._emit('utxos', payload);
|
||||||
|
};
|
||||||
|
|
||||||
|
Peer.prototype.getUTXOs = function getUTXOs(utxos, callback) {
|
||||||
|
var self = this;
|
||||||
|
var reqs = [];
|
||||||
|
var coins = [];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < utxos.length; i += 15)
|
||||||
|
reqs.push(utxos.slice(i, i + 15));
|
||||||
|
|
||||||
|
utils.forEachSerial(reqs, function(utxos, next) {
|
||||||
|
self._getUTXOs(utxos, function(err, coin) {
|
||||||
|
if (err)
|
||||||
|
return next(err);
|
||||||
|
|
||||||
|
coins = coins.concat(coin);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
return callback(null, coins);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Peer.prototype._getUTXOs = function getUTXOs(utxos, callback) {
|
||||||
|
var index = 0;
|
||||||
|
var i, prevout, coin;
|
||||||
|
|
||||||
|
this._req('utxos', function(err, payload) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
for (i = 0; i < payload.hits.length; i++) {
|
||||||
|
if (payload.hits[i]) {
|
||||||
|
prevout = utxos[i];
|
||||||
|
coin = payload.coins[index++];
|
||||||
|
|
||||||
|
if (!prevout || !coin)
|
||||||
|
return callback(new Error('Malformed utxos message.'));
|
||||||
|
|
||||||
|
coin.hash = prevout.hash;
|
||||||
|
coin.index = prevout.index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null, payload.coins);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._write(this.framer.getUTXOs({
|
||||||
|
mempool: true,
|
||||||
|
prevout: utxos.map(function(item) {
|
||||||
|
return { hash: item[0], index: item[1] };
|
||||||
|
})
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var coins = [];
|
var coins = [];
|
||||||
var notfound = [];
|
var hits = [];
|
||||||
|
|
||||||
if (this.pool.options.selfish)
|
if (this.pool.options.selfish)
|
||||||
return;
|
return;
|
||||||
@ -577,6 +650,9 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
|||||||
self.mempool.isSpent(hash, index, callback);
|
self.mempool.isSpent(hash, index, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payload.prevout.length > 15)
|
||||||
|
return;
|
||||||
|
|
||||||
utils.forEachSerial(payload.prevout, function(prevout, next, i) {
|
utils.forEachSerial(payload.prevout, function(prevout, next, i) {
|
||||||
var hash = prevout.hash;
|
var hash = prevout.hash;
|
||||||
var index = prevout.index;
|
var index = prevout.index;
|
||||||
@ -586,6 +662,7 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
|||||||
return next(err);
|
return next(err);
|
||||||
|
|
||||||
if (coin) {
|
if (coin) {
|
||||||
|
hits.push(1);
|
||||||
coins.push(coin);
|
coins.push(coin);
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -595,7 +672,7 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
|||||||
return next(err);
|
return next(err);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
notfound.push(i);
|
hits.push(0);
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,10 +681,11 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
|||||||
return next(err);
|
return next(err);
|
||||||
|
|
||||||
if (!coin) {
|
if (!coin) {
|
||||||
notfound.push(i);
|
hits.push(0);
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hits.push(1);
|
||||||
coins.push(coin);
|
coins.push(coin);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
@ -621,7 +699,7 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
|||||||
self._write(self.framer.UTXOs({
|
self._write(self.framer.UTXOs({
|
||||||
height: self.chain.height,
|
height: self.chain.height,
|
||||||
tip: self.chain.tip.hash,
|
tip: self.chain.tip.hash,
|
||||||
notfound: notfound,
|
hits: hits,
|
||||||
coins: coins
|
coins: coins
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
@ -778,7 +856,7 @@ Peer.prototype._handleVersion = function handleVersion(payload) {
|
|||||||
|
|
||||||
if (this.options.witness) {
|
if (this.options.witness) {
|
||||||
if (!payload.witness) {
|
if (!payload.witness) {
|
||||||
this._req('havewitness', function(err, payload) {
|
this._req('havewitness', function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
self._error('Peer does not support segregated witness.');
|
self._error('Peer does not support segregated witness.');
|
||||||
self.setMisbehavior(100);
|
self.setMisbehavior(100);
|
||||||
@ -1151,30 +1229,30 @@ Peer.prototype._handleAlert = function handleAlert(details) {
|
|||||||
this.emit('alert', details);
|
this.emit('alert', details);
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype.getHeaders = function getHeaders(hashes, stop) {
|
Peer.prototype.getHeaders = function getHeaders(locator, stop) {
|
||||||
utils.debug(
|
utils.debug(
|
||||||
'Requesting headers packet from %s with getheaders',
|
'Requesting headers packet from %s with getheaders',
|
||||||
this.host);
|
this.host);
|
||||||
|
|
||||||
utils.debug('Height: %s, Hash: %s, Stop: %s',
|
utils.debug('Height: %s, Hash: %s, Stop: %s',
|
||||||
this.chain._getCachedHeight(hashes[0]),
|
locator && locator.length ? this.chain._getCachedHeight(locator[0]) : null,
|
||||||
hashes ? utils.revHex(hashes[0]) : 0,
|
locator && locator.length ? utils.revHex(locator[0]) : 0,
|
||||||
stop ? utils.revHex(stop) : 0);
|
stop ? utils.revHex(stop) : 0);
|
||||||
|
|
||||||
this._write(this.framer.getHeaders(hashes, stop));
|
this._write(this.framer.getHeaders({ locator: locator, stop: stop }));
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype.getBlocks = function getBlocks(hashes, stop) {
|
Peer.prototype.getBlocks = function getBlocks(locator, stop) {
|
||||||
utils.debug(
|
utils.debug(
|
||||||
'Requesting inv packet from %s with getblocks',
|
'Requesting inv packet from %s with getblocks',
|
||||||
this.host);
|
this.host);
|
||||||
|
|
||||||
utils.debug('Height: %s, Hash: %s, Stop: %s',
|
utils.debug('Height: %s, Hash: %s, Stop: %s',
|
||||||
this.chain._getCachedHeight(hashes[0]),
|
locator && locator.length ? this.chain._getCachedHeight(locator[0]) : null,
|
||||||
hashes ? utils.revHex(hashes[0]) : 0,
|
locator && locator.length ? utils.revHex(locator[0]) : 0,
|
||||||
stop ? utils.revHex(stop) : 0);
|
stop ? utils.revHex(stop) : 0);
|
||||||
|
|
||||||
this._write(this.framer.getBlocks(hashes, stop));
|
this._write(this.framer.getBlocks({ locator: locator, stop: stop }));
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype.getMempool = function getMempool() {
|
Peer.prototype.getMempool = function getMempool() {
|
||||||
|
|||||||
@ -1730,6 +1730,39 @@ Pool.prototype.getPeer = function getPeer(addr) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Pool.prototype.getUTXOs = function getUTXOs(utxos, callback) {
|
||||||
|
var peer = this.peers.load || this.peers.regular[0];
|
||||||
|
|
||||||
|
if (!peer)
|
||||||
|
return utils.asyncify(callback)(new Error('No peer available.'));
|
||||||
|
|
||||||
|
peer.getUTXOs(utxos, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Pool.prototype.fillTX = function fillTX(tx, callback) {
|
||||||
|
var utxos = [];
|
||||||
|
var reqs = [];
|
||||||
|
var i, input;
|
||||||
|
|
||||||
|
for (i = 0; i < tx.inputs.length; i++) {
|
||||||
|
input = tx.inputs[i];
|
||||||
|
if (!input.coin)
|
||||||
|
utxos.push([input.prevout.hash, input.prevout.index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utxos.length === 0)
|
||||||
|
return utils.asyncify(callback)(null, tx);
|
||||||
|
|
||||||
|
this.getUTXOs(utxos, function(err, coins) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
tx.fillCoins(coins);
|
||||||
|
|
||||||
|
return callback(null, tx);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Pool.prototype.getSeed = function getSeed(priority) {
|
Pool.prototype.getSeed = function getSeed(priority) {
|
||||||
var addr;
|
var addr;
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,6 @@ var utils = require('../utils');
|
|||||||
var assert = utils.assert;
|
var assert = utils.assert;
|
||||||
var BufferWriter = require('../writer');
|
var BufferWriter = require('../writer');
|
||||||
var DUMMY = new Buffer([]);
|
var DUMMY = new Buffer([]);
|
||||||
var bn = require('bn.js');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Framer
|
* Framer
|
||||||
@ -141,16 +140,16 @@ Framer.prototype.pong = function pong(data) {
|
|||||||
return this.packet('pong', Framer.pong(data));
|
return this.packet('pong', Framer.pong(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.prototype.filterLoad = function filterLoad(bloom, update) {
|
Framer.prototype.filterLoad = function filterLoad(data) {
|
||||||
return this.packet('filterload', Framer.filterLoad(bloom, update));
|
return this.packet('filterload', Framer.filterLoad(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.prototype.getHeaders = function getHeaders(hashes, stop) {
|
Framer.prototype.getHeaders = function getHeaders(data) {
|
||||||
return this.packet('getheaders', Framer.getHeaders(hashes, stop));
|
return this.packet('getheaders', Framer.getHeaders(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.prototype.getBlocks = function getBlocks(hashes, stop) {
|
Framer.prototype.getBlocks = function getBlocks(data) {
|
||||||
return this.packet('getblocks', Framer.getBlocks(hashes, stop));
|
return this.packet('getblocks', Framer.getBlocks(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.prototype.utxo = function _coin(coin) {
|
Framer.prototype.utxo = function _coin(coin) {
|
||||||
@ -192,38 +191,30 @@ Framer.prototype.addr = function addr(peers) {
|
|||||||
Framer.address = function address(data, full, writer) {
|
Framer.address = function address(data, full, writer) {
|
||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
|
|
||||||
if (!data)
|
if (full) {
|
||||||
data = {};
|
if (!data.ts)
|
||||||
|
p.writeU32(utils.now() - (process.uptime() | 0));
|
||||||
|
else
|
||||||
|
p.writeU32(data.ts);
|
||||||
|
}
|
||||||
|
|
||||||
if (!data.ts)
|
p.writeU64(data.services || 0);
|
||||||
data.ts = utils.now() - (process.uptime() | 0);
|
|
||||||
|
|
||||||
if (!data.services)
|
|
||||||
data.services = 0;
|
|
||||||
|
|
||||||
if (!data.port)
|
|
||||||
data.port = network.port;
|
|
||||||
|
|
||||||
if (full)
|
|
||||||
p.writeU32(data.ts);
|
|
||||||
|
|
||||||
p.writeU64(data.services);
|
|
||||||
|
|
||||||
if (data.ipv6) {
|
if (data.ipv6) {
|
||||||
data.ipv6 = utils.ip2array(data.ipv6, 6);
|
p.writeBytes(utils.ip2array(data.ipv6, 6));
|
||||||
p.writeBytes(data.ipv6);
|
|
||||||
} else {
|
} else {
|
||||||
if (!data.ipv4)
|
// We don't have an ipv6 address: convert
|
||||||
data.ipv4 = new Buffer([0, 0, 0, 0]);
|
// ipv4 to ipv4-mapped ipv6 address.
|
||||||
data.ipv4 = utils.ip2array(data.ipv4, 4);
|
|
||||||
// We don't have an ipv6, convert ipv4 to ipv4-mapped ipv6 address
|
|
||||||
p.writeU32BE(0x00000000);
|
p.writeU32BE(0x00000000);
|
||||||
p.writeU32BE(0x00000000);
|
p.writeU32BE(0x00000000);
|
||||||
p.writeU32BE(0x0000ffff);
|
p.writeU32BE(0x0000ffff);
|
||||||
p.writeBytes(data.ipv4);
|
if (data.ipv4)
|
||||||
|
p.writeBytes(utils.ip2array(data.ipv4, 4));
|
||||||
|
else
|
||||||
|
p.writeU32BE(0x00000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.writeU16BE(data.port);
|
p.writeU16BE(data.port || network.port);
|
||||||
|
|
||||||
if (!writer)
|
if (!writer)
|
||||||
p = p.render();
|
p = p.render();
|
||||||
@ -233,29 +224,23 @@ Framer.address = function address(data, full, writer) {
|
|||||||
|
|
||||||
Framer.version = function version(options, writer) {
|
Framer.version = function version(options, writer) {
|
||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
|
var agent = options.agent || constants.userAgent;
|
||||||
|
var remote = options.remote || {};
|
||||||
|
var local = options.local || {};
|
||||||
|
|
||||||
if (!options.agent)
|
if (typeof agent === 'string')
|
||||||
options.agent = new Buffer(constants.userAgent, 'ascii');
|
agent = new Buffer(agent, 'ascii');
|
||||||
|
|
||||||
if (!options)
|
if (local.services == null)
|
||||||
options = {};
|
local.services = constants.localServices;
|
||||||
|
|
||||||
if (!options.remote)
|
|
||||||
options.remote = {};
|
|
||||||
|
|
||||||
if (!options.local)
|
|
||||||
options.local = {};
|
|
||||||
|
|
||||||
if (options.local.services == null)
|
|
||||||
options.local.services = constants.localServices;
|
|
||||||
|
|
||||||
p.write32(constants.version);
|
p.write32(constants.version);
|
||||||
p.writeU64(constants.localServices);
|
p.writeU64(constants.localServices);
|
||||||
p.write64(utils.now());
|
p.write64(utils.now());
|
||||||
Framer.address(options.remote, false, p);
|
Framer.address(remote, false, p);
|
||||||
Framer.address(options.local, false, p);
|
Framer.address(local, false, p);
|
||||||
p.writeU64(utils.nonce());
|
p.writeU64(utils.nonce());
|
||||||
p.writeVarString(options.agent);
|
p.writeVarString(agent);
|
||||||
p.write32(options.height || 0);
|
p.write32(options.height || 0);
|
||||||
p.writeU8(options.relay ? 1 : 0);
|
p.writeU8(options.relay ? 1 : 0);
|
||||||
|
|
||||||
@ -317,30 +302,18 @@ Framer.pong = function pong(data) {
|
|||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.filterLoad = function filterLoad(bloom, update, writer) {
|
Framer.filterLoad = function filterLoad(data, writer) {
|
||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
var filter, n, tweak;
|
var update = data.update;
|
||||||
|
|
||||||
if (bloom instanceof bcoin.bloom) {
|
|
||||||
filter = bloom.toBuffer();
|
|
||||||
n = bloom.n;
|
|
||||||
tweak = bloom.tweak;
|
|
||||||
} else {
|
|
||||||
writer = update;
|
|
||||||
update = bloom.update;
|
|
||||||
filter = bloom.filter;
|
|
||||||
n = bloom.n;
|
|
||||||
tweak = bloom.tweak;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof update === 'string')
|
if (typeof update === 'string')
|
||||||
update = constants.filterFlags[update];
|
update = constants.filterFlags[update];
|
||||||
|
|
||||||
assert(update != null, 'Bad filter flag.');
|
assert(update != null, 'Bad filter flag.');
|
||||||
|
|
||||||
p.writeVarBytes(filter);
|
p.writeVarBytes(data.filter);
|
||||||
p.writeU32(n);
|
p.writeU32(data.n);
|
||||||
p.writeU32(tweak);
|
p.writeU32(data.tweak);
|
||||||
p.writeU8(update);
|
p.writeU8(update);
|
||||||
|
|
||||||
if (!writer)
|
if (!writer)
|
||||||
@ -349,33 +322,33 @@ Framer.filterLoad = function filterLoad(bloom, update, writer) {
|
|||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.getHeaders = function getHeaders(locator, stop, writer) {
|
Framer.getHeaders = function getHeaders(data, writer) {
|
||||||
// NOTE: getheaders can have an empty locator.
|
return Framer._getBlocks(data, writer, true);
|
||||||
return Framer._getBlocks(locator || [], stop, writer);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.getBlocks = function getBlocks(locator, stop, writer) {
|
Framer.getBlocks = function getBlocks(data, writer) {
|
||||||
return Framer._getBlocks(locator, stop, writer);
|
return Framer._getBlocks(data, writer, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer._getBlocks = function _getBlocks(locator, stop, writer) {
|
Framer._getBlocks = function _getBlocks(data, writer, headers) {
|
||||||
var p, i, version;
|
var version = data.version;
|
||||||
|
var locator = data.locator;
|
||||||
if (locator.locator) {
|
var stop = data.stop;
|
||||||
writer = stop;
|
var p, i;
|
||||||
stop = locator.stop;
|
|
||||||
version = locator.version;
|
|
||||||
locator = locator.locator;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!version)
|
if (!version)
|
||||||
version = constants.version;
|
version = constants.version;
|
||||||
|
|
||||||
|
if (!locator) {
|
||||||
|
if (headers)
|
||||||
|
locator = [];
|
||||||
|
else
|
||||||
|
assert(false, 'getblocks requires a locator');
|
||||||
|
}
|
||||||
|
|
||||||
if (!stop)
|
if (!stop)
|
||||||
stop = constants.zeroHash;
|
stop = constants.zeroHash;
|
||||||
|
|
||||||
assert(locator, 'getblocks requires a locator');
|
|
||||||
|
|
||||||
p = new BufferWriter(writer);
|
p = new BufferWriter(writer);
|
||||||
|
|
||||||
p.writeU32(version);
|
p.writeU32(version);
|
||||||
@ -819,19 +792,10 @@ Framer.UTXOs = function UTXOs(data, writer) {
|
|||||||
var i, j, coin, height, index, map;
|
var i, j, coin, height, index, map;
|
||||||
|
|
||||||
if (!data.map) {
|
if (!data.map) {
|
||||||
assert(data.notfound);
|
assert(data.hits);
|
||||||
map = new bn(0);
|
map = new Buffer((data.hits.length + 7) / 8 | 0);
|
||||||
j = -1;
|
for (i = 0; i < data.hits.length; i++)
|
||||||
for (i = 0; i < data.notfound.length; i++) {
|
map[i / 8 | 0] |= +data.hits[i] << (i % 8);
|
||||||
index = data.notfound[i];
|
|
||||||
while (++j < index) {
|
|
||||||
map.iushln(1);
|
|
||||||
map.iuorn(1);
|
|
||||||
}
|
|
||||||
map.iushln(1);
|
|
||||||
map.iuorn(0);
|
|
||||||
}
|
|
||||||
map = map.toBuffer('be');
|
|
||||||
} else {
|
} else {
|
||||||
map = data.map;
|
map = data.map;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -287,7 +287,7 @@ Parser.parseGetUTXOs = function parseGetUTXOs(p) {
|
|||||||
|
|
||||||
Parser.parseUTXOs = function parseUTXOs(p) {
|
Parser.parseUTXOs = function parseUTXOs(p) {
|
||||||
var chainHeight, tip, map, count, coins;
|
var chainHeight, tip, map, count, coins;
|
||||||
var coin, version, height, i, notfound, ch, j;
|
var coin, version, height, i, hits, ch, j;
|
||||||
|
|
||||||
p = new BufferReader(p);
|
p = new BufferReader(p);
|
||||||
p.start();
|
p.start();
|
||||||
@ -297,15 +297,11 @@ Parser.parseUTXOs = function parseUTXOs(p) {
|
|||||||
map = p.readVarBytes();
|
map = p.readVarBytes();
|
||||||
count = p.readVarint();
|
count = p.readVarint();
|
||||||
coins = [];
|
coins = [];
|
||||||
notfound = [];
|
hits = [];
|
||||||
|
|
||||||
for (i = 0; i < map.length; i++) {
|
for (i = 0; i < map.length; i++) {
|
||||||
ch = map[i];
|
for (j = 0; j < 8; j++)
|
||||||
for (j = 0; j < 8; j++) {
|
hits.push((map[i] >> j) & 1);
|
||||||
if ((ch & 1) === 0)
|
|
||||||
notfound.push(i + j);
|
|
||||||
ch >>>= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
@ -326,7 +322,7 @@ Parser.parseUTXOs = function parseUTXOs(p) {
|
|||||||
tip: tip,
|
tip: tip,
|
||||||
map: map,
|
map: map,
|
||||||
coins: coins,
|
coins: coins,
|
||||||
notfound: notfound,
|
hits: hits,
|
||||||
_size: p.end()
|
_size: p.end()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user