Merge pull request #31 from maraoz/preconditions
various bugfixes and tests
This commit is contained in:
commit
650f4618c4
@ -27,8 +27,8 @@ var blockHash = {
|
||||
'testnet': '0000000058cc069d964711cd25083c0a709f4df2b34c8ff9302ce71fe5b45786'
|
||||
};
|
||||
var stopBlock = {
|
||||
'livenet': '000000000000000006181d9d183e2191a5e704d6ed3513f29b0970198fb34d2e',
|
||||
'testnet': '000000003d594c41db49d5a8b850344943438620acf79ce8aa88177f5b35e337'
|
||||
'livenet': '00000000000000000b539ef570128acb953af3dbcfc19dd8e6066949672311a1',
|
||||
'testnet': '00000000d0bc4271bcefaa7eb25000e345910ba16b91eb375cd944b68624de9f'
|
||||
};
|
||||
var txHash = {
|
||||
'livenet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b',
|
||||
@ -87,7 +87,6 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
|
||||
connect(function(peer) {
|
||||
peer.once('addr', function(message) {
|
||||
message.addresses.forEach(function(address) {
|
||||
// console.log(address.ip.v4 + ':' + address.port);
|
||||
(address.time instanceof Date).should.equal(true);
|
||||
should.exist(address.ip);
|
||||
(address.services instanceof BN).should.equal(true);
|
||||
@ -98,15 +97,13 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
});
|
||||
it('can request inv detailed info', function(cb) {
|
||||
it('requests inv detailed info', function(cb) {
|
||||
connect(function(peer) {
|
||||
peer.once('block', function(message) {
|
||||
//console.log(message.block.toJSON());
|
||||
should.exist(message.block);
|
||||
cb();
|
||||
});
|
||||
peer.once('tx', function(message) {
|
||||
//console.log(message.transaction.toJSON());
|
||||
should.exist(message.transaction);
|
||||
cb();
|
||||
});
|
||||
@ -116,7 +113,7 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
it('can send tx inv and receive getdata for that tx', function(cb) {
|
||||
it('sends tx inv and receives getdata for that tx', function(cb) {
|
||||
connect(function(peer) {
|
||||
var type = Messages.Inventory.TYPE.TX;
|
||||
var inv = [{
|
||||
@ -133,7 +130,7 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
});
|
||||
it('can request block data', function(cb) {
|
||||
it('requests block data', function(cb) {
|
||||
connect(function(peer) {
|
||||
peer.once('block', function(message) {
|
||||
(message.block instanceof Block).should.equal(true);
|
||||
@ -143,39 +140,37 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
});
|
||||
it('can handle request tx data not found', function(cb) {
|
||||
var fakeHash = 'e2dfb8afe1575bfacae1a0b4afc49af7ddda69285857267bae0e22be15f74a3a';
|
||||
it('handles request tx data not found', function(cb) {
|
||||
connect(function(peer) {
|
||||
var hash = 'e2dfb8afe1575bfacae1a0b4afc49af7ddda69285857267bae0e22be15f74a3a';
|
||||
var expected = Messages.NotFound.forTransaction(hash);
|
||||
var expected = Messages.NotFound.forTransaction(fakeHash);
|
||||
peer.once('notfound', function(message) {
|
||||
(message instanceof Messages.NotFound).should.equal(true);
|
||||
message.should.deep.equal(expected);
|
||||
cb();
|
||||
});
|
||||
var message = Messages.GetData.forTransaction(hash);
|
||||
var message = Messages.GetData.forTransaction(fakeHash);
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
});
|
||||
var from = [blockHash[network.name]];
|
||||
var stop = stopBlock[network.name];
|
||||
it('can get headers', function(cb) {
|
||||
it('gets headers', function(cb) {
|
||||
connect(function(peer) {
|
||||
peer.once('headers', function(message) {
|
||||
(message instanceof Messages.Headers).should.equal(true);
|
||||
message.headers.length.should.equal(2);
|
||||
message.headers.length.should.equal(3);
|
||||
cb();
|
||||
});
|
||||
var message = new Messages.GetHeaders(from, stop);
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
});
|
||||
it.skip('can get blocks', function(cb) {
|
||||
it('gets blocks', function(cb) {
|
||||
connect(function(peer) {
|
||||
peer.on('inv', function(message) {
|
||||
peer.once('inv', function(message) {
|
||||
(message instanceof Messages.Inventory).should.equal(true);
|
||||
console.log('inv' + message.inventory.length);
|
||||
if (message.inventory.length === 2) {
|
||||
console.log(message);
|
||||
message.inventory[0].type.should.equal(Messages.Inventory.TYPE.BLOCK);
|
||||
cb();
|
||||
}
|
||||
@ -184,4 +179,26 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
});
|
||||
var testInvGetData = function(expected, message, cb) {
|
||||
connect(function(peer) {
|
||||
peer.once('getdata', function(message) {
|
||||
(message instanceof Messages.GetData).should.equal(true);
|
||||
message.should.deep.equal(expected);
|
||||
cb();
|
||||
});
|
||||
peer.sendMessage(message);
|
||||
});
|
||||
};
|
||||
it('sends block inv and receives getdata', function(cb) {
|
||||
var randomHash = Random.getRandomBuffer(32); // needs to be random for repeatability
|
||||
var expected = Messages.GetData.forBlock(randomHash);
|
||||
var message = Messages.Inventory.forBlock(randomHash);
|
||||
testInvGetData(expected, message, cb);
|
||||
});
|
||||
it('sends tx inv and receives getdata', function(cb) {
|
||||
var randomHash = Random.getRandomBuffer(32); // needs to be random for repeatability
|
||||
var expected = Messages.GetData.forTransaction(randomHash);
|
||||
var message = Messages.Inventory.forTransaction(randomHash);
|
||||
testInvGetData(expected, message, cb);
|
||||
});
|
||||
});
|
||||
|
||||
150
lib/messages.js
150
lib/messages.js
@ -72,6 +72,8 @@ var PAYLOAD_START = 16;
|
||||
* @returns{Message|undefined} A message or undefined if there is nothing to read.
|
||||
*/
|
||||
var parseMessage = function(network, dataBuffer) {
|
||||
$.checkArgument(network);
|
||||
$.checkArgument(dataBuffer);
|
||||
/* jshint maxstatements: 18 */
|
||||
if (dataBuffer.length < 20) {
|
||||
return;
|
||||
@ -112,13 +114,9 @@ module.exports.parseMessage = parseMessage;
|
||||
* @name P2P.Message#buildMessage
|
||||
*/
|
||||
Message.buildMessage = function(command, payload) {
|
||||
try {
|
||||
var CommandClass = Message.COMMANDS[command];
|
||||
return new CommandClass().fromBuffer(payload);
|
||||
} catch (err) {
|
||||
console.log('Error while parsing message', err);
|
||||
throw err;
|
||||
}
|
||||
var CommandClass = Message.COMMANDS[command];
|
||||
$.checkState(CommandClass, 'Unsupported message command: ' + command);
|
||||
return new CommandClass().fromBuffer(payload);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -169,6 +167,13 @@ Message.prototype.serialize = function(network) {
|
||||
return message.buffer();
|
||||
};
|
||||
|
||||
/**
|
||||
* check if parser has no more extra data
|
||||
*/
|
||||
Message.prototype._checkFinished = function(parser) {
|
||||
$.checkState(parser.finished(), 'data still available after parsing ' + this.constructor.name);
|
||||
};
|
||||
|
||||
module.exports.Message = Message;
|
||||
|
||||
/**
|
||||
@ -209,15 +214,29 @@ Version.prototype.fromBuffer = function(payload) {
|
||||
*/
|
||||
this.timestamp = new Date(parser.readUInt64LEBN().toNumber() * 1000);
|
||||
/**
|
||||
* @type {Buffer}
|
||||
* @type {object}
|
||||
* @desc IPv4/6 address of the interface used to connect to this peer
|
||||
*/
|
||||
this.addr_me = parser.read(26);
|
||||
var me_services = parser.readUInt64LEBN();
|
||||
var me_ip = Addresses.parseIP(parser);
|
||||
var me_port = parser.readUInt16BE();
|
||||
this.addr_me = {
|
||||
services: me_services,
|
||||
ip: me_ip,
|
||||
port: me_port
|
||||
};
|
||||
/**
|
||||
* @type {Buffer}
|
||||
* @type {object}
|
||||
* @desc IPv4/6 address of the peer
|
||||
*/
|
||||
this.addr_you = parser.read(26);
|
||||
var your_services = parser.readUInt64LEBN();
|
||||
var your_ip = Addresses.parseIP(parser);
|
||||
var your_port = parser.readUInt16BE();
|
||||
this.addr_you = {
|
||||
services: your_services,
|
||||
ip: your_ip,
|
||||
port: your_port
|
||||
};
|
||||
/**
|
||||
* @type {Buffer}
|
||||
* @desc A random number
|
||||
@ -227,23 +246,30 @@ Version.prototype.fromBuffer = function(payload) {
|
||||
* @desc The node's user agent / subversion
|
||||
* @type {string}
|
||||
*/
|
||||
this.subversion = parser.readVarintBuf().toString();
|
||||
this.subversion = parser.readVarLengthBuffer().toString();
|
||||
/**
|
||||
* @desc The height of the last block accepted in the blockchain by this peer
|
||||
* @type {number}
|
||||
*/
|
||||
this.start_height = parser.readUInt32LE();
|
||||
|
||||
/**
|
||||
* @desc Whether the remote peer should announce relayed transactions or not, see BIP 0037
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.relay = !!parser.readUInt8();
|
||||
|
||||
this._checkFinished(parser);
|
||||
return this;
|
||||
};
|
||||
|
||||
Version.prototype.getPayload = function() {
|
||||
var put = new Put();
|
||||
put.word32le(this.version); // version
|
||||
put.word32le(this.version);
|
||||
put.word64le(1); // services
|
||||
put.word64le(Math.round(new Date().getTime() / 1000)); // timestamp
|
||||
put.pad(26); // addr_me
|
||||
put.pad(26); // addr_you
|
||||
Addresses.writeAddr(this.addr_me, put);
|
||||
Addresses.writeAddr(this.addr_you, put);
|
||||
put.put(this.nonce);
|
||||
put.varint(this.subversion.length);
|
||||
put.put(new Buffer(this.subversion, 'ascii'));
|
||||
@ -315,6 +341,7 @@ Inventory.prototype.fromBuffer = function(payload) {
|
||||
this.inventory.push(Inventory.forItem(type, hash));
|
||||
}
|
||||
|
||||
this._checkFinished(parser);
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -396,7 +423,10 @@ function Ping(nonce) {
|
||||
util.inherits(Ping, Message);
|
||||
|
||||
Ping.prototype.fromBuffer = function(payload) {
|
||||
this.nonce = new BufferReader(payload).read(8);
|
||||
var parser = new BufferReader(payload);
|
||||
this.nonce = parser.read(8);
|
||||
|
||||
this._checkFinished(parser);
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -422,9 +452,6 @@ function Pong(nonce) {
|
||||
}
|
||||
|
||||
util.inherits(Pong, Ping);
|
||||
Pong.prototype.fromBuffer = function() {
|
||||
return new Pong();
|
||||
};
|
||||
module.exports.Pong = Message.COMMANDS.pong = Pong;
|
||||
|
||||
/**
|
||||
@ -443,26 +470,58 @@ function Addresses(addresses) {
|
||||
}
|
||||
util.inherits(Addresses, Message);
|
||||
|
||||
Addresses.writeAddr = function(addr, put) {
|
||||
if (_.isUndefined(addr)) {
|
||||
put.pad(26);
|
||||
return;
|
||||
}
|
||||
put.word64le(addr.services);
|
||||
Addresses.writeIP(addr.ip, put);
|
||||
put.word16be(addr.port);
|
||||
};
|
||||
|
||||
Addresses.writeIP = function(ip, put) {
|
||||
$.checkArgument(ip.v6, 'Need ipv6 to write IP');
|
||||
var words = ip.v6.split(':').map(function(s) {
|
||||
return new Buffer(s, 'hex');
|
||||
});
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
var word = words[i];
|
||||
put.put(word);
|
||||
}
|
||||
};
|
||||
|
||||
// http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses
|
||||
Addresses.parseIP = function(parser) {
|
||||
// parse the ipv6 to a string
|
||||
var ipv6 = [];
|
||||
for (var a = 0; a < 6; a++) {
|
||||
ipv6.push(parser.read(2).toString('hex'));
|
||||
var ipv4 = [];
|
||||
for (var a = 0; a < 8; a++) {
|
||||
var word = parser.read(2);
|
||||
ipv6.push(word.toString('hex'));
|
||||
if (a >= 6) {
|
||||
ipv4.push(word[0]);
|
||||
ipv4.push(word[1]);
|
||||
}
|
||||
}
|
||||
ipv6 = ipv6.join(':');
|
||||
|
||||
// parse the ipv4 to a string
|
||||
var ipv4 = [];
|
||||
for (var b = 0; b < 4; b++) {
|
||||
ipv4.push(parser.read(1)[0]);
|
||||
}
|
||||
ipv4 = ipv4.join('.');
|
||||
|
||||
return {
|
||||
v6: ipv6,
|
||||
v4: ipv4
|
||||
};
|
||||
};
|
||||
|
||||
Addresses.parseAddr = function(parser) {
|
||||
var services = parser.readUInt64LEBN();
|
||||
var ip = Addresses.parseIP(parser);
|
||||
var port = parser.readUInt16BE();
|
||||
return {
|
||||
services: services,
|
||||
ip: ip,
|
||||
port: port
|
||||
};
|
||||
};
|
||||
|
||||
Addresses.prototype.fromBuffer = function(payload) {
|
||||
var parser = new BufferReader(payload);
|
||||
@ -471,22 +530,15 @@ Addresses.prototype.fromBuffer = function(payload) {
|
||||
this.addresses = [];
|
||||
for (var i = 0; i < addrCount; i++) {
|
||||
// TODO: Time actually depends on the version of the other peer (>=31402)
|
||||
|
||||
var time = new Date(parser.readUInt32LE() * 1000);
|
||||
var services = parser.readUInt64LEBN();
|
||||
|
||||
var ip = Addresses.parseIP(parser);
|
||||
var addr = Addresses.parseAddr(parser);
|
||||
addr.time = time;
|
||||
|
||||
var port = parser.readUInt16BE();
|
||||
|
||||
this.addresses.push({
|
||||
time: time,
|
||||
services: services,
|
||||
ip: ip,
|
||||
port: port
|
||||
});
|
||||
this.addresses.push(addr);
|
||||
}
|
||||
|
||||
this._checkFinished(parser);
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -495,10 +547,10 @@ Addresses.prototype.getPayload = function() {
|
||||
put.varint(this.addresses.length);
|
||||
|
||||
for (var i = 0; i < this.addresses.length; i++) {
|
||||
put.word32le(this.addresses[i].time);
|
||||
put.word64le(this.addresses[i].services);
|
||||
put.put(this.addresses[i].ip);
|
||||
put.word16be(this.addresses[i].port);
|
||||
var addr = this.addresses[i];
|
||||
put.word32le(addr.time);
|
||||
Addresses.writeAddr(addr, put);
|
||||
break;
|
||||
}
|
||||
|
||||
return put.buffer();
|
||||
@ -559,8 +611,9 @@ util.inherits(Alert, Message);
|
||||
|
||||
Alert.prototype.fromBuffer = function(payload) {
|
||||
var parser = new BufferReader(payload);
|
||||
this.payload = parser.readVarintBuf(); // TODO: Use current format
|
||||
this.signature = parser.readVarintBuf();
|
||||
this.payload = parser.readVarLengthBuffer();
|
||||
this.signature = parser.readVarLengthBuffer();
|
||||
this._checkFinished(parser);
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -603,8 +656,11 @@ Headers.prototype.fromBuffer = function(payload) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
var header = BlockHeaderModel.fromBufferReader(parser);
|
||||
this.headers.push(header);
|
||||
}
|
||||
var txn_count = parser.readUInt8();
|
||||
$.checkState(txn_count === 0, 'txn_count should always be 0');
|
||||
|
||||
}
|
||||
this._checkFinished(parser);
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -617,6 +673,7 @@ Headers.prototype.getPayload = function() {
|
||||
.headers[i]
|
||||
.toBuffer();
|
||||
put.put(buffer);
|
||||
put.varint(0);
|
||||
}
|
||||
|
||||
return put.buffer();
|
||||
@ -730,6 +787,7 @@ GetBlocks.prototype.fromBuffer = function(payload) {
|
||||
this.starts.push(parser.read(32));
|
||||
}
|
||||
this.stop = parser.read(32);
|
||||
this._checkFinished(parser);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
"url": "https://github.com/bitpay/bitcore-p2p.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"bitcore": "^0.9.0",
|
||||
"bitcore": "^0.9.5",
|
||||
"bufferput": "^0.1.2",
|
||||
"buffers": "^0.1.1",
|
||||
"socks5-client": "^0.3.6"
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
},
|
||||
"ALERT": {
|
||||
"message": "",
|
||||
"payload": ""
|
||||
"payload": "73010000003766404f00000000b305434f00000000f2030000f1030000001027000048ee00000064000000004653656520626974636f696e2e6f72672f666562323020696620796f7520686176652074726f75626c6520636f6e6e656374696e67206166746572203230204665627275617279004730450221008389df45f0703f39ec8c1cc42c13810ffcae14995bb648340219e353b63b53eb022009ec65e1c1aaeec1fd334c6b684bde2b3f573060d5b70c3a46723326e4e8a4f1"
|
||||
},
|
||||
"REJECT": {
|
||||
"message": "",
|
||||
@ -20,8 +20,8 @@
|
||||
"payload": ""
|
||||
},
|
||||
"GETDATA": {
|
||||
"message": "",
|
||||
"payload": ""
|
||||
"message": "f9beb4d967657464617461000000000025000000253fc50c01020000003c2a5e4dcb5a44daf5ebff14a89d26a99b8aa1c1d757694b03d7e6ca7eeda6ca",
|
||||
"payload": "01020000003c2a5e4dcb5a44daf5ebff14a89d26a99b8aa1c1d757694b03d7e6ca7eeda6ca"
|
||||
},
|
||||
"GETADDR": {
|
||||
"message": "",
|
||||
@ -32,8 +32,8 @@
|
||||
"payload": ""
|
||||
},
|
||||
"HEADERS": {
|
||||
"message": "f9beb4d9686561646572730000000000a1000000ffd6770b0202000000b91ddbbfc801b7fe6f470ce9528f98f01b496b53f23c411300000000000000004901c9d18d0a468b20cc62ddf75aee58cf410440ea390300bf7a5f6848be350508d4cb54c0a31a18b9f661ec0002000000a02d6472e3e6fc9a1cebeaad14a90208a715e2bd234ea00600000000000000006f596f650fbbd5478489c66d651c9e3ea56f394d1f1481f90975cf0c8dda45fd3ad4cb54c0a31a1872e262",
|
||||
"payload": "0202000000b91ddbbfc801b7fe6f470ce9528f98f01b496b53f23c411300000000000000004901c9d18d0a468b20cc62ddf75aee58cf410440ea390300bf7a5f6848be350508d4cb54c0a31a18b9f661ec0002000000a02d6472e3e6fc9a1cebeaad14a90208a715e2bd234ea00600000000000000006f596f650fbbd5478489c66d651c9e3ea56f394d1f1481f90975cf0c8dda45fd3ad4cb54c0a31a1872e262"
|
||||
"message": "f9beb4d9686561646572730000000000f400000043385d010302000000b91ddbbfc801b7fe6f470ce9528f98f01b496b53f23c411300000000000000004901c9d18d0a468b20cc62ddf75aee58cf410440ea390300bf7a5f6848be350508d4cb54c0a31a18b9f661ec0002000000a02d6472e3e6fc9a1cebeaad14a90208a715e2bd234ea00600000000000000006f596f650fbbd5478489c66d651c9e3ea56f394d1f1481f90975cf0c8dda45fd3ad4cb54c0a31a1872e262a200020000002e4db38f1970099bf21335edd604e7a591213e189d1d1806000000000000000031a30091f5bdbca8958d2c4ccc0bfa9df93e2a3ea4d00e03222a663179db90a756d6cb54c0a31a187947855000",
|
||||
"payload": "0302000000b91ddbbfc801b7fe6f470ce9528f98f01b496b53f23c411300000000000000004901c9d18d0a468b20cc62ddf75aee58cf410440ea390300bf7a5f6848be350508d4cb54c0a31a18b9f661ec0002000000a02d6472e3e6fc9a1cebeaad14a90208a715e2bd234ea00600000000000000006f596f650fbbd5478489c66d651c9e3ea56f394d1f1481f90975cf0c8dda45fd3ad4cb54c0a31a1872e262a200020000002e4db38f1970099bf21335edd604e7a591213e189d1d1806000000000000000031a30091f5bdbca8958d2c4ccc0bfa9df93e2a3ea4d00e03222a663179db90a756d6cb54c0a31a187947855000"
|
||||
},
|
||||
"TX": {
|
||||
"message": "",
|
||||
|
||||
@ -4,11 +4,15 @@ var chai = require('chai');
|
||||
|
||||
var should = chai.should();
|
||||
|
||||
var Buffers = require('buffers');
|
||||
var bitcore = require('bitcore');
|
||||
var Data = require('./data/messages');
|
||||
var P2P = require('../');
|
||||
var Messages = P2P.Messages;
|
||||
var Networks = bitcore.Networks;
|
||||
var BufferUtils = bitcore.util.buffer;
|
||||
|
||||
var network = Networks.livenet;
|
||||
|
||||
describe('Messages', function() {
|
||||
|
||||
@ -31,7 +35,7 @@ describe('Messages', function() {
|
||||
NotFound: 'notfound'
|
||||
};
|
||||
// TODO: add data for these
|
||||
var noPayload = ['Alert', 'Reject', 'GetBlocks', 'GetHeaders', 'GetData'];
|
||||
var noPayload = ['Reject', 'GetBlocks', 'GetHeaders'];
|
||||
var names = Object.keys(commands);
|
||||
describe('named', function() {
|
||||
names.forEach(function(name) {
|
||||
@ -67,4 +71,49 @@ describe('Messages', function() {
|
||||
});
|
||||
});
|
||||
|
||||
var buildMessage = function(hex) {
|
||||
var m = Buffers();
|
||||
m.push(new Buffer(hex, 'hex'));
|
||||
return m;
|
||||
};
|
||||
it('fails with invalid command', function() {
|
||||
var invalidCommand = 'f9beb4d96d616c6963696f757300000025000000bd5e830c' +
|
||||
'0102000000ec3995c1bf7269ff728818a65e53af00cbbee6b6eca8ac9ce7bc79d87' +
|
||||
'7041ed8';
|
||||
var fails = function() {
|
||||
Messages.parseMessage(network, buildMessage(invalidCommand));
|
||||
};
|
||||
fails.should.throw('Unsupported message command: malicious');
|
||||
});
|
||||
|
||||
it('ignores malformed messages', function() {
|
||||
var malformed1 = 'd8c4c3d976657273696f6e000000000065000000fc970f1772110' +
|
||||
'1000100000000000000ba6288540000000001000000000000000000000000000000' +
|
||||
'0000ffffba8886dceab0010000000000000000000000000000000000ffff0509552' +
|
||||
'2208de7e1c1ef80a1cea70f2f5361746f7368693a302e392e312fa317050001';
|
||||
var malformed2 = 'f9beb4d967657464617461000000000089000000d88134740102' +
|
||||
'0000006308e4a380c949dbad182747b0f7b6a89e874328ca41f37287f74a81b8f84' +
|
||||
'86d';
|
||||
var malformed3 = 'f9beb4d967657464617461000000000025000000616263640102' +
|
||||
'00000069ebcbc34a4f9890da9aea0f773beba883a9afb1ab9ad7647dd4a1cd346c3' +
|
||||
'728';
|
||||
[malformed1, malformed2, malformed3].forEach(function(malformed) {
|
||||
var ret = Messages.parseMessage(network, buildMessage(malformed));
|
||||
should.not.exist(ret);
|
||||
});
|
||||
});
|
||||
|
||||
it('Inventory#from family methods work', function() {
|
||||
var hash = 'eb951630aba498b9a0d10f72b5ea9e39d5ff04b03dc2231e662f52057f948aa1';
|
||||
[Messages.Inventory, Messages.GetData, Messages.NotFound].forEach(function(clazz) {
|
||||
var b = clazz.forBlock(hash);
|
||||
(b instanceof clazz).should.equal(true);
|
||||
var t = clazz.forTransaction(hash);
|
||||
(t instanceof clazz).should.equal(true);
|
||||
clazz.forBlock(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(b);
|
||||
clazz.forTransaction(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(t);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -12,15 +12,15 @@ var sinon = require('sinon');
|
||||
var fs = require('fs');
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var P2P = require('../');
|
||||
var Peer = P2P.Peer;
|
||||
var p2p = require('../');
|
||||
var Peer = p2p.Peer;
|
||||
var Networks = bitcore.Networks;
|
||||
|
||||
describe('Peer', function() {
|
||||
|
||||
describe('Integration test', function() {
|
||||
it('parses this stream of data from a connection', function(callback) {
|
||||
var peer = new P2P.Peer('');
|
||||
var peer = new p2p.Peer('');
|
||||
var stub = sinon.stub();
|
||||
var dataCallback;
|
||||
var connectCallback;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user