add notfound message

This commit is contained in:
Manuel Araoz 2015-02-02 15:56:32 -03:00
parent 1937abac11
commit 087c57e077
2 changed files with 78 additions and 29 deletions

View File

@ -18,6 +18,7 @@ var Pool = p2p.Pool;
var Networks = bitcore.Networks;
var Messages = p2p.Messages;
var Block = bitcore.Block;
var Transaction = bitcore.Transaction;
// config
var network = Networks.livenet;
@ -25,6 +26,10 @@ var blockHash = {
'livenet': '000000000000000013413cf2536b491bf0988f52e90c476ffeb701c8bfdb1db9',
'testnet': '0000000058cc069d964711cd25083c0a709f4df2b34c8ff9302ce71fe5b45786'
};
var txHash = {
'livenet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b',
'testnet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b'
};
// These tests require a running bitcoind instance
describe('Integration with ' + network.name + ' bitcoind', function() {
@ -126,15 +131,25 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
});
it('can request block data', function(cb) {
connect(function(peer) {
peer.on('block', function(message) {
peer.once('block', function(message) {
(message.block instanceof Block).should.equal(true);
cb();
});
// TODO: replace this for a new Messages.GetData.forTransaction(hash)
var message = new Messages.GetData([{
type: Messages.Inventory.TYPE.BLOCK,
hash: BufferUtil.reverse(new Buffer(blockHash[network.name], 'hex'))
}]);
// TODO: replace this for a new Messages.GetData.forBlock(hash)
var message = Messages.GetData.forBlock(blockHash[network.name]);
peer.sendMessage(message);
});
});
it('can handle request tx data not found', function(cb) {
connect(function(peer) {
var hash = 'e2dfb8afe1575bfacae1a0b4afc49af7ddda69285857267bae0e22be15f74a3a';
var expected = Messages.NotFound.forTransaction(hash);
peer.once('notfound', function(message) {
(message instanceof Messages.NotFound).should.equal(true);
message.should.deep.equal(expected);
cb();
});
var message = Messages.GetData.forTransaction(hash);
peer.sendMessage(message);
});
});

View File

@ -19,7 +19,6 @@ var $ = bitcore.util.preconditions;
var Hash = bitcore.crypto.Hash;
var Random = bitcore.crypto.Random;
var TransactionModel = bitcore.Transaction;
var errors = bitcore.Errors;
var CONNECTION_NONCE = Random.getPseudoRandomBuffer(8);
var PROTOCOL_VERSION = 70000;
@ -130,7 +129,7 @@ Message.buildMessage = function(command, payload) {
*/
Message.prototype.fromBuffer = function(payload) {
/* jshint unused: false */
throw new errors.NotImplemented();
return this;
};
/**
@ -264,6 +263,13 @@ module.exports.Version = Message.COMMANDS.version = Version;
* @param{Array} inventory - reported elements
*/
function Inventory(inventory) {
$.checkArgument(_.isUndefined(inventory) ||
_.isArray(inventory), 'Inventory for ' +
this.constructor.name + ' must be an array of objects');
$.checkArgument(_.isUndefined(inventory) ||
inventory.length === 0 ||
(inventory[0] && !_.isUndefined(inventory[0].type) && !_.isUndefined(inventory[0].hash)),
'Inventory for ' + this.constructor.name + ' must be an array of objects');
this.command = 'inv';
/**
* @name P2P.Message.Inventory.inventory
@ -287,16 +293,26 @@ Inventory.TYPE_NAME = [
'FILTERED_BLOCK'
];
Inventory.forItem = function(type, hash) {
$.checkArgument(hash);
if (_.isString(hash)) {
hash = new Buffer(hash, 'hex');
hash = BufferUtil.reverse(hash);
}
return {
type: type,
typeName: Inventory.TYPE_NAME[type],
hash: hash
};
};
Inventory.prototype.fromBuffer = function(payload) {
var parser = new BufferReader(payload);
var count = parser.readVarintNum();
for (var i = 0; i < count; i++) {
var type = parser.readUInt32LE();
this.inventory.push({
type: type,
typeName: Inventory.TYPE_NAME[type],
hash: parser.read(32)
});
var hash = parser.read(32);
this.inventory.push(Inventory.forItem(type, hash));
}
return this;
@ -314,8 +330,32 @@ Inventory.prototype.getPayload = function() {
return put.buffer();
};
var creatorForItem = function(clazz, type) {
return function(hash) {
return new clazz([Inventory.forItem(type, hash)]);
};
};
module.exports.Inventory = Message.COMMANDS.inv = Inventory;
/**
* notfound is a response to a getdata, sent if any requested data
* items could not be relayed, for example, because the requested
* transaction was not in the memory pool or relay set.
*
* (from bitcoin's protocol spec)
*
* @name P2P.Message.NotFound
* @param{Array} inventory - not found elements
*/
function NotFound(inventory) {
Inventory.call(this, inventory);
this.command = 'notfound';
}
util.inherits(NotFound, Inventory);
module.exports.NotFound = Message.COMMANDS.notfound = NotFound;
/**
* getdata is used in response to inv, to retrieve the content of a specific
* object, and is usually sent after receiving an inv packet, after filtering
@ -324,22 +364,18 @@ module.exports.Inventory = Message.COMMANDS.inv = Inventory;
* chain is not allowed to avoid having clients start to depend on nodes having
* full transaction indexes (which modern nodes do not).
*
* (taken from bitcoin's protocol spec)
* (from bitcoin's protocol spec)
*
* @name P2P.Message.GetData
* @param{Array} inventory - requested elements
*/
function GetData(inventory) {
$.checkArgument(_.isUndefined(inventory) ||
_.isArray(inventory), 'Inventory for GetData must be an array of objects');
$.checkArgument(_.isUndefined(inventory) ||
inventory.length === 0 ||
(inventory[0] && !_.isUndefined(inventory[0].type) && !_.isUndefined(inventory[0].hash)),
'Inventory for GetData must be an array of objects');
Inventory.call(this, inventory);
this.command = 'getdata';
this.inventory = inventory || [];
}
util.inherits(GetData, Inventory);
module.exports.GetData = Message.COMMANDS.getdata = GetData;
@ -480,9 +516,6 @@ function GetAddresses() {
}
util.inherits(GetAddresses, Message);
GetAddresses.prototype.fromBuffer = function() {
return new GetAddresses();
};
module.exports.GetAddresses = Message.COMMANDS.getaddr = GetAddresses;
/**
@ -495,9 +528,6 @@ function VerAck() {
}
util.inherits(VerAck, Message);
VerAck.prototype.fromBuffer = function() {
return new VerAck();
};
module.exports.VerAck = Message.COMMANDS.verack = VerAck;
/**
@ -737,9 +767,6 @@ function GetHeaders(starts, stop) {
}
util.inherits(GetHeaders, GetBlocks);
GetHeaders.prototype.fromBuffer = function() {
return new GetHeaders();
};
module.exports.GetHeaders = Message.COMMANDS.getheaders = GetHeaders;
/**
@ -769,3 +796,10 @@ Buffers.prototype.skip = function(i) {
this.buffers[0] = new Buffer(this.buffers[0].slice(pos.offset));
this.length -= i;
};
[Inventory, GetData, NotFound].forEach(function(clazz) {
clazz.forBlock = creatorForItem(clazz, Inventory.TYPE.BLOCK);
clazz.forTransaction = creatorForItem(clazz, Inventory.TYPE.TX);
});