add notfound message
This commit is contained in:
parent
1937abac11
commit
087c57e077
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user