2809 lines
50 KiB
JavaScript
2809 lines
50 KiB
JavaScript
/*!
|
|
* packets.js - packets for bcoin
|
|
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
|
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
|
* https://github.com/bcoin-org/bcoin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @module net/packets
|
|
*/
|
|
|
|
const assert = require('bsert');
|
|
const bio = require('bufio');
|
|
const {BloomFilter} = require('bfilter');
|
|
const common = require('./common');
|
|
const util = require('../utils/util');
|
|
const bip152 = require('./bip152');
|
|
const NetAddress = require('./netaddress');
|
|
const consensus = require('../protocol/consensus');
|
|
const Headers = require('../primitives/headers');
|
|
const InvItem = require('../primitives/invitem');
|
|
const MemBlock = require('../primitives/memblock');
|
|
const MerkleBlock = require('../primitives/merkleblock');
|
|
const TX = require('../primitives/tx');
|
|
const {encoding} = bio;
|
|
const DUMMY = Buffer.alloc(0);
|
|
|
|
/**
|
|
* Packet types.
|
|
* @enum {Number}
|
|
* @default
|
|
*/
|
|
|
|
exports.types = {
|
|
VERSION: 0,
|
|
VERACK: 1,
|
|
PING: 2,
|
|
PONG: 3,
|
|
GETADDR: 4,
|
|
ADDR: 5,
|
|
INV: 6,
|
|
GETDATA: 7,
|
|
NOTFOUND: 8,
|
|
GETBLOCKS: 9,
|
|
GETHEADERS: 10,
|
|
HEADERS: 11,
|
|
SENDHEADERS: 12,
|
|
BLOCK: 13,
|
|
TX: 14,
|
|
REJECT: 15,
|
|
MEMPOOL: 16,
|
|
FILTERLOAD: 17,
|
|
FILTERADD: 18,
|
|
FILTERCLEAR: 19,
|
|
MERKLEBLOCK: 20,
|
|
FEEFILTER: 21,
|
|
SENDCMPCT: 22,
|
|
CMPCTBLOCK: 23,
|
|
GETBLOCKTXN: 24,
|
|
BLOCKTXN: 25,
|
|
UNKNOWN: 26,
|
|
// Internal
|
|
INTERNAL: 27,
|
|
DATA: 28
|
|
};
|
|
|
|
/**
|
|
* Packet types by value.
|
|
* @const {Object}
|
|
* @default
|
|
*/
|
|
|
|
exports.typesByVal = [
|
|
'VERSION',
|
|
'VERACK',
|
|
'PING',
|
|
'PONG',
|
|
'GETADDR',
|
|
'ADDR',
|
|
'INV',
|
|
'GETDATA',
|
|
'NOTFOUND',
|
|
'GETBLOCKS',
|
|
'GETHEADERS',
|
|
'HEADERS',
|
|
'SENDHEADERS',
|
|
'BLOCK',
|
|
'TX',
|
|
'REJECT',
|
|
'MEMPOOL',
|
|
'FILTERLOAD',
|
|
'FILTERADD',
|
|
'FILTERCLEAR',
|
|
'MERKLEBLOCK',
|
|
'FEEFILTER',
|
|
'SENDCMPCT',
|
|
'CMPCTBLOCK',
|
|
'GETBLOCKTXN',
|
|
'BLOCKTXN',
|
|
'UNKNOWN',
|
|
// Internal
|
|
'INTERNAL',
|
|
'DATA'
|
|
];
|
|
|
|
/**
|
|
* Base Packet
|
|
*/
|
|
|
|
class Packet {
|
|
/**
|
|
* Create a base packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor() {
|
|
this.type = -1;
|
|
this.cmd = '';
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Serialize packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return DUMMY;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Version Packet
|
|
* @extends Packet
|
|
* @property {Number} version - Protocol version.
|
|
* @property {Number} services - Service bits.
|
|
* @property {Number} time - Timestamp of discovery.
|
|
* @property {NetAddress} local - Our address.
|
|
* @property {NetAddress} remote - Their address.
|
|
* @property {Buffer} nonce
|
|
* @property {String} agent - User agent string.
|
|
* @property {Number} height - Chain height.
|
|
* @property {Boolean} noRelay - Whether transactions
|
|
* should be relayed immediately.
|
|
*/
|
|
|
|
class VersionPacket extends Packet {
|
|
/**
|
|
* Create a version packet.
|
|
* @constructor
|
|
* @param {Object?} options
|
|
* @param {Number} options.version - Protocol version.
|
|
* @param {Number} options.services - Service bits.
|
|
* @param {Number} options.time - Timestamp of discovery.
|
|
* @param {NetAddress} options.local - Our address.
|
|
* @param {NetAddress} options.remote - Their address.
|
|
* @param {Buffer} options.nonce
|
|
* @param {String} options.agent - User agent string.
|
|
* @param {Number} options.height - Chain height.
|
|
* @param {Boolean} options.noRelay - Whether transactions
|
|
* should be relayed immediately.
|
|
*/
|
|
|
|
constructor(options) {
|
|
super();
|
|
|
|
this.cmd = 'version';
|
|
this.type = exports.types.VERSION;
|
|
|
|
this.version = common.PROTOCOL_VERSION;
|
|
this.services = common.LOCAL_SERVICES;
|
|
this.time = util.now();
|
|
this.remote = new NetAddress();
|
|
this.local = new NetAddress();
|
|
this.nonce = common.ZERO_NONCE;
|
|
this.agent = common.USER_AGENT;
|
|
this.height = 0;
|
|
this.noRelay = false;
|
|
|
|
if (options)
|
|
this.fromOptions(options);
|
|
}
|
|
|
|
/**
|
|
* Inject properties from options.
|
|
* @private
|
|
* @param {Object} options
|
|
*/
|
|
|
|
fromOptions(options) {
|
|
if (options.version != null)
|
|
this.version = options.version;
|
|
|
|
if (options.services != null)
|
|
this.services = options.services;
|
|
|
|
if (options.time != null)
|
|
this.time = options.time;
|
|
|
|
if (options.remote)
|
|
this.remote.fromOptions(options.remote);
|
|
|
|
if (options.local)
|
|
this.local.fromOptions(options.local);
|
|
|
|
if (options.nonce)
|
|
this.nonce = options.nonce;
|
|
|
|
if (options.agent)
|
|
this.agent = options.agent;
|
|
|
|
if (options.height != null)
|
|
this.height = options.height;
|
|
|
|
if (options.noRelay != null)
|
|
this.noRelay = options.noRelay;
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate version packet from options.
|
|
* @param {Object} options
|
|
* @returns {VersionPacket}
|
|
*/
|
|
|
|
static fromOptions(options) {
|
|
return new this().fromOptions(options);
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
let size = 0;
|
|
size += 20;
|
|
size += this.remote.getSize(false);
|
|
size += this.local.getSize(false);
|
|
size += 8;
|
|
size += encoding.sizeVarString(this.agent, 'ascii');
|
|
size += 5;
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Write version packet to buffer writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeI32(this.version);
|
|
bw.writeU32(this.services);
|
|
bw.writeU32(0);
|
|
bw.writeI64(this.time);
|
|
this.remote.toWriter(bw, false);
|
|
this.local.toWriter(bw, false);
|
|
bw.writeBytes(this.nonce);
|
|
bw.writeVarString(this.agent, 'ascii');
|
|
bw.writeI32(this.height);
|
|
bw.writeU8(this.noRelay ? 0 : 1);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize version packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.version = br.readI32();
|
|
this.services = br.readU32();
|
|
|
|
// Note: hi service bits
|
|
// are currently unused.
|
|
br.readU32();
|
|
|
|
this.time = br.readI64();
|
|
this.remote.fromReader(br, false);
|
|
|
|
if (br.left() > 0) {
|
|
this.local.fromReader(br, false);
|
|
this.nonce = br.readBytes(8);
|
|
}
|
|
|
|
if (br.left() > 0)
|
|
this.agent = br.readVarString('ascii', 256);
|
|
|
|
if (br.left() > 0)
|
|
this.height = br.readI32();
|
|
|
|
if (br.left() > 0)
|
|
this.noRelay = br.readU8() === 0;
|
|
|
|
if (this.version === 10300)
|
|
this.version = 300;
|
|
|
|
assert(this.version >= 0, 'Version is negative.');
|
|
assert(this.time >= 0, 'Timestamp is negative.');
|
|
|
|
// No idea why so many peers do this.
|
|
if (this.height < 0)
|
|
this.height = 0;
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate version packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {VersionPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate version packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {VersionPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data, enc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verack Packet
|
|
* @extends Packet
|
|
*/
|
|
|
|
class VerackPacket extends Packet {
|
|
/**
|
|
* Create a `verack` packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor() {
|
|
super();
|
|
this.cmd = 'verack';
|
|
this.type = exports.types.VERACK;
|
|
}
|
|
|
|
/**
|
|
* Instantiate verack packet from serialized data.
|
|
* @param {BufferReader} br
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate verack packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ping Packet
|
|
* @extends Packet
|
|
* @property {BN|null} nonce
|
|
*/
|
|
|
|
class PingPacket extends Packet {
|
|
/**
|
|
* Create a `ping` packet.
|
|
* @constructor
|
|
* @param {BN?} nonce
|
|
*/
|
|
|
|
constructor(nonce) {
|
|
super();
|
|
|
|
this.cmd = 'ping';
|
|
this.type = exports.types.PING;
|
|
|
|
this.nonce = nonce || null;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return this.nonce ? 8 : 0;
|
|
}
|
|
|
|
/**
|
|
* Serialize ping packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Serialize ping packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
if (this.nonce)
|
|
bw.writeBytes(this.nonce);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
if (br.left() >= 8)
|
|
this.nonce = br.readBytes(8);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate ping packet from serialized data.
|
|
* @param {BufferReader} br
|
|
* @returns {PingPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromRaw(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate ping packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {PingPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pong Packet
|
|
* @extends Packet
|
|
* @property {BN} nonce
|
|
*/
|
|
|
|
class PongPacket extends Packet {
|
|
/**
|
|
* Create a `pong` packet.
|
|
* @constructor
|
|
* @param {BN?} nonce
|
|
*/
|
|
|
|
constructor(nonce) {
|
|
super();
|
|
|
|
this.cmd = 'pong';
|
|
this.type = exports.types.PONG;
|
|
|
|
this.nonce = nonce || common.ZERO_NONCE;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return 8;
|
|
}
|
|
|
|
/**
|
|
* Serialize pong packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeBytes(this.nonce);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize pong packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.toWriter(bio.write(8)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.nonce = br.readBytes(8);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate pong packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate pong packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GetAddr Packet
|
|
* @extends Packet
|
|
*/
|
|
|
|
class GetAddrPacket extends Packet {
|
|
/**
|
|
* Create a `getaddr` packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor() {
|
|
super();
|
|
this.cmd = 'getaddr';
|
|
this.type = exports.types.GETADDR;
|
|
}
|
|
|
|
/**
|
|
* Instantiate getaddr packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {GetAddrPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate getaddr packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {GetAddrPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Addr Packet
|
|
* @extends Packet
|
|
* @property {NetAddress[]} items
|
|
*/
|
|
|
|
class AddrPacket extends Packet {
|
|
/**
|
|
* Create a `addr` packet.
|
|
* @constructor
|
|
* @param {(NetAddress[])?} items
|
|
*/
|
|
|
|
constructor(items) {
|
|
super();
|
|
|
|
this.cmd = 'addr';
|
|
this.type = exports.types.ADDR;
|
|
|
|
this.items = items || [];
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
let size = 0;
|
|
size += encoding.sizeVarint(this.items.length);
|
|
size += 30 * this.items.length;
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Serialize addr packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeVarint(this.items.length);
|
|
|
|
for (const item of this.items)
|
|
item.toWriter(bw, true);
|
|
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize addr packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
const br = bio.read(data);
|
|
const count = br.readVarint();
|
|
|
|
for (let i = 0; i < count; i++)
|
|
this.items.push(NetAddress.fromReader(br, true));
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate addr packet from Buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {AddrPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate addr packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {AddrPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inv Packet
|
|
* @extends Packet
|
|
* @property {InvItem[]} items
|
|
*/
|
|
|
|
class InvPacket extends Packet {
|
|
/**
|
|
* Create a `inv` packet.
|
|
* @constructor
|
|
* @param {(InvItem[])?} items
|
|
*/
|
|
|
|
constructor(items) {
|
|
super();
|
|
|
|
this.cmd = 'inv';
|
|
this.type = exports.types.INV;
|
|
|
|
this.items = items || [];
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
let size = 0;
|
|
size += encoding.sizeVarint(this.items.length);
|
|
size += 36 * this.items.length;
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Serialize inv packet to writer.
|
|
* @param {Buffer} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
assert(this.items.length <= common.MAX_INV);
|
|
|
|
bw.writeVarint(this.items.length);
|
|
|
|
for (const item of this.items)
|
|
item.toWriter(bw);
|
|
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize inv packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
const count = br.readVarint();
|
|
|
|
assert(count <= common.MAX_INV, 'Inv item count too high.');
|
|
|
|
for (let i = 0; i < count; i++)
|
|
this.items.push(InvItem.fromReader(br));
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate inv packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {InvPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromRaw(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate inv packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {InvPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GetData Packet
|
|
* @extends InvPacket
|
|
*/
|
|
|
|
class GetDataPacket extends InvPacket {
|
|
/**
|
|
* Create a `getdata` packet.
|
|
* @constructor
|
|
* @param {(InvItem[])?} items
|
|
*/
|
|
|
|
constructor(items) {
|
|
super(items);
|
|
this.cmd = 'getdata';
|
|
this.type = exports.types.GETDATA;
|
|
}
|
|
|
|
/**
|
|
* Instantiate getdata packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {GetDataPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate getdata packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {GetDataPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* NotFound Packet
|
|
* @extends InvPacket
|
|
*/
|
|
|
|
class NotFoundPacket extends InvPacket {
|
|
/**
|
|
* Create a `notfound` packet.
|
|
* @constructor
|
|
* @param {(InvItem[])?} items
|
|
*/
|
|
|
|
constructor(items) {
|
|
super(items);
|
|
this.cmd = 'notfound';
|
|
this.type = exports.types.NOTFOUND;
|
|
}
|
|
|
|
/**
|
|
* Instantiate notfound packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {NotFoundPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate notfound packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {NotFoundPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GetBlocks Packet
|
|
* @extends Packet
|
|
* @property {Hash[]} locator
|
|
* @property {Hash|null} stop
|
|
*/
|
|
|
|
class GetBlocksPacket extends Packet {
|
|
/**
|
|
* Create a `getblocks` packet.
|
|
* @constructor
|
|
* @param {Hash[]} locator
|
|
* @param {Hash?} stop
|
|
*/
|
|
|
|
constructor(locator, stop) {
|
|
super();
|
|
|
|
this.cmd = 'getblocks';
|
|
this.type = exports.types.GETBLOCKS;
|
|
|
|
this.version = common.PROTOCOL_VERSION;
|
|
this.locator = locator || [];
|
|
this.stop = stop || null;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
let size = 0;
|
|
size += 4;
|
|
size += encoding.sizeVarint(this.locator.length);
|
|
size += 32 * this.locator.length;
|
|
size += 32;
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Serialize getblocks packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
assert(this.locator.length <= common.MAX_INV, 'Too many block hashes.');
|
|
|
|
bw.writeU32(this.version);
|
|
bw.writeVarint(this.locator.length);
|
|
|
|
for (const hash of this.locator)
|
|
bw.writeHash(hash);
|
|
|
|
bw.writeHash(this.stop || consensus.ZERO_HASH);
|
|
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize getblocks packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.version = br.readU32();
|
|
|
|
const count = br.readVarint();
|
|
|
|
assert(count <= common.MAX_INV, 'Too many block hashes.');
|
|
|
|
for (let i = 0; i < count; i++)
|
|
this.locator.push(br.readHash());
|
|
|
|
this.stop = br.readHash();
|
|
|
|
if (this.stop.equals(consensus.ZERO_HASH))
|
|
this.stop = null;
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate getblocks packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {GetBlocksPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GetHeader Packets
|
|
* @extends GetBlocksPacket
|
|
*/
|
|
|
|
class GetHeadersPacket extends GetBlocksPacket {
|
|
/**
|
|
* Create a `getheaders` packet.
|
|
* @constructor
|
|
* @param {Hash[]} locator
|
|
* @param {Hash?} stop
|
|
*/
|
|
|
|
constructor(locator, stop) {
|
|
super(locator, stop);
|
|
this.cmd = 'getheaders';
|
|
this.type = exports.types.GETHEADERS;
|
|
}
|
|
|
|
/**
|
|
* Instantiate getheaders packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {GetHeadersPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate getheaders packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {GetHeadersPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Headers Packet
|
|
* @extends Packet
|
|
* @property {Headers[]} items
|
|
*/
|
|
|
|
class HeadersPacket extends Packet {
|
|
/**
|
|
* Create a `headers` packet.
|
|
* @constructor
|
|
* @param {(Headers[])?} items
|
|
*/
|
|
|
|
constructor(items) {
|
|
super();
|
|
|
|
this.cmd = 'headers';
|
|
this.type = exports.types.HEADERS;
|
|
|
|
this.items = items || [];
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
let size = 0;
|
|
|
|
size += encoding.sizeVarint(this.items.length);
|
|
|
|
for (const item of this.items)
|
|
size += item.getSize();
|
|
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Serialize headers packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
assert(this.items.length <= 2000, 'Too many headers.');
|
|
|
|
bw.writeVarint(this.items.length);
|
|
|
|
for (const item of this.items)
|
|
item.toWriter(bw);
|
|
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize headers packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
const count = br.readVarint();
|
|
|
|
assert(count <= 2000, 'Too many headers.');
|
|
|
|
for (let i = 0; i < count; i++)
|
|
this.items.push(Headers.fromReader(br));
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate headers packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* SendHeaders Packet
|
|
* @extends Packet
|
|
*/
|
|
|
|
class SendHeadersPacket extends Packet {
|
|
/**
|
|
* Create a `sendheaders` packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor() {
|
|
super();
|
|
this.cmd = 'sendheaders';
|
|
this.type = exports.types.SENDHEADERS;
|
|
}
|
|
|
|
/**
|
|
* Instantiate sendheaders packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {SendHeadersPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate sendheaders packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {SendHeadersPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Block Packet
|
|
* @extends Packet
|
|
* @property {Block} block
|
|
* @property {Boolean} witness
|
|
*/
|
|
|
|
class BlockPacket extends Packet {
|
|
/**
|
|
* Create a `block` packet.
|
|
* @constructor
|
|
* @param {Block|null} block
|
|
* @param {Boolean?} witness
|
|
*/
|
|
|
|
constructor(block, witness) {
|
|
super();
|
|
|
|
this.cmd = 'block';
|
|
this.type = exports.types.BLOCK;
|
|
|
|
this.block = block || new MemBlock();
|
|
this.witness = witness || false;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
if (this.witness)
|
|
return this.block.getSize();
|
|
return this.block.getBaseSize();
|
|
}
|
|
|
|
/**
|
|
* Serialize block packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
if (this.witness)
|
|
return this.block.toWriter(bw);
|
|
return this.block.toNormalWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize block packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
if (this.witness)
|
|
return this.block.toRaw();
|
|
return this.block.toNormal();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.block.fromReader(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.block.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate block packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {BlockPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate block packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {BlockPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TX Packet
|
|
* @extends Packet
|
|
* @property {TX} block
|
|
* @property {Boolean} witness
|
|
*/
|
|
|
|
class TXPacket extends Packet {
|
|
/**
|
|
* Create a `tx` packet.
|
|
* @constructor
|
|
* @param {TX|null} tx
|
|
* @param {Boolean?} witness
|
|
*/
|
|
|
|
constructor(tx, witness) {
|
|
super();
|
|
|
|
this.cmd = 'tx';
|
|
this.type = exports.types.TX;
|
|
|
|
this.tx = tx || new TX();
|
|
this.witness = witness || false;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
if (this.witness)
|
|
return this.tx.getSize();
|
|
return this.tx.getBaseSize();
|
|
}
|
|
|
|
/**
|
|
* Serialize tx packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
if (this.witness)
|
|
return this.tx.toWriter(bw);
|
|
return this.tx.toNormalWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize tx packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
if (this.witness)
|
|
return this.tx.toRaw();
|
|
return this.tx.toNormal();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.tx.fromRaw(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.tx.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate tx packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {TXPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate tx packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {TXPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reject Packet
|
|
* @extends Packet
|
|
* @property {(Number|String)?} code - Code
|
|
* (see {@link RejectPacket.codes}).
|
|
* @property {String?} msg - Message.
|
|
* @property {String?} reason - Reason.
|
|
* @property {(Hash|Buffer)?} data - Transaction or block hash.
|
|
*/
|
|
|
|
class RejectPacket extends Packet {
|
|
/**
|
|
* Create reject packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor(options) {
|
|
super();
|
|
|
|
this.cmd = 'reject';
|
|
this.type = exports.types.REJECT;
|
|
|
|
this.message = '';
|
|
this.code = RejectPacket.codes.INVALID;
|
|
this.reason = '';
|
|
this.hash = null;
|
|
|
|
if (options)
|
|
this.fromOptions(options);
|
|
}
|
|
|
|
/**
|
|
* Inject properties from options object.
|
|
* @private
|
|
* @param {Object} options
|
|
*/
|
|
|
|
fromOptions(options) {
|
|
let code = options.code;
|
|
|
|
if (options.message)
|
|
this.message = options.message;
|
|
|
|
if (code != null) {
|
|
if (typeof code === 'string')
|
|
code = RejectPacket.codes[code.toUpperCase()];
|
|
|
|
if (code >= RejectPacket.codes.INTERNAL)
|
|
code = RejectPacket.codes.INVALID;
|
|
|
|
this.code = code;
|
|
}
|
|
|
|
if (options.reason)
|
|
this.reason = options.reason;
|
|
|
|
if (options.hash)
|
|
this.hash = options.hash;
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate reject packet from options.
|
|
* @param {Object} options
|
|
* @returns {RejectPacket}
|
|
*/
|
|
|
|
static fromOptions(options) {
|
|
return new this().fromOptions(options);
|
|
}
|
|
|
|
/**
|
|
* Get uint256le hash if present.
|
|
* @returns {Hash}
|
|
*/
|
|
|
|
rhash() {
|
|
return this.hash ? util.revHex(this.hash) : null;
|
|
}
|
|
|
|
/**
|
|
* Get symbolic code.
|
|
* @returns {String}
|
|
*/
|
|
|
|
getCode() {
|
|
const code = RejectPacket.codesByVal[this.code];
|
|
|
|
if (!code)
|
|
return this.code.toString(10);
|
|
|
|
return code.toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
let size = 0;
|
|
|
|
size += encoding.sizeVarString(this.message, 'ascii');
|
|
size += 1;
|
|
size += encoding.sizeVarString(this.reason, 'ascii');
|
|
|
|
if (this.hash)
|
|
size += 32;
|
|
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Serialize reject packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
assert(this.message.length <= 12);
|
|
assert(this.reason.length <= 111);
|
|
|
|
bw.writeVarString(this.message, 'ascii');
|
|
bw.writeU8(this.code);
|
|
bw.writeVarString(this.reason, 'ascii');
|
|
|
|
if (this.hash)
|
|
bw.writeHash(this.hash);
|
|
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize reject packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.message = br.readVarString('ascii', 12);
|
|
this.code = br.readU8();
|
|
this.reason = br.readVarString('ascii', 111);
|
|
|
|
switch (this.message) {
|
|
case 'block':
|
|
case 'tx':
|
|
this.hash = br.readHash();
|
|
break;
|
|
default:
|
|
this.hash = null;
|
|
break;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate reject packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {RejectPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate reject packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {RejectPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data, enc);
|
|
}
|
|
|
|
/**
|
|
* Inject properties from reason message and object.
|
|
* @private
|
|
* @param {Number} code
|
|
* @param {String} reason
|
|
* @param {String?} msg
|
|
* @param {Hash?} hash
|
|
*/
|
|
|
|
fromReason(code, reason, msg, hash) {
|
|
if (typeof code === 'string')
|
|
code = RejectPacket.codes[code.toUpperCase()];
|
|
|
|
if (!code)
|
|
code = RejectPacket.codes.INVALID;
|
|
|
|
if (code >= RejectPacket.codes.INTERNAL)
|
|
code = RejectPacket.codes.INVALID;
|
|
|
|
this.message = '';
|
|
this.code = code;
|
|
this.reason = reason;
|
|
|
|
if (msg) {
|
|
assert(hash);
|
|
this.message = msg;
|
|
this.hash = hash;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate reject packet from reason message.
|
|
* @param {Number} code
|
|
* @param {String} reason
|
|
* @param {String?} msg
|
|
* @param {Hash?} hash
|
|
* @returns {RejectPacket}
|
|
*/
|
|
|
|
static fromReason(code, reason, msg, hash) {
|
|
return new this().fromReason(code, reason, msg, hash);
|
|
}
|
|
|
|
/**
|
|
* Instantiate reject packet from verify error.
|
|
* @param {VerifyError} err
|
|
* @param {(TX|Block)?} obj
|
|
* @returns {RejectPacket}
|
|
*/
|
|
|
|
static fromError(err, obj) {
|
|
return this.fromReason(err.code, err.reason, obj);
|
|
}
|
|
|
|
/**
|
|
* Inspect reject packet.
|
|
* @returns {String}
|
|
*/
|
|
|
|
inspect() {
|
|
const code = RejectPacket.codesByVal[this.code] || this.code;
|
|
const hash = this.hash ? util.revHex(this.hash) : null;
|
|
return '<Reject:'
|
|
+ ` msg=${this.message}`
|
|
+ ` code=${code}`
|
|
+ ` reason=${this.reason}`
|
|
+ ` hash=${hash}`
|
|
+ '>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reject codes. Note that `internal` and higher
|
|
* are not meant for use on the p2p network.
|
|
* @enum {Number}
|
|
* @default
|
|
*/
|
|
|
|
RejectPacket.codes = {
|
|
MALFORMED: 0x01,
|
|
INVALID: 0x10,
|
|
OBSOLETE: 0x11,
|
|
DUPLICATE: 0x12,
|
|
NONSTANDARD: 0x40,
|
|
DUST: 0x41,
|
|
INSUFFICIENTFEE: 0x42,
|
|
CHECKPOINT: 0x43,
|
|
// Internal codes (NOT FOR USE ON NETWORK)
|
|
INTERNAL: 0x100,
|
|
HIGHFEE: 0x101,
|
|
ALREADYKNOWN: 0x102,
|
|
CONFLICT: 0x103
|
|
};
|
|
|
|
/**
|
|
* Reject codes by value.
|
|
* @const {Object}
|
|
*/
|
|
|
|
RejectPacket.codesByVal = {
|
|
0x01: 'MALFORMED',
|
|
0x10: 'INVALID',
|
|
0x11: 'OBSOLETE',
|
|
0x12: 'DUPLICATE',
|
|
0x40: 'NONSTANDARD',
|
|
0x41: 'DUST',
|
|
0x42: 'INSUFFICIENTFEE',
|
|
0x43: 'CHECKPOINT',
|
|
// Internal codes (NOT FOR USE ON NETWORK)
|
|
0x100: 'INTERNAL',
|
|
0x101: 'HIGHFEE',
|
|
0x102: 'ALREADYKNOWN',
|
|
0x103: 'CONFLICT'
|
|
};
|
|
|
|
/**
|
|
* Mempool Packet
|
|
* @extends Packet
|
|
*/
|
|
|
|
class MempoolPacket extends Packet {
|
|
/**
|
|
* Create a `mempool` packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor() {
|
|
super();
|
|
this.cmd = 'mempool';
|
|
this.type = exports.types.MEMPOOL;
|
|
}
|
|
|
|
/**
|
|
* Instantiate mempool packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate mempool packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {VerackPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* FilterLoad Packet
|
|
* @extends Packet
|
|
*/
|
|
|
|
class FilterLoadPacket extends Packet {
|
|
/**
|
|
* Create a `filterload` packet.
|
|
* @constructor
|
|
* @param {BloomFilter|null} filter
|
|
*/
|
|
|
|
constructor(filter) {
|
|
super();
|
|
|
|
this.cmd = 'filterload';
|
|
this.type = exports.types.FILTERLOAD;
|
|
|
|
this.filter = filter || new BloomFilter();
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return this.filter.getSize();
|
|
}
|
|
|
|
/**
|
|
* Serialize filterload packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
return this.filter.toWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize filterload packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.filter.toRaw();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.filter.fromReader(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.filter.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate filterload packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {FilterLoadPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate filterload packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {FilterLoadPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
|
|
/**
|
|
* Ensure the filter is within the size limits.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
isWithinConstraints() {
|
|
return this.filter.isWithinConstraints();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* FilterAdd Packet
|
|
* @extends Packet
|
|
* @property {Buffer} data
|
|
*/
|
|
|
|
class FilterAddPacket extends Packet {
|
|
/**
|
|
* Create a `filteradd` packet.
|
|
* @constructor
|
|
* @param {Buffer?} data
|
|
*/
|
|
|
|
constructor(data) {
|
|
super();
|
|
|
|
this.cmd = 'filteradd';
|
|
this.type = exports.types.FILTERADD;
|
|
|
|
this.data = data || DUMMY;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return encoding.sizeVarBytes(this.data);
|
|
}
|
|
|
|
/**
|
|
* Serialize filteradd packet to writer.
|
|
* @returns {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeVarBytes(this.data);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize filteradd packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
const size = this.getSize();
|
|
return this.toWriter(bio.write(size)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.data = br.readVarBytes();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate filteradd packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {FilterAddPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* FilterClear Packet
|
|
* @extends Packet
|
|
*/
|
|
|
|
class FilterClearPacket extends Packet {
|
|
/**
|
|
* Create a `filterclear` packet.
|
|
* @constructor
|
|
*/
|
|
|
|
constructor() {
|
|
super();
|
|
this.cmd = 'filterclear';
|
|
this.type = exports.types.FILTERCLEAR;
|
|
}
|
|
|
|
/**
|
|
* Instantiate filterclear packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {FilterClearPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MerkleBlock Packet
|
|
* @extends Packet
|
|
* @property {MerkleBlock} block
|
|
*/
|
|
|
|
class MerkleBlockPacket extends Packet {
|
|
/**
|
|
* Create a `merkleblock` packet.
|
|
* @constructor
|
|
* @param {MerkleBlock?} block
|
|
*/
|
|
|
|
constructor(block) {
|
|
super();
|
|
|
|
this.cmd = 'merkleblock';
|
|
this.type = exports.types.MERKLEBLOCK;
|
|
|
|
this.block = block || new MerkleBlock();
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return this.block.getSize();
|
|
}
|
|
|
|
/**
|
|
* Serialize merkleblock packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
return this.block.toWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize merkleblock packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.block.toRaw();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.block.fromReader(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.block.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate merkleblock packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {MerkleBlockPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* FeeFilter Packet
|
|
* @extends Packet
|
|
* @property {Rate} rate
|
|
*/
|
|
|
|
class FeeFilterPacket extends Packet {
|
|
/**
|
|
* Create a `feefilter` packet.
|
|
* @constructor
|
|
* @param {Rate?} rate
|
|
*/
|
|
|
|
constructor(rate) {
|
|
super();
|
|
|
|
this.cmd = 'feefilter';
|
|
this.type = exports.types.FEEFILTER;
|
|
|
|
this.rate = rate || 0;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return 8;
|
|
}
|
|
|
|
/**
|
|
* Serialize feefilter packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeI64(this.rate);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize feefilter packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.toWriter(bio.write(8)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.rate = br.readI64();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate feefilter packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {FeeFilterPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate feefilter packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {FeeFilterPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* SendCmpct Packet
|
|
* @extends Packet
|
|
* @property {Number} mode
|
|
* @property {Number} version
|
|
*/
|
|
|
|
class SendCmpctPacket extends Packet {
|
|
/**
|
|
* Create a `sendcmpct` packet.
|
|
* @constructor
|
|
* @param {Number|null} mode
|
|
* @param {Number|null} version
|
|
*/
|
|
|
|
constructor(mode, version) {
|
|
super();
|
|
|
|
this.cmd = 'sendcmpct';
|
|
this.type = exports.types.SENDCMPCT;
|
|
|
|
this.mode = mode || 0;
|
|
this.version = version || 1;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return 9;
|
|
}
|
|
|
|
/**
|
|
* Serialize sendcmpct packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeU8(this.mode);
|
|
bw.writeU64(this.version);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize sendcmpct packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.toWriter(bio.write(9)).render();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.mode = br.readU8();
|
|
this.version = br.readU64();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
return this.fromReader(bio.read(data));
|
|
}
|
|
|
|
/**
|
|
* Instantiate sendcmpct packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {SendCmpctPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate sendcmpct packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {SendCmpctPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* CmpctBlock Packet
|
|
* @extends Packet
|
|
* @property {Block} block
|
|
* @property {Boolean} witness
|
|
*/
|
|
|
|
class CmpctBlockPacket extends Packet {
|
|
/**
|
|
* Create a `cmpctblock` packet.
|
|
* @constructor
|
|
* @param {Block|null} block
|
|
* @param {Boolean|null} witness
|
|
*/
|
|
|
|
constructor(block, witness) {
|
|
super();
|
|
|
|
this.cmd = 'cmpctblock';
|
|
this.type = exports.types.CMPCTBLOCK;
|
|
|
|
this.block = block || new bip152.CompactBlock();
|
|
this.witness = witness || false;
|
|
}
|
|
|
|
/**
|
|
* Serialize cmpctblock packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
getSize() {
|
|
if (this.witness)
|
|
return this.block.getSize(true);
|
|
return this.block.getSize(false);
|
|
}
|
|
|
|
/**
|
|
* Serialize cmpctblock packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
if (this.witness)
|
|
return this.block.toWriter(bw);
|
|
return this.block.toNormalWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize cmpctblock packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
if (this.witness)
|
|
return this.block.toRaw();
|
|
return this.block.toNormal();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.block.fromReader(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.block.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate cmpctblock packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {CmpctBlockPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromRaw(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate cmpctblock packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {CmpctBlockPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GetBlockTxn Packet
|
|
* @extends Packet
|
|
* @property {TXRequest} request
|
|
*/
|
|
|
|
class GetBlockTxnPacket extends Packet {
|
|
/**
|
|
* Create a `getblocktxn` packet.
|
|
* @constructor
|
|
* @param {TXRequest?} request
|
|
*/
|
|
|
|
constructor(request) {
|
|
super();
|
|
|
|
this.cmd = 'getblocktxn';
|
|
this.type = exports.types.GETBLOCKTXN;
|
|
|
|
this.request = request || new bip152.TXRequest();
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return this.request.getSize();
|
|
}
|
|
|
|
/**
|
|
* Serialize getblocktxn packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
return this.request.toWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize getblocktxn packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.request.toRaw();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.request.fromReader(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.request.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate getblocktxn packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {GetBlockTxnPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate getblocktxn packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {GetBlockTxnPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* BlockTxn Packet
|
|
* @extends Packet
|
|
* @property {TXResponse} response
|
|
* @property {Boolean} witness
|
|
*/
|
|
|
|
class BlockTxnPacket extends Packet {
|
|
/**
|
|
* Create a `blocktxn` packet.
|
|
* @constructor
|
|
* @param {TXResponse?} response
|
|
* @param {Boolean?} witness
|
|
*/
|
|
|
|
constructor(response, witness) {
|
|
super();
|
|
|
|
this.cmd = 'blocktxn';
|
|
this.type = exports.types.BLOCKTXN;
|
|
|
|
this.response = response || new bip152.TXResponse();
|
|
this.witness = witness || false;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
if (this.witness)
|
|
return this.response.getSize(true);
|
|
return this.response.getSize(false);
|
|
}
|
|
|
|
/**
|
|
* Serialize blocktxn packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
if (this.witness)
|
|
return this.response.toWriter(bw);
|
|
return this.response.toNormalWriter(bw);
|
|
}
|
|
|
|
/**
|
|
* Serialize blocktxn packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
if (this.witness)
|
|
return this.response.toRaw();
|
|
return this.response.toNormal();
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @private
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
fromReader(br) {
|
|
this.response.fromReader(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(data) {
|
|
this.response.fromRaw(data);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate blocktxn packet from buffer reader.
|
|
* @param {BufferReader} br
|
|
* @returns {BlockTxnPacket}
|
|
*/
|
|
|
|
static fromReader(br) {
|
|
return new this().fromReader(br);
|
|
}
|
|
|
|
/**
|
|
* Instantiate blocktxn packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {BlockTxnPacket}
|
|
*/
|
|
|
|
static fromRaw(data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unknown Packet
|
|
* @extends Packet
|
|
* @property {String} cmd
|
|
* @property {Buffer} data
|
|
*/
|
|
|
|
class UnknownPacket extends Packet {
|
|
/**
|
|
* Create an unknown packet.
|
|
* @constructor
|
|
* @param {String|null} cmd
|
|
* @param {Buffer|null} data
|
|
*/
|
|
|
|
constructor(cmd, data) {
|
|
super();
|
|
|
|
this.cmd = cmd;
|
|
this.type = exports.types.UNKNOWN;
|
|
this.data = data;
|
|
}
|
|
|
|
/**
|
|
* Get serialization size.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
return this.data.length;
|
|
}
|
|
|
|
/**
|
|
* Serialize unknown packet to writer.
|
|
* @param {BufferWriter} bw
|
|
*/
|
|
|
|
toWriter(bw) {
|
|
bw.writeBytes(this.data);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Serialize unknown packet.
|
|
* @returns {Buffer}
|
|
*/
|
|
|
|
toRaw() {
|
|
return this.data;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from serialized data.
|
|
* @private
|
|
* @param {Buffer} data
|
|
*/
|
|
|
|
fromRaw(cmd, data) {
|
|
assert(Buffer.isBuffer(data));
|
|
this.cmd = cmd;
|
|
this.data = data;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate unknown packet from serialized data.
|
|
* @param {Buffer} data
|
|
* @param {String?} enc
|
|
* @returns {UnknownPacket}
|
|
*/
|
|
|
|
static fromRaw(cmd, data, enc) {
|
|
if (typeof data === 'string')
|
|
data = Buffer.from(data, enc);
|
|
return new this().fromRaw(cmd, data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parse a payload.
|
|
* @param {String} cmd
|
|
* @param {Buffer} data
|
|
* @returns {Packet}
|
|
*/
|
|
|
|
exports.fromRaw = function fromRaw(cmd, data) {
|
|
switch (cmd) {
|
|
case 'version':
|
|
return VersionPacket.fromRaw(data);
|
|
case 'verack':
|
|
return VerackPacket.fromRaw(data);
|
|
case 'ping':
|
|
return PingPacket.fromRaw(data);
|
|
case 'pong':
|
|
return PongPacket.fromRaw(data);
|
|
case 'getaddr':
|
|
return GetAddrPacket.fromRaw(data);
|
|
case 'addr':
|
|
return AddrPacket.fromRaw(data);
|
|
case 'inv':
|
|
return InvPacket.fromRaw(data);
|
|
case 'getdata':
|
|
return GetDataPacket.fromRaw(data);
|
|
case 'notfound':
|
|
return NotFoundPacket.fromRaw(data);
|
|
case 'getblocks':
|
|
return GetBlocksPacket.fromRaw(data);
|
|
case 'getheaders':
|
|
return GetHeadersPacket.fromRaw(data);
|
|
case 'headers':
|
|
return HeadersPacket.fromRaw(data);
|
|
case 'sendheaders':
|
|
return SendHeadersPacket.fromRaw(data);
|
|
case 'block':
|
|
return BlockPacket.fromRaw(data);
|
|
case 'tx':
|
|
return TXPacket.fromRaw(data);
|
|
case 'reject':
|
|
return RejectPacket.fromRaw(data);
|
|
case 'mempool':
|
|
return MempoolPacket.fromRaw(data);
|
|
case 'filterload':
|
|
return FilterLoadPacket.fromRaw(data);
|
|
case 'filteradd':
|
|
return FilterAddPacket.fromRaw(data);
|
|
case 'filterclear':
|
|
return FilterClearPacket.fromRaw(data);
|
|
case 'merkleblock':
|
|
return MerkleBlockPacket.fromRaw(data);
|
|
case 'feefilter':
|
|
return FeeFilterPacket.fromRaw(data);
|
|
case 'sendcmpct':
|
|
return SendCmpctPacket.fromRaw(data);
|
|
case 'cmpctblock':
|
|
return CmpctBlockPacket.fromRaw(data);
|
|
case 'getblocktxn':
|
|
return GetBlockTxnPacket.fromRaw(data);
|
|
case 'blocktxn':
|
|
return BlockTxnPacket.fromRaw(data);
|
|
default:
|
|
return UnknownPacket.fromRaw(cmd, data);
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Expose
|
|
*/
|
|
|
|
exports.Packet = Packet;
|
|
exports.VersionPacket = VersionPacket;
|
|
exports.VerackPacket = VerackPacket;
|
|
exports.PingPacket = PingPacket;
|
|
exports.PongPacket = PongPacket;
|
|
exports.GetAddrPacket = GetAddrPacket;
|
|
exports.AddrPacket = AddrPacket;
|
|
exports.InvPacket = InvPacket;
|
|
exports.GetDataPacket = GetDataPacket;
|
|
exports.NotFoundPacket = NotFoundPacket;
|
|
exports.GetBlocksPacket = GetBlocksPacket;
|
|
exports.GetHeadersPacket = GetHeadersPacket;
|
|
exports.HeadersPacket = HeadersPacket;
|
|
exports.SendHeadersPacket = SendHeadersPacket;
|
|
exports.BlockPacket = BlockPacket;
|
|
exports.TXPacket = TXPacket;
|
|
exports.RejectPacket = RejectPacket;
|
|
exports.MempoolPacket = MempoolPacket;
|
|
exports.FilterLoadPacket = FilterLoadPacket;
|
|
exports.FilterAddPacket = FilterAddPacket;
|
|
exports.FilterClearPacket = FilterClearPacket;
|
|
exports.MerkleBlockPacket = MerkleBlockPacket;
|
|
exports.FeeFilterPacket = FeeFilterPacket;
|
|
exports.SendCmpctPacket = SendCmpctPacket;
|
|
exports.CmpctBlockPacket = CmpctBlockPacket;
|
|
exports.GetBlockTxnPacket = GetBlockTxnPacket;
|
|
exports.BlockTxnPacket = BlockTxnPacket;
|
|
exports.UnknownPacket = UnknownPacket;
|