bip152: fixes. refactor.

This commit is contained in:
Christopher Jeffrey 2016-07-25 11:32:18 -07:00
parent 642f3c715f
commit 064ba7df9b
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 103 additions and 48 deletions

View File

@ -168,7 +168,7 @@ CompactBlock.prototype.toRaw = function toRaw(witness, writer) {
}; };
CompactBlock.prototype.toRequest = function toRequest() { CompactBlock.prototype.toRequest = function toRequest() {
return BlockTXRequest.fromCompact(this); return TXRequest.fromCompact(this);
}; };
CompactBlock.prototype.fillMempool = function fillMempool(mempool, callback) { CompactBlock.prototype.fillMempool = function fillMempool(mempool, callback) {
@ -218,7 +218,7 @@ CompactBlock.prototype.fillMempool = function fillMempool(mempool, callback) {
}); });
}; };
CompactBlock.prototype.fillMissing = function fillMissing(missing) { CompactBlock.prototype.fillMissing = function fillMissing(res) {
var offset = 0; var offset = 0;
var i; var i;
@ -226,13 +226,13 @@ CompactBlock.prototype.fillMissing = function fillMissing(missing) {
if (this.available[i]) if (this.available[i])
continue; continue;
if (offset >= missing.length) if (offset >= res.txs.length)
return false; return false;
this.available = missing[offset++]; this.available[i] = res.txs[offset++];
} }
return offset === missing.length; return offset === res.txs.length;
}; };
CompactBlock.prototype.sid = function sid(hash) { CompactBlock.prototype.sid = function sid(hash) {
@ -374,9 +374,9 @@ CompactBlock.prototype.stopTimeout = function stopTimeout() {
* @constructor * @constructor
*/ */
function BlockTXRequest(options) { function TXRequest(options) {
if (!(this instanceof BlockTXRequest)) if (!(this instanceof TXRequest))
return new BlockTXRequest(options); return new TXRequest(options);
this.hash = null; this.hash = null;
this.indexes = []; this.indexes = [];
@ -385,7 +385,7 @@ function BlockTXRequest(options) {
this.fromOptions(options); this.fromOptions(options);
} }
BlockTXRequest.prototype.fromOptions = function fromOptions(options) { TXRequest.prototype.fromOptions = function fromOptions(options) {
this.hash = options.hash; this.hash = options.hash;
if (options.indexes) if (options.indexes)
@ -394,11 +394,11 @@ BlockTXRequest.prototype.fromOptions = function fromOptions(options) {
return this; return this;
}; };
BlockTXRequest.fromOptions = function fromOptions(options) { TXRequest.fromOptions = function fromOptions(options) {
return new BlockTXRequest().fromOptions(options); return new TXRequest().fromOptions(options);
}; };
BlockTXRequest.prototype.fromCompact = function fromCompact(block) { TXRequest.prototype.fromCompact = function fromCompact(block) {
var i; var i;
this.hash = block.hash('hex'); this.hash = block.hash('hex');
@ -411,11 +411,11 @@ BlockTXRequest.prototype.fromCompact = function fromCompact(block) {
return this; return this;
}; };
BlockTXRequest.fromCompact = function fromCompact(block) { TXRequest.fromCompact = function fromCompact(block) {
return new BlockTXRequest().fromCompact(block); return new TXRequest().fromCompact(block);
}; };
BlockTXRequest.prototype.fromRaw = function fromRaw(data) { TXRequest.prototype.fromRaw = function fromRaw(data) {
var p = bcoin.reader(data); var p = bcoin.reader(data);
var i, count, index, offset; var i, count, index, offset;
@ -442,11 +442,11 @@ BlockTXRequest.prototype.fromRaw = function fromRaw(data) {
return this; return this;
}; };
BlockTXRequest.fromRaw = function fromRaw(data) { TXRequest.fromRaw = function fromRaw(data) {
return new BlockTXRequest().fromRaw(data); return new TXRequest().fromRaw(data);
}; };
BlockTXRequest.prototype.toRaw = function toRaw(writer) { TXRequest.prototype.toRaw = function toRaw(writer) {
var p = bcoin.writer(writer); var p = bcoin.writer(writer);
var i, index; var i, index;
@ -471,9 +471,9 @@ BlockTXRequest.prototype.toRaw = function toRaw(writer) {
* @constructor * @constructor
*/ */
function BlockTX(options) { function TXResponse(options) {
if (!(this instanceof BlockTX)) if (!(this instanceof TXResponse))
return new BlockTX(options); return new TXResponse(options);
this.hash = null; this.hash = null;
this.txs = []; this.txs = [];
@ -482,7 +482,7 @@ function BlockTX(options) {
this.fromOptions(options); this.fromOptions(options);
} }
BlockTX.prototype.fromOptions = function fromOptions(options) { TXResponse.prototype.fromOptions = function fromOptions(options) {
this.hash = options.hash; this.hash = options.hash;
if (options.txs) if (options.txs)
@ -491,11 +491,11 @@ BlockTX.prototype.fromOptions = function fromOptions(options) {
return this; return this;
}; };
BlockTX.fromOptions = function fromOptions(options) { TXResponse.fromOptions = function fromOptions(options) {
return new BlockTX().fromOptions(options); return new TXResponse().fromOptions(options);
}; };
BlockTX.prototype.fromRaw = function fromRaw(data) { TXResponse.prototype.fromRaw = function fromRaw(data) {
var p = bcoin.reader(data); var p = bcoin.reader(data);
var i, count; var i, count;
@ -509,30 +509,30 @@ BlockTX.prototype.fromRaw = function fromRaw(data) {
return this; return this;
}; };
BlockTX.fromRaw = function fromRaw(data) { TXResponse.fromRaw = function fromRaw(data) {
return new BlockTX().fromRaw(data); return new TXResponse().fromRaw(data);
}; };
BlockTX.prototype.fromBlock = function fromBlock(block, request) { TXResponse.prototype.fromBlock = function fromBlock(block, req) {
var i, index; var i, index;
this.hash = request.hash; this.hash = req.hash;
for (i = 0; i < request.indexes.length; i++) { for (i = 0; i < req.indexes.length; i++) {
index = request.indexes[i]; index = req.indexes[i];
if (index >= block.txs.length) if (index >= block.txs.length)
return; return this;
this.txs.push(block.txs[index]); this.txs.push(block.txs[index]);
} }
return this; return this;
}; };
BlockTX.fromBlock = function fromBlock(block, request) { TXResponse.fromBlock = function fromBlock(block, req) {
return new BlockTX().fromBlock(block, request); return new TXResponse().fromBlock(block, req);
}; };
BlockTX.prototype.toRaw = function toRaw(witness, writer) { TXResponse.prototype.toRaw = function toRaw(witness, writer) {
var p = bcoin.writer(writer); var p = bcoin.writer(writer);
var i, tx; var i, tx;
@ -597,6 +597,6 @@ SendCompact.prototype.toRaw = function toRaw(writer) {
*/ */
exports.CompactBlock = CompactBlock; exports.CompactBlock = CompactBlock;
exports.BlockTXRequest = BlockTXRequest; exports.TXRequest = TXRequest;
exports.BlockTX = BlockTX; exports.TXResponse = TXResponse;
exports.SendCompact = SendCompact; exports.SendCompact = SendCompact;

View File

@ -1919,16 +1919,16 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(block) {
* @param {Object} * @param {Object}
*/ */
Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) { Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(req) {
var self = this; var self = this;
var blockTX; var res;
function done(err) { function done(err) {
if (err) { if (err) {
self.emit('error', err); self.emit('error', err);
return; return;
} }
self.fire('blocktxn', payload); self.fire('blocktxn', req);
} }
if (this.chain.db.options.spv) if (this.chain.db.options.spv)
@ -1940,7 +1940,7 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
if (this.pool.options.selfish) if (this.pool.options.selfish)
return done(); return done();
this.chain.db.getBlock(payload.hash, function(err, block) { this.chain.db.getBlock(req.hash, function(err, block) {
if (err) if (err)
return done(err); return done(err);
@ -1959,9 +1959,9 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
return done(); return done();
} }
blockTX = bcoin.bip152.BlockTX.fromBlock(block, payload); res = bcoin.bip152.TXResponse.fromBlock(block, req);
self.write(self.framer.blockTxn(blockTX)); self.write(self.framer.blockTxn(res));
done(); done();
}); });
@ -1973,20 +1973,20 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
* @param {Object} * @param {Object}
*/ */
Peer.prototype._handleBlockTxn = function _handleBlockTxn(payload) { Peer.prototype._handleBlockTxn = function _handleBlockTxn(res) {
var block = this.compactBlocks[payload.hash]; var block = this.compactBlocks[res.hash];
if (!block) { if (!block) {
this.logger.info('Peer sent unsolicited blocktxn (%s).', this.hostname); this.logger.info('Peer sent unsolicited blocktxn (%s).', this.hostname);
return; return;
} }
this.fire('getblocktxn', payload); this.fire('getblocktxn', res);
block.stopTimeout(); block.stopTimeout();
delete this.compactBlocks[payload.hash]; delete this.compactBlocks[res.hash];
if (!block.fillMissing(payload.txs)) { if (!block.fillMissing(res)) {
this.setMisbehavior(100); this.setMisbehavior(100);
this.logger.info('Peer sent non-full blocktxn (%s).', this.hostname); this.logger.info('Peer sent non-full blocktxn (%s).', this.hostname);
return; return;

View File

@ -242,4 +242,59 @@ describe('Block', function() {
cb(); cb();
}); });
}); });
it('should handle half-full compact block', function(cb) {
var cblock = bip152.CompactBlock.fromRaw(cmpct[0], 'hex');
var block = bcoin.block.fromRaw(cmpct[1], 'hex');
var cblock2 = bip152.CompactBlock.fromBlock(block, cblock.keyNonce);
var map = {};
assert.equal(cblock.toRaw().toString('hex'), cmpct[0]);
assert.equal(cblock2.toRaw().toString('hex'), cmpct[0]);
for (var i = 0; i < block.txs.length; i++) {
var tx = block.txs[i];
map[tx.hash('hex')] = tx;
}
var mid = block.txs.length >>> 1;
var keys = Object.keys(map).slice(0, mid);
var fakeMempool = {
getSnapshot: function(callback) {
callback(null, keys);
},
getTX: function(hash, callback) {
callback(null, map[hash]);
}
};
assert.equal(cblock.sid(block.txs[1].hash()), 125673511480291);
cblock.fillMempool(fakeMempool, function(err, result) {
assert.ifError(err);
assert(!result);
var req = cblock.toRequest();
assert.equal(req.hash, cblock.hash('hex'));
assert.deepEqual(req.indexes, [5, 6, 7, 8, 9]);
req = bip152.TXRequest.fromRaw(req.toRaw());
assert.equal(req.hash, cblock.hash('hex'));
assert.deepEqual(req.indexes, [5, 6, 7, 8, 9]);
var res = bip152.TXResponse.fromBlock(block, req);
res = bip152.TXResponse.fromRaw(res.toRaw());
var result = cblock.fillMissing(res);
assert(result);
for (var i = 0; i < cblock.available.length; i++)
assert(cblock.available[i]);
assert.equal(cblock.toBlock().toRaw().toString('hex'), block.toRaw().toString('hex'));
cb();
});
});
}); });