tx: parse
This commit is contained in:
parent
cd3f04268a
commit
40ea4d1fb1
@ -5,6 +5,7 @@ bcoin.ecdsa = elliptic.ecdsa(elliptic.nist.secp256k1);
|
||||
bcoin.utils = require('./bcoin/utils');
|
||||
bcoin.bloom = require('./bcoin/bloom');
|
||||
bcoin.protocol = require('./bcoin/protocol');
|
||||
bcoin.script = require('./bcoin/script');
|
||||
bcoin.tx = require('./bcoin/tx');
|
||||
bcoin.block = require('./bcoin/block');
|
||||
bcoin.chain = require('./bcoin/chain');
|
||||
|
||||
@ -12,6 +12,11 @@ function Block(data) {
|
||||
this.ts = data.ts;
|
||||
this.bits = data.bits;
|
||||
this.nonce = data.nonce;
|
||||
this.totalTx = data.totalTx;
|
||||
this.hashes = data.hashes.map(function(hash) {
|
||||
return utils.toHex(hash);
|
||||
});
|
||||
this.flags = data.flags;
|
||||
|
||||
this._hash = null;
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ function Pool(options) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.options = options || {};
|
||||
this.size = options.size || 2;
|
||||
this.size = options.size || 3;
|
||||
this.parallel = options.parallel || 2000;
|
||||
this.load = {
|
||||
timeout: options.loadTimeout || 10000,
|
||||
@ -23,7 +23,7 @@ function Pool(options) {
|
||||
hiReached: false
|
||||
};
|
||||
this.maxRetries = options.maxRetries || 300;
|
||||
this.requestTimeout = options.requestTimeout || 30000;
|
||||
this.requestTimeout = options.requestTimeout || 10000;
|
||||
this.chain = new bcoin.chain();
|
||||
this.bloom = new bcoin.bloom(8 * 10 * 1024,
|
||||
10,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
var assert = require('assert');
|
||||
var util = require('util');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var bn = require('bn.js');
|
||||
|
||||
var bcoin = require('../../bcoin');
|
||||
var utils = bcoin.utils;
|
||||
@ -54,7 +55,8 @@ Parser.prototype.parse = function parse(chunk) {
|
||||
return this.emit('error', new Error('Invalid checksum'));
|
||||
this.packet.payload = this.parsePayload(this.packet.cmd,
|
||||
this.packet.payload);
|
||||
this.emit('packet', this.packet);
|
||||
if (this.packet.payload)
|
||||
this.emit('packet', this.packet);
|
||||
|
||||
this.waiting = 24;
|
||||
this.packet = null;
|
||||
@ -92,6 +94,8 @@ Parser.prototype.parsePayload = function parsePayload(cmd, p) {
|
||||
return this.parseMerkleBlock(p);
|
||||
else if (cmd === 'block')
|
||||
return this.parseBlock(p);
|
||||
else if (cmd === 'tx')
|
||||
return this.parseTx(p);
|
||||
else
|
||||
return p;
|
||||
};
|
||||
@ -144,7 +148,7 @@ function readIntv(p, off) {
|
||||
bytes = 9;
|
||||
}
|
||||
|
||||
return { off: bytes, r: r };
|
||||
return { off: off + bytes, r: r };
|
||||
}
|
||||
|
||||
Parser.prototype.parseInvList = function parseInvList(p) {
|
||||
@ -165,9 +169,29 @@ Parser.prototype.parseInvList = function parseInvList(p) {
|
||||
};
|
||||
|
||||
Parser.prototype.parseMerkleBlock = function parseMerkleBlock(p) {
|
||||
if (p.length < 84)
|
||||
if (p.length < 86)
|
||||
return this.emit('error', new Error('Invalid merkleblock size'));
|
||||
|
||||
var hashCount = readIntv(p, 84);
|
||||
var off = hashCount.off;
|
||||
hashCount = hashCount.r;
|
||||
if (off + 32 * hashCount + 1 > p.length)
|
||||
return this.emit('error', new Error('Invalid hash count'));
|
||||
|
||||
var hashes = new Array(hashCount);
|
||||
for (var i = 0; i < hashCount; i++)
|
||||
hashes[i] = p.slice(off + i * 32, off + (i + 1) * 32);
|
||||
|
||||
off = off + 32 * hashCount;
|
||||
var flagCount = readIntv(p, off);
|
||||
off = flagCount.off;
|
||||
flagCount = flagCount.r;
|
||||
|
||||
if (off + flagCount > p.length)
|
||||
return this.emit('error', new Error('Invalid flag count'));
|
||||
|
||||
var flags = p.slice(off, off + flagCount);
|
||||
|
||||
return {
|
||||
version: readU32(p, 0),
|
||||
prevBlock: p.slice(4, 36),
|
||||
@ -175,10 +199,9 @@ Parser.prototype.parseMerkleBlock = function parseMerkleBlock(p) {
|
||||
ts: readU32(p, 68),
|
||||
bits: readU32(p, 72),
|
||||
nonce: readU32(p, 76),
|
||||
totalTx: readU32(p, 80)
|
||||
|
||||
// hashes:
|
||||
// flags:
|
||||
totalTx: readU32(p, 80),
|
||||
hashes: hashes,
|
||||
flags: flags
|
||||
};
|
||||
};
|
||||
|
||||
@ -194,8 +217,96 @@ Parser.prototype.parseBlock = function parseBlock(p) {
|
||||
bits: readU32(p, 72),
|
||||
nonce: readU32(p, 76),
|
||||
totalTx: readU32(p, 80)
|
||||
|
||||
// hashes:
|
||||
// flags:
|
||||
};
|
||||
};
|
||||
|
||||
Parser.prototype.parseTxIn = function parseTxIn(p) {
|
||||
if (p.length < 41)
|
||||
return this.emit('error', new Error('Invalid tx_in size'));
|
||||
|
||||
var scriptLen = readIntv(p, 36);
|
||||
var off = scriptLen.off;
|
||||
scriptLen = scriptLen.r;
|
||||
if (off + scriptLen + 4 > p.length)
|
||||
return this.emit('error', new Error('Invalid tx_in script length'));
|
||||
|
||||
return {
|
||||
size: off + scriptLen + 4,
|
||||
out: {
|
||||
hash: p.slice(0, 32),
|
||||
index: readU32(p, 32)
|
||||
},
|
||||
script: p.slice(off, off + scriptLen),
|
||||
seq: readU32(p, off + scriptLen)
|
||||
};
|
||||
};
|
||||
|
||||
Parser.prototype.parseTxOut = function parseTxOut(p) {
|
||||
if (p.length < 9)
|
||||
return this.emit('error', new Error('Invalid tx_out size'));
|
||||
|
||||
var scriptLen = readIntv(p, 8);
|
||||
var off = scriptLen.off;
|
||||
scriptLen = scriptLen.r;
|
||||
if (off + scriptLen > p.length)
|
||||
return this.emit('error', new Error('Invalid tx_out script length'));
|
||||
|
||||
return {
|
||||
size: off + scriptLen,
|
||||
value: new bn(p.slice(0, 8).reverse()),
|
||||
script: p.slice(off, off + scriptLen)
|
||||
};
|
||||
};
|
||||
|
||||
Parser.prototype.parseTx = function parseTx(p) {
|
||||
if (p.length < 60)
|
||||
return this.emit('error', new Error('Invalid tx size'));
|
||||
|
||||
var inCount = readIntv(p, 4);
|
||||
var off = inCount.off;
|
||||
inCount = inCount.r;
|
||||
if (inCount <= 0)
|
||||
return this.emit('error', new Error('Invalid tx_in count'));
|
||||
if (off + 41 * inCount + 14 > p.length)
|
||||
return this.emit('error', new Error('Invalid tx_in count'));
|
||||
|
||||
var txIn = new Array(inCount);
|
||||
for (var i = 0; i < inCount; i++) {
|
||||
var tx = this.parseTxIn(p.slice(off));
|
||||
if (!tx)
|
||||
return;
|
||||
txIn[i] = tx;
|
||||
off += tx.size;
|
||||
|
||||
if (off + 14 > p.length)
|
||||
return this.emit('error', new Error('Invalid tx_in offset'));
|
||||
}
|
||||
|
||||
var outCount = readIntv(p, off);
|
||||
var off = outCount.off;
|
||||
outCount = outCount.r;
|
||||
if (outCount <= 0)
|
||||
return this.emit('error', new Error('Invalid tx_out count'));
|
||||
if (off + 9 * outCount + 4 > p.length)
|
||||
return this.emit('error', new Error('Invalid tx_out count'));
|
||||
|
||||
var txOut = new Array(outCount);
|
||||
for (var i = 0; i < outCount; i++) {
|
||||
var tx = this.parseTxOut(p.slice(off));
|
||||
if (!tx)
|
||||
return;
|
||||
txOut[i] = tx;
|
||||
off += tx.size;
|
||||
|
||||
if (off + 4 > p.length)
|
||||
return this.emit('error', new Error('Invalid tx_out offset'));
|
||||
}
|
||||
|
||||
return {
|
||||
_raw: p,
|
||||
version: readU32(p, 0),
|
||||
inputs: txIn,
|
||||
outputs: txOut,
|
||||
lock: readU32(p, off)
|
||||
};
|
||||
};
|
||||
|
||||
5
lib/bcoin/script.js
Normal file
5
lib/bcoin/script.js
Normal file
@ -0,0 +1,5 @@
|
||||
var script = exports;
|
||||
|
||||
script.parse = function parse(s) {
|
||||
return s;
|
||||
};
|
||||
@ -6,8 +6,26 @@ function TX(data) {
|
||||
return new TX(data);
|
||||
this.type = 'tx';
|
||||
|
||||
this.version = data.version;
|
||||
this.inputs = data.inputs.map(function(input) {
|
||||
return {
|
||||
out: {
|
||||
hash: utils.toHex(input.out.hash),
|
||||
index: bcoin.script.parse(input.out.index)
|
||||
},
|
||||
script: input.script,
|
||||
seq: input.seq
|
||||
};
|
||||
});
|
||||
this.outputs = data.outputs.map(function(output) {
|
||||
return {
|
||||
value: output.value,
|
||||
script: bcoin.script.parse(output.script)
|
||||
};
|
||||
});
|
||||
|
||||
this._hash = null;
|
||||
this._raw = data || null;
|
||||
this._raw = data._raw || null;
|
||||
}
|
||||
module.exports = TX;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user