move extended tx serialization.

This commit is contained in:
Christopher Jeffrey 2016-05-05 05:23:18 -07:00
parent fe18352a4c
commit f5b4bb2bf6
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 125 additions and 90 deletions

View File

@ -911,6 +911,63 @@ Framer.renderTX = function renderTX(tx, useWitness, writer) {
return p;
};
/**
* Serialize a transaction to BCoin "extended format".
* This is the serialization format BCoin uses internally
* to store transactions in the database. The extended
* serialization includes the height, block hash, index,
* timestamp, pending-since time, and optionally a vector
* for the serialized coins.
* @param {NakedTX|TX} tx
* @param {Boolean?} saveCoins - Whether to serialize the coins.
* @param {String?} enc - One of `"hex"` or `null`.
* @returns {Buffer}
*/
Framer.extendedTX = function extendedTX(tx, saveCoins, writer) {
var height = tx.height;
var index = tx.index;
var changeIndex = tx.changeIndex != null ? tx.changeIndex : -1;
var p = new BufferWriter(writer);
var i, input, tmp;
if (height === -1)
height = 0x7fffffff;
if (index === -1)
index = 0x7fffffff;
if (changeIndex === -1)
changeIndex = 0x7fffffff;
Framer.renderTX(tx, true, p);
p.writeU32(height);
p.writeHash(tx.block || constants.ZERO_HASH);
p.writeU32(index);
p.writeU32(tx.ts);
p.writeU32(tx.ps);
// p.writeU32(changeIndex);
if (saveCoins) {
p.writeVarint(tx.inputs.length);
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
if (!input.coin) {
p.writeVarint(0);
continue;
}
p.writeVarBytes(Framer.coin(input.coin, false));
}
}
if (!writer)
p = p.render();
return p;
};
Framer._block = function _block(block, useWitness, writer) {
var p = new BufferWriter(writer);
var witnessSize = 0;

View File

@ -692,6 +692,57 @@ Parser.parseBlockHeaders = function parseBlockHeaders(p) {
};
};
/**
* Parse a transaction in "extended" serialization format.
* @param {Buffer} p
* @param {Boolean?} saveCoins - If true, the function will
* attempt to parse the coins.
* @param {String?} enc - One of `"hex"` or `null`.
* @returns {NakedTX} - A "naked" transaction object.
*/
Parser.parseExtendedTX = function parseExtendedTX(p, saveCoins) {
var tx, coinCount, coin, i, tmp;
p = new BufferReader(p);
tx = Parser.parseTX(p);
tx.height = p.readU32();
tx.block = p.readHash('hex');
tx.index = p.readU32();
tx.ts = p.readU32();
tx.ps = p.readU32();
// tx.changeIndex = p.readU32();
if (tx.block === constants.NULL_HASH)
tx.block = null;
if (tx.height === 0x7fffffff)
tx.height = -1;
if (tx.index === 0x7fffffff)
tx.index = -1;
if (tx.changeIndex === 0x7fffffff)
tx.changeIndex = -1;
if (saveCoins) {
coinCount = p.readVarint();
for (i = 0; i < coinCount; i++) {
coin = p.readVarBytes();
if (coin.length === 0)
continue;
coin = Parser.parseCoin(coin, false);
coin.hash = tx.inputs[i].prevout.hash;
coin.index = tx.inputs[i].prevout.index;
tx.inputs[i].coin = coin;
}
}
return tx;
};
/**
* Parse block packet.
* @param {Buffer|BufferReader} p

View File

@ -1761,11 +1761,7 @@ TX.fromRaw = function fromRaw(data, enc) {
*/
TX.prototype.toExtended = function toExtended(saveCoins, enc) {
var height = this.height;
var index = this.index;
var changeIndex = this.changeIndex != null ? this.changeIndex : -1;
var p = new BufferWriter();
var i, input, tmp;
var data;
if (typeof saveCoins === 'string') {
tmp = saveCoins;
@ -1773,57 +1769,24 @@ TX.prototype.toExtended = function toExtended(saveCoins, enc) {
enc = tmp;
}
if (height === -1)
height = 0x7fffffff;
if (index === -1)
index = 0x7fffffff;
if (changeIndex === -1)
changeIndex = 0x7fffffff;
bcoin.protocol.framer.renderTX(this, true, p);
p.writeU32(height);
p.writeHash(this.block || constants.ZERO_HASH);
p.writeU32(index);
p.writeU32(this.ts);
p.writeU32(this.ps);
// p.writeU32(changeIndex);
if (saveCoins) {
p.writeVarint(this.inputs.length);
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
if (!input.coin) {
p.writeVarint(0);
continue;
}
p.writeVarBytes(bcoin.protocol.framer.coin(input.coin, false));
}
}
p = p.render();
data = bcoin.protocol.framer.extendedTX(this, saveCoins);
if (enc === 'hex')
p = p.toString('hex');
data = data.toString('hex');
return p;
return data;
};
/**
* Parse a transaction in "extended" serialization format.
* @param {Buffer} buf
* @param {Buffer} data
* @param {Boolean?} saveCoins - If true, the function will
* attempt to parse the coins.
* @param {String?} enc - One of `"hex"` or `null`.
* @returns {NakedTX} - A "naked" transaction object.
*/
TX.parseExtended = function parseExtended(buf, saveCoins, enc) {
var p, tx, coinCount, coin, i, tmp;
TX.parseExtended = function parseExtended(data, saveCoins, enc) {
if (typeof saveCoins === 'string') {
tmp = saveCoins;
saveCoins = enc;
@ -1831,59 +1794,23 @@ TX.parseExtended = function parseExtended(buf, saveCoins, enc) {
}
if (enc === 'hex')
buf = new Buffer(buf, 'hex');
data = new Buffer(data, 'hex');
p = new BufferReader(buf);
tx = bcoin.protocol.parser.parseTX(p);
tx.height = p.readU32();
tx.block = p.readHash('hex');
tx.index = p.readU32();
tx.ts = p.readU32();
tx.ps = p.readU32();
// tx.changeIndex = p.readU32();
if (tx.block === constants.NULL_HASH)
tx.block = null;
if (tx.height === 0x7fffffff)
tx.height = -1;
if (tx.index === 0x7fffffff)
tx.index = -1;
if (tx.changeIndex === 0x7fffffff)
tx.changeIndex = -1;
if (saveCoins) {
coinCount = p.readVarint();
for (i = 0; i < coinCount; i++) {
coin = p.readVarBytes();
if (coin.length === 0)
continue;
coin = bcoin.protocol.parser.parseCoin(coin, false);
coin.hash = tx.inputs[i].prevout.hash;
coin.index = tx.inputs[i].prevout.index;
tx.inputs[i].coin = coin;
}
}
return tx;
return bcoin.protocol.parser.parseExtendedTX(data, saveCoins);
};
/**
* Instantiate a transaction from a Buffer
* in "extended" serialization format.
* @param {Buffer} buf
* @param {Buffer} data
* @param {Boolean?} saveCoins - If true, the function will
* attempt to parse the coins.
* @param {String?} enc - One of `"hex"` or `null`.
* @returns {TX}
*/
TX.fromExtended = function fromExtended(buf, saveCoins, enc) {
return new TX(TX.parseExtended(buf, saveCoins, enc));
TX.fromExtended = function fromExtended(data, saveCoins, enc) {
return new TX(TX.parseExtended(data, saveCoins, enc));
};
/**

View File

@ -672,13 +672,13 @@ Framer.item = function _item(item, p) {
} else {
if (item instanceof bcoin.block) {
p.writeU8(40);
p.writeVarBytes(item.render());
bcoin.protocol.framer.witnessBlock(item, p);
} else if (item instanceof bcoin.tx) {
p.writeU8(41);
p.writeVarBytes(item.toExtended(true));
bcoin.protocol.framer.extendedTX(item, true, p);
} else if (item instanceof bcoin.coin) {
p.writeU8(42);
p.writeVarBytes(item.toExtended());
bcoin.protocol.framer.coin(item, true, p);
} else if (bn.isBN(item)) {
p.writeU8(43);
p.writeVarBytes(item.toBuffer());
@ -830,11 +830,11 @@ Parser.parseItem = function parseItem(p) {
items[p.readVarString('utf8')] = Parser.parseItem(p);
return items;
case 40:
return bcoin.block.fromRaw(p.readVarBytes());
return bcoin.block.fromRaw(p);
case 41:
return bcoin.tx.fromExtended(p.readVarBytes(), true);
return bcoin.tx.fromExtended(p, true);
case 42:
return bcoin.coin.fromExtended(p.readVarBytes());
return bcoin.coin.fromExtended(p);
case 43:
return new bn(p.readVarBytes());
default: