no slices.

This commit is contained in:
Christopher Jeffrey 2016-03-14 13:51:04 -07:00
parent 00dfad25da
commit d0a5ae7aa4

View File

@ -54,7 +54,6 @@ Parser.prototype.feed = function feed(data) {
this.pending.shift();
else
this.pending[0] = this.pending[0].slice(len);
//this.pending[0] = this.pending[0].slice(len);
off += len;
}
@ -154,47 +153,57 @@ Parser.prototype.parsePayload = function parsePayload(cmd, p) {
return p;
};
Parser.parsePing = function parsePing(p) {
if (p.length < 8)
Parser.parsePing = function parsePing(p, off) {
off = off || 0;
if (p.length - off < 8)
throw new Error('pong packet is too small');
return {
nonce: utils.readU64(p, 0)
nonce: utils.readU64(p, off)
};
};
Parser.parsePong = function parsePong(p) {
if (p.length < 8)
Parser.parsePong = function parsePong(p, off) {
off = off || 0;
if (p.length - off < 8)
throw new Error('ping packet is too small');
return {
nonce: utils.readU64(p, 0)
nonce: utils.readU64(p, off)
};
};
Parser.parseVersion = function parseVersion(p) {
Parser.parseVersion = function parseVersion(p, off) {
var v, services, ts, recv, from, nonce, result, off, agent, height, relay;
off = off || 0;
if (p.length < 85)
throw new Error('version packet is too small');
v = utils.readU32(p, 0);
services = utils.readU64(p, 4);
v = utils.readU32(p, off);
off += 4;
services = utils.readU64(p, off);
off += 8;
// Timestamp
ts = utils.read64(p, 12);
ts = utils.read64(p, off);
off += 8;
// Our address (recv)
recv = Parser.parseAddress(p, 20);
recv = Parser.parseAddress(p, off);
off += 26;
// Their Address (from)
from = Parser.parseAddress(p, 46);
from = Parser.parseAddress(p, off);
off += 26;
// Nonce, very dramatic
nonce = utils.readU64(p, 72);
nonce = utils.readU64(p, off);
off += 8;
// User agent length
result = utils.readIntv(p, 80);
result = utils.readIntv(p, off);
off = result.off;
agent = p.toString('ascii', off, off + result.r);
off += result.r;
@ -205,6 +214,8 @@ Parser.parseVersion = function parseVersion(p) {
// Relay
relay = p.length > off ? p[off] === 1 : true;
if (p.length > off)
off += 1;
try {
ts = ts.toNumber();
@ -235,18 +246,19 @@ Parser.parseVersion = function parseVersion(p) {
};
};
Parser.parseInvList = function parseInvList(p) {
Parser.parseInvList = function parseInvList(p, off) {
var items = [];
var i, off, count;
var i, count;
off = off || 0;
count = utils.readIntv(p, 0);
p = p.slice(count.off);
count = utils.readIntv(p, off);
off = count.off;
count = count.r;
if (p.length < count * 36)
throw new Error('Invalid getdata size');
for (i = 0, off = 0; i < count; i++, off += 36) {
for (i = 0; i < count; i++, off += 36) {
items.push({
type: constants.invByVal[utils.readU32(p, off)],
hash: utils.slice(p, off + 4, off + 36)
@ -256,13 +268,30 @@ Parser.parseInvList = function parseInvList(p) {
return items;
};
Parser.parseMerkleBlock = function parseMerkleBlock(p) {
var i, hashCount, off, hashes, flagCount, flags;
Parser.parseMerkleBlock = function parseMerkleBlock(p, off) {
var i, hashCount, hashes, flagCount, flags;
off = off || 0;
var start = off;
if (p.length < 86)
if (p.length - off < 86)
throw new Error('Invalid merkleblock size');
hashCount = utils.readIntv(p, 84);
var version = utils.read32(p, off);
off += 4;
var prevBlock = utils.slice(p, off, off + 32);
off += 32;
var merkleRoot = utils.slice(p, off, off + 32);
off += 32;
var ts = utils.readU32(p, off);
off += 4;
var bits = utils.readU32(p, off);
off += 4;
var nonce = utils.readU32(p, off);
off += 4;
var totalTX = utils.readU32(p, off);
off += 4;
hashCount = utils.readIntv(p, off);
off = hashCount.off;
hashCount = hashCount.r;
@ -285,27 +314,28 @@ Parser.parseMerkleBlock = function parseMerkleBlock(p) {
flags = utils.slice(p, off, off + flagCount);
return {
version: utils.read32(p, 0),
prevBlock: utils.slice(p, 4, 36),
merkleRoot: utils.slice(p, 36, 68),
ts: utils.readU32(p, 68),
bits: utils.readU32(p, 72),
nonce: utils.readU32(p, 76),
totalTX: utils.readU32(p, 80),
version: version,
prevBlock: prevBlock,
merkleRoot: merkleRoot,
ts: ts,
bits: bits,
nonce: nonce,
totalTX: totalTX,
hashes: hashes,
flags: flags,
_size: p.length
_size: off - start
};
};
Parser.parseHeaders = function parseHeaders(p) {
Parser.parseHeaders = function parseHeaders(p, off) {
var headers = [];
var i, result, off, count, header, start, r;
var i, result, count, header, start, r;
off = off || 0;
if (p.length < 81)
if (p.length - off < 81)
throw new Error('Invalid headers size');
result = utils.readIntv(p, 0);
result = utils.readIntv(p, off);
off = result.off;
count = result.r;
@ -336,20 +366,35 @@ Parser.parseHeaders = function parseHeaders(p) {
return headers;
};
Parser.parseBlock = function parseBlock(p) {
Parser.parseBlock = function parseBlock(p, off) {
var txs = [];
var witnessSize = 0;
var i, result, off, totalTX, tx;
off = off || 0;
var start = off;
if (p.length < 81)
if (p.length - off < 81)
throw new Error('Invalid block size');
result = utils.readIntv(p, 80);
var version = utils.read32(p, off);
off += 4;
var prevBlock = utils.slice(p, off, off + 32);
off += 32;
var merkleRoot = utils.slice(p, off, off + 32);
off += 32;
var ts = utils.readU32(p, off);
off += 4;
var bits = utils.readU32(p, off);
off += 4;
var nonce = utils.readU32(p, off);
off += 4;
result = utils.readIntv(p, off);
off = result.off;
totalTX = result.r;
for (i = 0; i < totalTX; i++) {
tx = Parser.parseTX(p.slice(off), true);
tx = Parser.parseTX(p, off);
if (!tx)
throw new Error('Invalid tx count for block');
tx._offset = off;
@ -359,30 +404,43 @@ Parser.parseBlock = function parseBlock(p) {
}
return {
version: utils.read32(p, 0),
prevBlock: utils.slice(p, 4, 36),
merkleRoot: utils.slice(p, 36, 68),
ts: utils.readU32(p, 68),
bits: utils.readU32(p, 72),
nonce: utils.readU32(p, 76),
totalTX: totalTX,
version: version,
prevBlock: prevBlock,
merkleRoot: merkleRoot,
ts: ts,
bits: bits,
nonce: nonce,
txs: txs,
_size: p.length,
_size: off - start,
_witnessSize: witnessSize
};
};
Parser.parseBlockCompact = function parseBlockCompact(p) {
Parser.parseBlockCompact = function parseBlockCompact(p, off) {
var height = -1;
var i, result, off, totalTX, tx;
var inCount, input, s, version;
off = off || 0;
var start = off;
if (p.length < 81)
if (p.length - off < 81)
throw new Error('Invalid block size');
version = utils.read32(p, 0);
version = utils.read32(p, off);
off += 4;
result = utils.readIntv(p, 80);
var prevBlock = utils.slice(p, off, off + 32);
off += 32;
var merkleRoot = utils.slice(p, off, off + 32);
off += 32;
var ts = utils.readU32(p, off);
off += 4;
var bits = utils.readU32(p, off);
off += 4;
var nonce = utils.readU32(p, off);
off += 4;
result = utils.readIntv(p, off);
off = result.off;
totalTX = result.r;
@ -395,7 +453,7 @@ Parser.parseBlockCompact = function parseBlockCompact(p) {
inCount = inCount.r;
if (inCount > 0) {
input = Parser.parseInput(p.slice(off));
input = Parser.parseInput(p, off);
if (!input)
throw new Error('Invalid tx count for block');
}
@ -409,66 +467,87 @@ Parser.parseBlockCompact = function parseBlockCompact(p) {
return {
version: version,
prevBlock: utils.slice(p, 4, 36),
merkleRoot: utils.slice(p, 36, 68),
ts: utils.readU32(p, 68),
bits: utils.readU32(p, 72),
nonce: utils.readU32(p, 76),
prevBlock: prevBlock,
merkleRoot: merkleRoot,
ts: ts,
bits: bits,
nonce: nonce,
totalTX: totalTX,
coinbaseHeight: height,
txs: [],
_raw: p,
_size: p.length
_size: off - start
};
};
Parser.parseInput = function parseInput(p) {
var scriptLen, off;
Parser.parseInput = function parseInput(p, off) {
var scriptLen;
if (p.length < 41)
off = off || 0;
var start = off;
if (p.length - off < 41)
throw new Error('Invalid tx_in size');
scriptLen = utils.readIntv(p, 36);
var hash = utils.slice(p, off, off + 32);
off += 32;
var index = utils.readU32(p, off);
off += 4;
scriptLen = utils.readIntv(p, off);
off = scriptLen.off;
scriptLen = scriptLen.r;
if (off + scriptLen + 4 > p.length)
throw new Error('Invalid tx_in script length');
var script = bcoin.script.decode(utils.slice(p, off, off + scriptLen));
off += scriptLen;
var sequence = utils.readU32(p, off);
off += 4;
return {
_size: off + scriptLen + 4,
_size: off - start,
prevout: {
hash: utils.slice(p, 0, 32),
index: utils.readU32(p, 32)
hash: hash,
index: index
},
script: bcoin.script.decode(utils.slice(p, off, off + scriptLen)),
sequence: utils.readU32(p, off + scriptLen)
script: script,
sequence: sequence
};
};
Parser.parseOutput = function parseOutput(p) {
var scriptLen, off;
Parser.parseOutput = function parseOutput(p, off) {
var scriptLen;
off = off || 0;
var start = off;
if (p.length < 9)
if (p.length - off < 9)
throw new Error('Invalid tx_out size');
scriptLen = utils.readIntv(p, 8);
var value = utils.read64(p, off);
off += 8;
scriptLen = utils.readIntv(p, off);
off = scriptLen.off;
scriptLen = scriptLen.r;
if (off + scriptLen > p.length)
throw new Error('Invalid tx_out script length');
var script = bcoin.script.decode(utils.slice(p, off, off + scriptLen));
off += scriptLen;
return {
_size: off + scriptLen,
value: utils.read64(p, 0),
script: bcoin.script.decode(utils.slice(p, off, off + scriptLen))
_size: off - start,
value: value,
script: script
};
};
Parser.parseCoin = function parseCoin(p, extended) {
var off = 0;
Parser.parseCoin = function parseCoin(p, extended, off) {
var version, height, value, script, hash, index, spent, scriptLen;
off = off || 0;
if (p.length < 17 + (extended ? 37 : 0))
throw new Error('Invalid utxo size');
@ -520,18 +599,20 @@ Parser.parseCoin = function parseCoin(p, extended) {
};
};
Parser.parseTX = function parseTX(p, block) {
var off = 0;
Parser.parseTX = function parseTX(p, off) {
var inCount, txIn, tx;
var outCount, txOut;
var version, locktime, i;
var raw;
off = off || 0;
var start = off;
var block = off !== 0;
if (p.length < 10)
if (p.length - off < 10)
throw new Error('Invalid tx size');
if (Parser.isWitnessTX(p))
return Parser.parseWitnessTX(p, block);
if (Parser.isWitnessTX(p, off))
return Parser.parseWitnessTX(p, off);
version = utils.readU32(p, off);
off += 4;
@ -548,7 +629,7 @@ Parser.parseTX = function parseTX(p, block) {
txIn = new Array(inCount);
for (i = 0; i < inCount; i++) {
tx = Parser.parseInput(p.slice(off));
tx = Parser.parseInput(p, off);
if (!tx)
return;
@ -572,7 +653,7 @@ Parser.parseTX = function parseTX(p, block) {
txOut = new Array(outCount);
for (i = 0; i < outCount; i++) {
tx = Parser.parseOutput(p.slice(off));
tx = Parser.parseOutput(p, off);
if (!tx)
return;
@ -600,27 +681,31 @@ Parser.parseTX = function parseTX(p, block) {
locktime: locktime,
_witnessSize: 0,
// _raw: raw,
_size: off
_size: off - start
};
};
Parser.isWitnessTX = function isWitnessTX(p) {
if (p.length < 12)
Parser.isWitnessTX = function isWitnessTX(p, off) {
off = off || 0;
if (p.length - off < 12)
return false;
return p[4] === 0 && p[5] !== 0;
return p[off + 4] === 0 && p[off + 5] !== 0;
};
Parser.parseWitnessTX = function parseWitnessTX(p, block) {
var off = 0;
Parser.parseWitnessTX = function parseWitnessTX(p, off) {
var inCount, txIn, tx;
var outCount, txOut;
var marker, flag;
var version, locktime, i;
var witnessSize = 0;
var raw;
off = off || 0;
var start = off;
var block = off !== 0;
if (p.length < 12)
if (p.length - off < 12)
throw new Error('Invalid witness tx size');
version = utils.readU32(p, off);
@ -648,7 +733,7 @@ Parser.parseWitnessTX = function parseWitnessTX(p, block) {
txIn = new Array(inCount);
for (i = 0; i < inCount; i++) {
tx = Parser.parseInput(p.slice(off));
tx = Parser.parseInput(p, off);
if (!tx)
return;
@ -671,7 +756,7 @@ Parser.parseWitnessTX = function parseWitnessTX(p, block) {
txOut = new Array(outCount);
for (i = 0; i < outCount; i++) {
tx = Parser.parseOutput(p.slice(off));
tx = Parser.parseOutput(p, off);
if (!tx)
return;
@ -685,7 +770,7 @@ Parser.parseWitnessTX = function parseWitnessTX(p, block) {
}
for (i = 0; i < inCount; i++) {
tx = Parser.parseWitness(p.slice(off));
tx = Parser.parseWitness(p, off);
if (!tx)
return;
@ -716,15 +801,16 @@ Parser.parseWitnessTX = function parseWitnessTX(p, block) {
outputs: txOut,
locktime: locktime,
// _raw: raw,
_size: off,
_size: off - start,
_witnessSize: witnessSize + 2
};
};
Parser.parseWitness = function parseWitness(p) {
Parser.parseWitness = function parseWitness(p, off) {
var witness = [];
var off = 0;
var chunkCount, chunkSize, item, i;
off = off || 0;
var start = off;
chunkCount = utils.readIntv(p, off);
off = chunkCount.off;
@ -742,25 +828,26 @@ Parser.parseWitness = function parseWitness(p) {
}
return {
_size: off,
_size: off - start,
witness: witness
};
};
Parser.parseReject = function parseReject(p) {
Parser.parseReject = function parseReject(p, off) {
var messageLen, off, message, ccode, reasonLen, reason, data;
off = off || 0;
if (p.length < 3)
throw new Error('Invalid reject size');
messageLen = utils.readIntv(p, 0);
messageLen = utils.readIntv(p, off);
off = messageLen.off;
messageLen = messageLen.r;
if (off + messageLen + 2 > p.length)
throw new Error('Invalid reject message');
message = p.slice(off, off + messageLen).toString('ascii');
message = p.toString('ascii', off, off + messageLen);
off += messageLen;
ccode = utils.readU8(p, off);
@ -773,7 +860,7 @@ Parser.parseReject = function parseReject(p) {
if (off + reasonLen > p.length)
throw new Error('Invalid reject reason');
reason = p.slice(off, off + reasonLen).toString('ascii');
reason = p.toString('ascii', off, off + reasonLen);
off += reasonLen;
@ -828,14 +915,15 @@ Parser.parseAddress = function parseAddress(p, off, full) {
};
};
Parser.parseAddr = function parseAddr(p) {
Parser.parseAddr = function parseAddr(p, off) {
if (p.length < 31)
throw new Error('Invalid addr size');
var addrs = [];
var i, off, count;
var i, count;
off = off || 0;
count = utils.readIntv(p, 0);
count = utils.readIntv(p, off);
off = count.off;
count = count.r;
@ -847,13 +935,116 @@ Parser.parseAddr = function parseAddr(p) {
return addrs;
};
Parser.parseMempool = function parseMempool(p) {
if (p.length > 0)
Parser.parseMempool = function parseMempool(p, off) {
off = off || 0;
if (p.length - off > 0)
throw new Error('Invalid mempool size');
return {};
};
function BufferReader(data, offset) {
this.data = data;
this.offset = offset || 0;
}
BufferReader.prototype.readU8 = function readU8() {
var ret = utils.readU8(this.data, this.offset);
this.offset += 1;
return ret;
};
BufferReader.prototype.readU16 = function readU16() {
var ret = utils.readU16(this.data, this.offset);
this.offset += 2;
return ret;
};
BufferReader.prototype.readU16BE = function readU16BE() {
var ret = utils.readU16BE(this.data, this.offset);
this.offset += 2;
return ret;
};
BufferReader.prototype.readU32 = function readU32() {
var ret = utils.readU32(this.data, this.offset);
this.offset += 4;
return ret;
};
BufferReader.prototype.readU32BE = function readU32BE() {
var ret = utils.readU32BE(this.data, this.offset);
this.offset += 4;
return ret;
};
BufferReader.prototype.readU64 = function readU64() {
var ret = utils.readU64(this.data, this.offset);
this.offset += 8;
return ret;
};
BufferReader.prototype.readU64BE = function readU64BE() {
var ret = utils.readU64BE(this.data, this.offset);
this.offset += 8;
return ret;
};
BufferReader.prototype.read8 = function read8() {
var ret = utils.read8(this.data, this.offset);
this.offset += 1;
return ret;
};
BufferReader.prototype.read16 = function read16() {
var ret = utils.read16(this.data, this.offset);
this.offset += 2;
return ret;
};
BufferReader.prototype.read16BE = function read16BE() {
var ret = utils.read16BE(this.data, this.offset);
this.offset += 2;
return ret;
};
BufferReader.prototype.read32 = function read32() {
var ret = utils.read32(this.data, this.offset);
this.offset += 4;
return ret;
};
BufferReader.prototype.read32BE = function read32BE() {
var ret = utils.read32BE(this.data, this.offset);
this.offset += 4;
return ret;
};
BufferReader.prototype.read64 = function read64() {
var ret = utils.read64(this.data, this.offset);
this.offset += 8;
return ret;
};
BufferReader.prototype.read64BE = function read64BE() {
var ret = utils.read64BE(this.data, this.offset);
this.offset += 8;
return ret;
};
BufferReader.prototype.slice = function slice(size) {
if (size == null)
size = this.data.length - this.offset;
var ret = utils.slice(this.data, this.offset, this.offset + size);
this.offset += size;
return ret;
};
BufferReader.prototype.readHash = function readHash() {
return this.slice(32);
};
/**
* Expose
*/