segwit parsing and framing.
This commit is contained in:
parent
5d1f6089ed
commit
5a8e2b80f3
@ -122,6 +122,32 @@ Block.prototype.getWitnessRoot = function getWitnessRoot() {
|
||||
return utils.toHex(root);
|
||||
};
|
||||
|
||||
Block.prototype.__defineGetter__('witnessRoot', function() {
|
||||
var coinbase, i, commitment, witnessRoot;
|
||||
|
||||
if (!block.witness)
|
||||
return;
|
||||
|
||||
if (this._witnessRoot)
|
||||
return this._witnessRoot;
|
||||
|
||||
coinbase = block.txs[0];
|
||||
|
||||
// Find the fucking commitment for segregated shitness
|
||||
for (i = 0; i < coinbase.outputs.length; i++) {
|
||||
commitment = coinbase.outputs[i].script;
|
||||
if (bcoin.script.isCommitment(commitment)) {
|
||||
witnessRoot = bcoin.script.getWitnessRoot(commitment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (witnessRoot)
|
||||
this._witnessRoot = utils.toHex(witnessRoot);
|
||||
|
||||
return this._witnessRoot;
|
||||
});
|
||||
|
||||
Block.prototype._verify = function _verify() {
|
||||
var uniq = {};
|
||||
var i, tx, hash;
|
||||
@ -275,6 +301,7 @@ Block.prototype.inspect = function inspect() {
|
||||
version: this.version,
|
||||
prevBlock: utils.revHex(this.prevBlock),
|
||||
merkleRoot: utils.revHex(this.merkleRoot),
|
||||
witnessRoot: utils.revHex(this.witnessRoot),
|
||||
ts: this.ts,
|
||||
bits: this.bits,
|
||||
nonce: this.nonce,
|
||||
@ -291,6 +318,7 @@ Block.prototype.toJSON = function toJSON() {
|
||||
version: this.version,
|
||||
prevBlock: utils.revHex(this.prevBlock),
|
||||
merkleRoot: utils.revHex(this.merkleRoot),
|
||||
witnessRoot: utils.revHex(this.witnessRoot),
|
||||
ts: this.ts,
|
||||
bits: this.bits,
|
||||
nonce: this.nonce,
|
||||
|
||||
@ -573,19 +573,10 @@ Chain.prototype._verify = function _verify(block, prev) {
|
||||
}
|
||||
}
|
||||
|
||||
// Find the fucking commitment for segregated shitness
|
||||
if (segwit && block.witness) {
|
||||
coinbase = block.txs[0];
|
||||
for (i = 0; i < coinbase.outputs.length; i++) {
|
||||
commitment = coinbase.outputs[i].script;
|
||||
if (bcoin.script.isCommitment(commitment)) {
|
||||
witnessRoot = bcoin.script.getWitnessRoot(commitment);
|
||||
if (utils.toHex(witnessRoot) !== block.getWitnessRoot()) {
|
||||
utils.debug('Block failed witnessroot test: %s', block.rhash);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (block.witnessRoot !== block.getWitnessRoot()) {
|
||||
utils.debug('Block failed witnessroot test: %s', block.rhash);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,13 +111,21 @@ Framer.prototype.coin = function _coin(coin) {
|
||||
};
|
||||
|
||||
Framer.prototype.tx = function tx(tx) {
|
||||
return this.packet('tx', Framer.tx(block));
|
||||
return this.packet('tx', Framer.tx(tx));
|
||||
};
|
||||
|
||||
Framer.prototype.witnessTX = function witnessTX(tx) {
|
||||
return this.packet('tx', Framer.witnessTX(tx));
|
||||
};
|
||||
|
||||
Framer.prototype.block = function _block(block) {
|
||||
return this.packet('block', Framer.block(block));
|
||||
};
|
||||
|
||||
Framer.prototype.witnessBlock = function witnessBlock(block) {
|
||||
return this.packet('block', Framer.witnessBlock(block));
|
||||
};
|
||||
|
||||
Framer.prototype.merkleBlock = function merkleBlock(block) {
|
||||
return this.packet('merkleblock', Framer.merkleBlock(block));
|
||||
};
|
||||
@ -543,7 +551,7 @@ Framer.witness = function _witness(witness) {
|
||||
if (!witness)
|
||||
return new Buffer([0]);
|
||||
|
||||
size += utils.writeIntv(witness.length);
|
||||
size += utils.sizeIntv(witness.length);
|
||||
|
||||
for (i = 0; i < witness.length; i++) {
|
||||
chunk = witness[i];
|
||||
@ -552,6 +560,8 @@ Framer.witness = function _witness(witness) {
|
||||
|
||||
p = new Buffer(size);
|
||||
|
||||
off += utils.writeIntv(p, witness.length, off);
|
||||
|
||||
for (i = 0; i < witness.length; i++) {
|
||||
chunk = witness[i];
|
||||
off += utils.writeIntv(p, chunk.length, off);
|
||||
@ -576,7 +586,7 @@ Framer._block = function _block(block, witness) {
|
||||
var i, tx, p;
|
||||
|
||||
for (i = 0; i < block.txs.length; i++) {
|
||||
tx = witness && block.txs[i].witness
|
||||
tx = witness
|
||||
? Framer.witnessTX(block.txs[i])
|
||||
: Framer.tx(block.txs[i]);
|
||||
txs.push(tx);
|
||||
|
||||
@ -521,9 +521,10 @@ Parser.parseCoin = function parseCoin(p, extended) {
|
||||
};
|
||||
|
||||
Parser.parseTX = function parseTX(p) {
|
||||
var inCount, off, txIn, tx;
|
||||
var off = 0;
|
||||
var inCount, txIn, tx;
|
||||
var outCount, txOut;
|
||||
var i;
|
||||
var version, locktime, i;
|
||||
|
||||
if (p.length < 10)
|
||||
throw new Error('Invalid tx size');
|
||||
@ -531,7 +532,10 @@ Parser.parseTX = function parseTX(p) {
|
||||
if (Parser.isWitnessTX(p))
|
||||
return Parser.parseWitnessTX(p);
|
||||
|
||||
inCount = utils.readIntv(p, 4);
|
||||
version = utils.readU32(p, off);
|
||||
off += 4;
|
||||
|
||||
inCount = utils.readIntv(p, off);
|
||||
off = inCount.off;
|
||||
inCount = inCount.r;
|
||||
|
||||
@ -579,14 +583,18 @@ Parser.parseTX = function parseTX(p) {
|
||||
throw new Error('Invalid tx_out offset');
|
||||
}
|
||||
|
||||
locktime = utils.readU32(p, off);
|
||||
off += 4;
|
||||
|
||||
return {
|
||||
version: utils.read32(p, 0),
|
||||
witness: false,
|
||||
version: version,
|
||||
inputs: txIn,
|
||||
outputs: txOut,
|
||||
locktime: utils.readU32(p, off),
|
||||
_cost: (off + 4) * 4,
|
||||
_raw: p.slice(0, off + 4),
|
||||
_size: off + 4
|
||||
locktime: locktime,
|
||||
_cost: off * 4,
|
||||
_raw: p.length !== off ? p.slice(0, off) : p,
|
||||
_size: off
|
||||
};
|
||||
};
|
||||
|
||||
@ -599,16 +607,21 @@ Parser.isWitnessTX = function isWitnessTX(p) {
|
||||
|
||||
Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
var cost = 0;
|
||||
var inCount, off, txIn, tx;
|
||||
var off = 0;
|
||||
var inCount, txIn, tx;
|
||||
var outCount, txOut;
|
||||
var marker, flag;
|
||||
var i;
|
||||
var version, locktime, i;
|
||||
|
||||
if (p.length < 12)
|
||||
throw new Error('Invalid witness tx size');
|
||||
|
||||
marker = utils.readU8(p, 4);
|
||||
flag = utils.readU8(p, 5);
|
||||
version = utils.readU32(p, off);
|
||||
off += 4;
|
||||
marker = utils.readU8(p, off);
|
||||
off += 1;
|
||||
flag = utils.readU8(p, off);
|
||||
off += 1;
|
||||
|
||||
if (marker !== 0)
|
||||
throw new Error('Invalid witness tx (marker != 0)');
|
||||
@ -616,7 +629,7 @@ Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
if (flag === 0)
|
||||
throw new Error('Invalid witness tx (flag == 0)');
|
||||
|
||||
inCount = utils.readIntv(p, 6);
|
||||
inCount = utils.readIntv(p, off);
|
||||
off = inCount.off;
|
||||
inCount = inCount.r;
|
||||
|
||||
@ -682,25 +695,30 @@ Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
throw new Error('Invalid witness offset');
|
||||
}
|
||||
|
||||
locktime = utils.readU32(p, off);
|
||||
off += 4;
|
||||
cost += 4 * 4;
|
||||
|
||||
return {
|
||||
witness: true,
|
||||
version: utils.read32(p, 0),
|
||||
version: version,
|
||||
marker: marker,
|
||||
flag: flag,
|
||||
inputs: txIn,
|
||||
outputs: txOut,
|
||||
locktime: utils.readU32(p, off),
|
||||
_raw: p.slice(0, off + 4),
|
||||
_size: off + 4,
|
||||
locktime: locktime,
|
||||
_raw: off !== p.length ? p.slice(0, off) : p,
|
||||
_size: off,
|
||||
_cost: cost
|
||||
};
|
||||
};
|
||||
|
||||
Parser.parseWitness = function parseWitness(p) {
|
||||
var witness = [];
|
||||
var off, chunkCount, chunkSize, item, i;
|
||||
var off = 0;
|
||||
var chunkCount, chunkSize, item, i;
|
||||
|
||||
chunkCount = utils.readIntv(p, 0);
|
||||
chunkCount = utils.readIntv(p, off);
|
||||
off = chunkCount.off;
|
||||
chunkCount = chunkCount.r;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user