move extended tx serialization.
This commit is contained in:
parent
fe18352a4c
commit
f5b4bb2bf6
@ -911,6 +911,63 @@ Framer.renderTX = function renderTX(tx, useWitness, writer) {
|
|||||||
return p;
|
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) {
|
Framer._block = function _block(block, useWitness, writer) {
|
||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
var witnessSize = 0;
|
var witnessSize = 0;
|
||||||
|
|||||||
@ -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.
|
* Parse block packet.
|
||||||
* @param {Buffer|BufferReader} p
|
* @param {Buffer|BufferReader} p
|
||||||
|
|||||||
@ -1761,11 +1761,7 @@ TX.fromRaw = function fromRaw(data, enc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TX.prototype.toExtended = function toExtended(saveCoins, enc) {
|
TX.prototype.toExtended = function toExtended(saveCoins, enc) {
|
||||||
var height = this.height;
|
var data;
|
||||||
var index = this.index;
|
|
||||||
var changeIndex = this.changeIndex != null ? this.changeIndex : -1;
|
|
||||||
var p = new BufferWriter();
|
|
||||||
var i, input, tmp;
|
|
||||||
|
|
||||||
if (typeof saveCoins === 'string') {
|
if (typeof saveCoins === 'string') {
|
||||||
tmp = saveCoins;
|
tmp = saveCoins;
|
||||||
@ -1773,57 +1769,24 @@ TX.prototype.toExtended = function toExtended(saveCoins, enc) {
|
|||||||
enc = tmp;
|
enc = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height === -1)
|
data = bcoin.protocol.framer.extendedTX(this, saveCoins);
|
||||||
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();
|
|
||||||
|
|
||||||
if (enc === 'hex')
|
if (enc === 'hex')
|
||||||
p = p.toString('hex');
|
data = data.toString('hex');
|
||||||
|
|
||||||
return p;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a transaction in "extended" serialization format.
|
* Parse a transaction in "extended" serialization format.
|
||||||
* @param {Buffer} buf
|
* @param {Buffer} data
|
||||||
* @param {Boolean?} saveCoins - If true, the function will
|
* @param {Boolean?} saveCoins - If true, the function will
|
||||||
* attempt to parse the coins.
|
* attempt to parse the coins.
|
||||||
* @param {String?} enc - One of `"hex"` or `null`.
|
* @param {String?} enc - One of `"hex"` or `null`.
|
||||||
* @returns {NakedTX} - A "naked" transaction object.
|
* @returns {NakedTX} - A "naked" transaction object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TX.parseExtended = function parseExtended(buf, saveCoins, enc) {
|
TX.parseExtended = function parseExtended(data, saveCoins, enc) {
|
||||||
var p, tx, coinCount, coin, i, tmp;
|
|
||||||
|
|
||||||
if (typeof saveCoins === 'string') {
|
if (typeof saveCoins === 'string') {
|
||||||
tmp = saveCoins;
|
tmp = saveCoins;
|
||||||
saveCoins = enc;
|
saveCoins = enc;
|
||||||
@ -1831,59 +1794,23 @@ TX.parseExtended = function parseExtended(buf, saveCoins, enc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (enc === 'hex')
|
if (enc === 'hex')
|
||||||
buf = new Buffer(buf, 'hex');
|
data = new Buffer(data, 'hex');
|
||||||
|
|
||||||
p = new BufferReader(buf);
|
return bcoin.protocol.parser.parseExtendedTX(data, saveCoins);
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate a transaction from a Buffer
|
* Instantiate a transaction from a Buffer
|
||||||
* in "extended" serialization format.
|
* in "extended" serialization format.
|
||||||
* @param {Buffer} buf
|
* @param {Buffer} data
|
||||||
* @param {Boolean?} saveCoins - If true, the function will
|
* @param {Boolean?} saveCoins - If true, the function will
|
||||||
* attempt to parse the coins.
|
* attempt to parse the coins.
|
||||||
* @param {String?} enc - One of `"hex"` or `null`.
|
* @param {String?} enc - One of `"hex"` or `null`.
|
||||||
* @returns {TX}
|
* @returns {TX}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TX.fromExtended = function fromExtended(buf, saveCoins, enc) {
|
TX.fromExtended = function fromExtended(data, saveCoins, enc) {
|
||||||
return new TX(TX.parseExtended(buf, saveCoins, enc));
|
return new TX(TX.parseExtended(data, saveCoins, enc));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -672,13 +672,13 @@ Framer.item = function _item(item, p) {
|
|||||||
} else {
|
} else {
|
||||||
if (item instanceof bcoin.block) {
|
if (item instanceof bcoin.block) {
|
||||||
p.writeU8(40);
|
p.writeU8(40);
|
||||||
p.writeVarBytes(item.render());
|
bcoin.protocol.framer.witnessBlock(item, p);
|
||||||
} else if (item instanceof bcoin.tx) {
|
} else if (item instanceof bcoin.tx) {
|
||||||
p.writeU8(41);
|
p.writeU8(41);
|
||||||
p.writeVarBytes(item.toExtended(true));
|
bcoin.protocol.framer.extendedTX(item, true, p);
|
||||||
} else if (item instanceof bcoin.coin) {
|
} else if (item instanceof bcoin.coin) {
|
||||||
p.writeU8(42);
|
p.writeU8(42);
|
||||||
p.writeVarBytes(item.toExtended());
|
bcoin.protocol.framer.coin(item, true, p);
|
||||||
} else if (bn.isBN(item)) {
|
} else if (bn.isBN(item)) {
|
||||||
p.writeU8(43);
|
p.writeU8(43);
|
||||||
p.writeVarBytes(item.toBuffer());
|
p.writeVarBytes(item.toBuffer());
|
||||||
@ -830,11 +830,11 @@ Parser.parseItem = function parseItem(p) {
|
|||||||
items[p.readVarString('utf8')] = Parser.parseItem(p);
|
items[p.readVarString('utf8')] = Parser.parseItem(p);
|
||||||
return items;
|
return items;
|
||||||
case 40:
|
case 40:
|
||||||
return bcoin.block.fromRaw(p.readVarBytes());
|
return bcoin.block.fromRaw(p);
|
||||||
case 41:
|
case 41:
|
||||||
return bcoin.tx.fromExtended(p.readVarBytes(), true);
|
return bcoin.tx.fromExtended(p, true);
|
||||||
case 42:
|
case 42:
|
||||||
return bcoin.coin.fromExtended(p.readVarBytes());
|
return bcoin.coin.fromExtended(p);
|
||||||
case 43:
|
case 43:
|
||||||
return new bn(p.readVarBytes());
|
return new bn(p.readVarBytes());
|
||||||
default:
|
default:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user