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

View File

@ -1919,16 +1919,16 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(block) {
* @param {Object}
*/
Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(req) {
var self = this;
var blockTX;
var res;
function done(err) {
if (err) {
self.emit('error', err);
return;
}
self.fire('blocktxn', payload);
self.fire('blocktxn', req);
}
if (this.chain.db.options.spv)
@ -1940,7 +1940,7 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
if (this.pool.options.selfish)
return done();
this.chain.db.getBlock(payload.hash, function(err, block) {
this.chain.db.getBlock(req.hash, function(err, block) {
if (err)
return done(err);
@ -1959,9 +1959,9 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
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();
});
@ -1973,20 +1973,20 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(payload) {
* @param {Object}
*/
Peer.prototype._handleBlockTxn = function _handleBlockTxn(payload) {
var block = this.compactBlocks[payload.hash];
Peer.prototype._handleBlockTxn = function _handleBlockTxn(res) {
var block = this.compactBlocks[res.hash];
if (!block) {
this.logger.info('Peer sent unsolicited blocktxn (%s).', this.hostname);
return;
}
this.fire('getblocktxn', payload);
this.fire('getblocktxn', res);
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.logger.info('Peer sent non-full blocktxn (%s).', this.hostname);
return;

View File

@ -242,4 +242,59 @@ describe('Block', function() {
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();
});
});
});