refactor message#fromBuffer()
This commit is contained in:
parent
ce7ccc773e
commit
eaca92b1c6
107
lib/messages.js
107
lib/messages.js
@ -17,6 +17,7 @@ var BufferUtil = bitcore.util.buffer;
|
||||
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;
|
||||
@ -88,7 +89,7 @@ function discardUntilNextMessage(network, dataBuffer) {
|
||||
|
||||
/**
|
||||
* Abstract Message that knows how to parse and serialize itself.
|
||||
* Concret subclases should implement {fromBuffer} and {getPayload} methods.
|
||||
* Concrete subclasses should implement {fromBuffer} and {getPayload} methods.
|
||||
* @name P2P.Message
|
||||
*/
|
||||
function Message() {}
|
||||
@ -106,7 +107,7 @@ Message.COMMANDS = {};
|
||||
Message.buildMessage = function(command, payload) {
|
||||
try {
|
||||
var CommandClass = Message.COMMANDS[command];
|
||||
return new CommandClass().fromBuffer(payload);
|
||||
return new CommandClass.fromBuffer(payload);
|
||||
} catch (err) {
|
||||
console.log('Error while parsing message', err);
|
||||
}
|
||||
@ -118,9 +119,9 @@ Message.buildMessage = function(command, payload) {
|
||||
* @param{Buffer} payload - the buffer to read from
|
||||
* @returns{Message} The same message instance
|
||||
*/
|
||||
Message.prototype.fromBuffer = function(payload) {
|
||||
Message.fromBuffer = function(payload) {
|
||||
/* jshint unused: false */
|
||||
return this;
|
||||
throw new errors.NotImplemented();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -180,51 +181,52 @@ function Version(subversion, nonce) {
|
||||
}
|
||||
util.inherits(Version, Message);
|
||||
|
||||
Version.prototype.fromBuffer = function(payload) {
|
||||
Version.fromBuffer = function(payload) {
|
||||
var that = new Version();
|
||||
var parser = new BufferReader(payload);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @desc The version of the bitcoin protocol
|
||||
*/
|
||||
this.version = parser.readUInt32LE();
|
||||
that.version = parser.readUInt32LE();
|
||||
/**
|
||||
* @type {BN}
|
||||
* @desc A mapbit with service bits: what features are supported by the peer
|
||||
*/
|
||||
this.services = parser.readUInt64LEBN();
|
||||
that.services = parser.readUInt64LEBN();
|
||||
/**
|
||||
* @type {BN}
|
||||
* @desc The time this message was sent
|
||||
*/
|
||||
this.timestamp = parser.readUInt64LEBN();
|
||||
that.timestamp = parser.readUInt64LEBN();
|
||||
/**
|
||||
* @type {Buffer}
|
||||
* @desc IPv4/6 address of the interface used to connect to this peer
|
||||
*/
|
||||
this.addr_me = parser.read(26);
|
||||
that.addr_me = parser.read(26);
|
||||
/**
|
||||
* @type {Buffer}
|
||||
* @desc IPv4/6 address of the peer
|
||||
*/
|
||||
this.addr_you = parser.read(26);
|
||||
that.addr_you = parser.read(26);
|
||||
/**
|
||||
* @type {Buffer}
|
||||
* @desc A random number
|
||||
*/
|
||||
this.nonce = parser.read(8);
|
||||
that.nonce = parser.read(8);
|
||||
/**
|
||||
* @desc A random number
|
||||
* @type {string}
|
||||
*/
|
||||
this.subversion = parser.readVarintBuf().toString();
|
||||
that.subversion = parser.readVarintBuf().toString();
|
||||
/**
|
||||
* @desc The height of the last block accepted in the blockchain by this peer
|
||||
* @type {number}
|
||||
*/
|
||||
this.start_height = parser.readUInt32LE();
|
||||
that.start_height = parser.readUInt32LE();
|
||||
|
||||
return this;
|
||||
return that;
|
||||
};
|
||||
|
||||
Version.prototype.getPayload = function() {
|
||||
@ -263,17 +265,18 @@ function Inventory(inventory) {
|
||||
}
|
||||
util.inherits(Inventory, Message);
|
||||
|
||||
Inventory.prototype.fromBuffer = function(payload) {
|
||||
Inventory.fromBuffer = function(payload) {
|
||||
var that = new Inventory();
|
||||
var parser = new BufferReader(payload);
|
||||
var count = parser.readVarintNum();
|
||||
for (var i = 0; i < count; i++) {
|
||||
this.inventory.push({
|
||||
that.inventory.push({
|
||||
type: parser.readUInt32LE(),
|
||||
hash: parser.read(32)
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
return that;
|
||||
};
|
||||
|
||||
Inventory.prototype.getPayload = function() {
|
||||
@ -327,9 +330,10 @@ function Ping(nonce) {
|
||||
}
|
||||
util.inherits(Ping, Message);
|
||||
|
||||
Ping.prototype.fromBuffer = function(payload) {
|
||||
this.nonce = new BufferReader(payload).read(8);
|
||||
return this;
|
||||
Ping.fromBuffer = function(payload) {
|
||||
var that = new Ping();
|
||||
that.nonce = new BufferReader(payload).read(8);
|
||||
return that;
|
||||
};
|
||||
|
||||
Ping.prototype.getPayload = function() {
|
||||
@ -354,6 +358,9 @@ function Pong(nonce) {
|
||||
}
|
||||
|
||||
util.inherits(Pong, Ping);
|
||||
Pong.fromBuffer = function() {
|
||||
return new Pong();
|
||||
};
|
||||
module.exports.Pong = Message.COMMANDS.pong = Pong;
|
||||
|
||||
/**
|
||||
@ -372,11 +379,12 @@ function Addresses(addresses) {
|
||||
}
|
||||
util.inherits(Addresses, Message);
|
||||
|
||||
Addresses.prototype.fromBuffer = function(payload) {
|
||||
Addresses.fromBuffer = function(payload) {
|
||||
var that = new Addresses();
|
||||
var parser = new BufferReader(payload);
|
||||
var addrCount = Math.min(parser.readVarintNum(), 1000);
|
||||
|
||||
this.addresses = [];
|
||||
that.addresses = [];
|
||||
for (var i = 0; i < addrCount; i++) {
|
||||
// TODO: Time actually depends on the version of the other peer (>=31402)
|
||||
|
||||
@ -399,7 +407,7 @@ Addresses.prototype.fromBuffer = function(payload) {
|
||||
|
||||
var port = parser.readUInt16BE();
|
||||
|
||||
this.addresses.push({
|
||||
that.addresses.push({
|
||||
time: time,
|
||||
services: services,
|
||||
ip: { v6: ipv6, v4: ipv4 },
|
||||
@ -407,7 +415,7 @@ Addresses.prototype.fromBuffer = function(payload) {
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
return that;
|
||||
};
|
||||
|
||||
Addresses.prototype.getPayload = function() {
|
||||
@ -436,6 +444,9 @@ function GetAddresses() {
|
||||
}
|
||||
|
||||
util.inherits(GetAddresses, Message);
|
||||
GetAddresses.fromBuffer = function() {
|
||||
return new GetAddresses();
|
||||
};
|
||||
module.exports.GetAddresses = Message.COMMANDS.getaddr = GetAddresses;
|
||||
|
||||
/**
|
||||
@ -448,6 +459,9 @@ function VerAck() {
|
||||
}
|
||||
|
||||
util.inherits(VerAck, Message);
|
||||
VerAck.fromBuffer = function() {
|
||||
return new VerAck();
|
||||
};
|
||||
module.exports.VerAck = Message.COMMANDS.verack = VerAck;
|
||||
|
||||
/**
|
||||
@ -477,11 +491,12 @@ function Alert(payload, signature) {
|
||||
}
|
||||
util.inherits(Alert, Message);
|
||||
|
||||
Alert.prototype.fromBuffer = function(payload) {
|
||||
Alert.fromBuffer = function(payload) {
|
||||
var that = new Alert();
|
||||
var parser = new BufferReader(payload);
|
||||
this.payload = parser.readVarintBuf(); // TODO: Use current format
|
||||
this.signature = parser.readVarintBuf();
|
||||
return this;
|
||||
that.payload = parser.readVarintBuf(); // TODO: Use current format
|
||||
that.signature = parser.readVarintBuf();
|
||||
return that;
|
||||
};
|
||||
|
||||
Alert.prototype.getPayload = function() {
|
||||
@ -514,17 +529,18 @@ function Headers(blockheaders) {
|
||||
}
|
||||
util.inherits(Headers, Message);
|
||||
|
||||
Headers.prototype.fromBuffer = function(payload) {
|
||||
Headers.fromBuffer = function(payload) {
|
||||
var that = new Headers();
|
||||
var parser = new BufferReader(payload);
|
||||
var count = parser.readVarintNum();
|
||||
|
||||
this.headers = [];
|
||||
that.headers = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
var header = BlockHeaderModel._fromBufferReader(parser);
|
||||
this.headers.push(header);
|
||||
that.headers.push(header);
|
||||
}
|
||||
|
||||
return this;
|
||||
return that;
|
||||
};
|
||||
|
||||
Headers.prototype.getPayload = function() {
|
||||
@ -558,9 +574,10 @@ function Block(block) {
|
||||
}
|
||||
util.inherits(Block, Message);
|
||||
|
||||
Block.prototype.fromBuffer = function(payload) {
|
||||
this.block = BlockModel(payload);
|
||||
return this;
|
||||
Block.fromBuffer = function(payload) {
|
||||
var that = new Block();
|
||||
that.block = BlockModel(payload);
|
||||
return that;
|
||||
};
|
||||
|
||||
Block.prototype.getPayload = function() {
|
||||
@ -584,9 +601,10 @@ function Transaction(transaction) {
|
||||
}
|
||||
util.inherits(Transaction, Message);
|
||||
|
||||
Transaction.prototype.fromBuffer = function(payload) {
|
||||
this.transaction = TransactionModel(payload);
|
||||
return this;
|
||||
Transaction.fromBuffer = function(payload) {
|
||||
var that = new Transaction();
|
||||
that.transaction = TransactionModel(payload);
|
||||
return that;
|
||||
};
|
||||
|
||||
Transaction.prototype.getPayload = function() {
|
||||
@ -622,18 +640,19 @@ function GetBlocks(starts, stop) {
|
||||
}
|
||||
util.inherits(GetBlocks, Message);
|
||||
|
||||
GetBlocks.prototype.fromBuffer = function(payload) {
|
||||
GetBlocks.fromBuffer = function(payload) {
|
||||
var that = new GetBlocks();
|
||||
var parser = new BufferReader(payload);
|
||||
this.version = parser.readUInt32LE();
|
||||
that.version = parser.readUInt32LE();
|
||||
|
||||
var startCount = Math.min(parser.readVarintNum(), 500);
|
||||
this.starts = [];
|
||||
that.starts = [];
|
||||
for (var i = 0; i < startCount; i++) {
|
||||
this.starts.push(parser.read(32));
|
||||
that.starts.push(parser.read(32));
|
||||
}
|
||||
this.stop = parser.read(32);
|
||||
that.stop = parser.read(32);
|
||||
|
||||
return this;
|
||||
return that;
|
||||
};
|
||||
|
||||
GetBlocks.prototype.getPayload = function() {
|
||||
|
||||
@ -36,31 +36,32 @@ describe('Messages', function() {
|
||||
|
||||
it('should be able to parse payload', function() {
|
||||
var payload = new Buffer(Data.VERSION.payload, 'hex');
|
||||
new Messages.Version().fromBuffer(payload);
|
||||
var m = Messages.Version.fromBuffer(payload);
|
||||
should.exist(m);
|
||||
});
|
||||
});
|
||||
|
||||
describe('VerAck', function() {
|
||||
var name = 'VerAck';
|
||||
describe(name, function() {
|
||||
var message = new Messages[name]();
|
||||
it('should be able to create instance', function() {
|
||||
var message = new Messages.VerAck();
|
||||
message.command.should.equal('verack');
|
||||
message.command.should.equal(name.toLowerCase());
|
||||
});
|
||||
|
||||
it('should be able to serialize the payload', function() {
|
||||
var message = new Messages.VerAck();
|
||||
var payload = message.getPayload();
|
||||
should.exist(payload);
|
||||
});
|
||||
|
||||
it('should be able to serialize the message', function() {
|
||||
var message = new Messages.VerAck();
|
||||
var buffer = message.serialize(Networks.livenet);
|
||||
should.exist(buffer);
|
||||
});
|
||||
|
||||
it('should be able to parse payload', function() {
|
||||
var payload = new Buffer(Data.VERACK.payload, 'hex');
|
||||
new Messages.VerAck().fromBuffer(payload);
|
||||
var payload = new Buffer(Data[name.toUpperCase()].payload, 'hex');
|
||||
var m = Messages[name].fromBuffer(payload);
|
||||
should.exist(m);
|
||||
});
|
||||
});
|
||||
|
||||
@ -84,7 +85,8 @@ describe('Messages', function() {
|
||||
|
||||
it('should be able to parse payload', function() {
|
||||
var payload = new Buffer(Data.INV.payload, 'hex');
|
||||
new Messages.Inventory().fromBuffer(payload);
|
||||
var m = Messages.Inventory.fromBuffer(payload);
|
||||
should.exist(m);
|
||||
});
|
||||
});
|
||||
|
||||
@ -108,10 +110,17 @@ describe('Messages', function() {
|
||||
|
||||
it('should be able to parse payload', function() {
|
||||
var payload = new Buffer(Data.ADDR.payload, 'hex');
|
||||
new Messages.Addresses().fromBuffer(payload);
|
||||
var m = Messages.Addresses.fromBuffer(payload);
|
||||
should.exist(m);
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
Data.forEach(function(x) {
|
||||
console.log(x);
|
||||
});
|
||||
*/
|
||||
|
||||
describe('Ping', function() {
|
||||
it('should be able to create instance', function() {
|
||||
var message = new Messages.Ping();
|
||||
@ -132,7 +141,8 @@ describe('Messages', function() {
|
||||
|
||||
it('should be able to parse payload', function() {
|
||||
var payload = new Buffer(Data.PING.payload, 'hex');
|
||||
new Messages.Ping().fromBuffer(payload);
|
||||
var m = Messages.Ping.fromBuffer(payload);
|
||||
should.exist(m);
|
||||
});
|
||||
});
|
||||
|
||||
@ -156,7 +166,8 @@ describe('Messages', function() {
|
||||
|
||||
it('should be able to parse payload', function() {
|
||||
var payload = new Buffer(Data.PING.payload, 'hex');
|
||||
new Messages.Pong().fromBuffer(payload);
|
||||
var m = Messages.Pong.fromBuffer(payload);
|
||||
should.exist(m);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ describe('Pool', function() {
|
||||
// mock a addr peer event
|
||||
var peerMessageStub = sinon.stub(Peer.prototype, '_readMessage', function() {
|
||||
var payload = new Buffer(MessagesData.ADDR.payload, 'hex');
|
||||
var message = new Messages.Addresses().fromBuffer(payload);
|
||||
var message = Messages.Addresses.fromBuffer(payload);
|
||||
this.emit(message.command, message);
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user