mempool: orphan serialization.
This commit is contained in:
parent
30526aaea4
commit
38eca965a7
@ -9,6 +9,8 @@
|
||||
var AsyncObject = require('../utils/async');
|
||||
var constants = require('../protocol/constants');
|
||||
var util = require('../utils/util');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var co = require('../utils/co');
|
||||
var assert = require('assert');
|
||||
var crypto = require('../crypto/crypto');
|
||||
@ -22,6 +24,7 @@ var Coin = require('../primitives/coin');
|
||||
var Locker = require('../utils/locker');
|
||||
var Outpoint = require('../primitives/outpoint');
|
||||
var TX = require('../primitives/tx');
|
||||
var Coin = require('../primitives/coin');
|
||||
var MempoolEntry = require('./mempoolentry');
|
||||
|
||||
/**
|
||||
@ -1310,7 +1313,7 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx) {
|
||||
this.waiting[prev].push(hash);
|
||||
}
|
||||
|
||||
this.orphans[hash] = tx.toExtended(true);
|
||||
this.orphans[hash] = toOrphanRaw(tx);
|
||||
this.totalOrphans++;
|
||||
|
||||
this.logger.debug('Added orphan %s to mempool.', tx.txid());
|
||||
@ -1389,7 +1392,7 @@ Mempool.prototype.getOrphan = function getOrphan(hash) {
|
||||
return;
|
||||
|
||||
try {
|
||||
orphan = TX.fromExtended(data, true);
|
||||
orphan = fromOrphanRaw(data);
|
||||
} catch (e) {
|
||||
delete this.orphans[hash];
|
||||
this.logger.warning('%s %s',
|
||||
@ -1444,7 +1447,7 @@ Mempool.prototype.resolveOrphans = function resolveOrphans(tx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.orphans[orphanHash] = orphan.toExtended(true);
|
||||
this.orphans[orphanHash] = toOrphanRaw(orphan);
|
||||
}
|
||||
|
||||
delete this.waiting[hash];
|
||||
@ -1981,6 +1984,53 @@ AddressIndex.prototype.removeCoin = function removeCoin(coin) {
|
||||
delete this.map[key];
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function toOrphanRaw(tx) {
|
||||
var bw = new BufferWriter();
|
||||
var i, input;
|
||||
|
||||
tx.toWriter(bw);
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
|
||||
if (!input.coin) {
|
||||
bw.writeU8(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
bw.writeU8(1);
|
||||
input.coin.toWriter(bw);
|
||||
}
|
||||
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
function fromOrphanRaw(data) {
|
||||
var br = new BufferReader(data);
|
||||
var i, tx, input, coin;
|
||||
|
||||
tx = TX.fromReader(br);
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
|
||||
if (br.readU8() === 0)
|
||||
continue;
|
||||
|
||||
coin = Coin.fromReader(br);
|
||||
coin.hash = input.prevout.hash;
|
||||
coin.index = input.prevout.index;
|
||||
|
||||
input.coin = coin;
|
||||
}
|
||||
|
||||
return tx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -2435,17 +2435,20 @@ TX.isWitness = function isWitness(br) {
|
||||
* 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 {Boolean?} saveCoins - Whether to serialize the coins.
|
||||
* timestamp, and pending-since time.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
TX.prototype.toExtended = function toExtended(saveCoins) {
|
||||
TX.prototype.toExtended = function toExtended() {
|
||||
var bw = new BufferWriter();
|
||||
var height = this.height;
|
||||
var index = this.index;
|
||||
var i, input, field, bit, oct;
|
||||
|
||||
if (height === -1)
|
||||
height = 0x7fffffff;
|
||||
|
||||
if (index === -1)
|
||||
index = 0x7fffffff;
|
||||
|
||||
this.toWriter(bw);
|
||||
|
||||
@ -2458,49 +2461,21 @@ TX.prototype.toExtended = function toExtended(saveCoins) {
|
||||
bw.writeU8(0);
|
||||
}
|
||||
|
||||
if (height === -1)
|
||||
height = 0x7fffffff;
|
||||
|
||||
if (index === -1)
|
||||
index = 0x7fffffff;
|
||||
|
||||
bw.writeU32(height);
|
||||
bw.writeU32(this.ts);
|
||||
bw.writeU32(index);
|
||||
|
||||
if (saveCoins) {
|
||||
field = new Buffer(Math.ceil(this.inputs.length / 8));
|
||||
field.fill(0);
|
||||
|
||||
bw.writeBytes(field);
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
if (!input.coin) {
|
||||
bit = i % 8;
|
||||
oct = (i - bit) / 8;
|
||||
field[oct] |= 1 << (7 - bit);
|
||||
continue;
|
||||
}
|
||||
|
||||
input.coin.toWriter(bw);
|
||||
}
|
||||
}
|
||||
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from "extended" serialization format.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {Boolean?} saveCoins - If true, the function will
|
||||
* attempt to parse the coins.
|
||||
*/
|
||||
|
||||
TX.prototype.fromExtended = function fromExtended(data, saveCoins) {
|
||||
TX.prototype.fromExtended = function fromExtended(data) {
|
||||
var br = new BufferReader(data);
|
||||
var i, input, coin, field, bit, oct, spent;
|
||||
|
||||
this.fromReader(br);
|
||||
|
||||
@ -2519,27 +2494,6 @@ TX.prototype.fromExtended = function fromExtended(data, saveCoins) {
|
||||
if (this.index === 0x7fffffff)
|
||||
this.index = -1;
|
||||
|
||||
if (saveCoins) {
|
||||
field = br.readBytes(Math.ceil(this.inputs.length / 8), true);
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
bit = i % 8;
|
||||
oct = (i - bit) / 8;
|
||||
spent = (field[oct] >>> (7 - bit)) & 1;
|
||||
|
||||
if (spent)
|
||||
continue;
|
||||
|
||||
coin = Coin.fromReader(br);
|
||||
coin.hash = input.prevout.hash;
|
||||
coin.index = input.prevout.index;
|
||||
|
||||
input.coin = coin;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -2547,22 +2501,14 @@ TX.prototype.fromExtended = function fromExtended(data, saveCoins) {
|
||||
* Instantiate a transaction from a Buffer
|
||||
* in "extended" serialization format.
|
||||
* @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(data, saveCoins, enc) {
|
||||
if (typeof saveCoins === 'string') {
|
||||
enc = saveCoins;
|
||||
saveCoins = false;
|
||||
}
|
||||
|
||||
TX.fromExtended = function fromExtended(data, enc) {
|
||||
if (typeof data === 'string')
|
||||
data = new Buffer(data, enc);
|
||||
|
||||
return new TX().fromExtended(data, saveCoins);
|
||||
return new TX().fromExtended(data);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user