txdb: details and pathinfo.

This commit is contained in:
Christopher Jeffrey 2016-08-11 00:08:14 -07:00
parent 759365ca25
commit 914bc8435d
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 214 additions and 3 deletions

View File

@ -311,7 +311,7 @@ Input.prototype.getRedeem = function getRedeem() {
*/
Input.prototype.getSubtype = function getSubtype() {
var redeem;
var redeem, type;
if (this.isCoinbase())
return;
@ -321,7 +321,9 @@ Input.prototype.getSubtype = function getSubtype() {
if (!redeem)
return;
return redeem.getType();
type = redeem.getType();
return constants.scriptTypesByVal[type].toLowerCase();
};
/**

View File

@ -2334,6 +2334,196 @@ MapMember.fromPath = function fromPath(path) {
return new MapMember().fromPath(path);
};
function PathInfo(tx, table) {
// All relevant Wallet-ID/Accounts for
// inputs and outputs (for database indexing).
this.keys = [];
// All output paths (for deriving during sync).
this.paths = [];
// All output wallet IDs (for balance & syncing).
this.wallets = [];
// Map of address hashes->paths (for everything).
this.table = {};
if (tx)
this.fromTX(tx, table);
}
PathInfo.prototype.fromTX = function fromTX(tx, table) {
var i, j, keys, wallets, hashes, hash, paths, path, key;
this.table = table;
keys = {};
hashes = Object.keys(table);
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
paths = table[hash];
for (j = 0; j < paths.length; j++) {
path = paths[j];
key = path.id + '/' + path.account;
keys[key] = true;
}
}
this.keys = Object.keys(keys);
wallets = {};
hashes = tx.getOutputHashes('hex');
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
paths = table[hash];
for (j = 0; j < paths.length; j++) {
path = paths[j];
this.paths.push(path);
wallets[path.id] = true;
}
}
this.wallets = Object.keys(wallets);
};
PathInfo.fromTX = function fromTX(tx, table) {
return new PathInfo().fromTX(tx, table);
};
/**
* Test whether the map has paths
* for a given address hash.
* @param {Hash} address
* @returns {Boolean}
*/
PathInfo.prototype.hasPaths = function hasPaths(address) {
var paths;
if (!address)
return false;
paths = this.table[address];
return paths && paths.length !== 0;
};
/**
* Get paths for a given address hash.
* @param {Hash} address
* @returns {Path[]|null}
*/
PathInfo.prototype.getPaths = function getPaths(address) {
var paths;
if (!address)
return;
paths = this.table[address];
if (!paths || paths.length === 0)
return;
return paths;
};
function Details(tx, id, table) {
this.hash = tx.hash('hex');
this.height = tx.height;
this.block = tx.block;
this.index = tx.index;
this.confirmations = tx.getConfirmations();
this.ts = tx.ts;
this.ps = tx.ps;
this.fee = tx.getFee();
this.tx = tx;
this.inputs = [];
this.outputs = [];
if (id)
this.init(id, table);
}
Details.prototype._insert = function _insert(vector, target, id, table) {
var i, j, io, address, hash, paths, path, member;
for (i = 0; i < vector.length; i++) {
io = vector[i];
member = new DetailsMember();
if (io instanceof bcoin.input)
member.value = io.coin ? io.coin.value : 0;
else
member.value = io.value;
address = io.getAddress();
if (address) {
member.address = address;
hash = address.getHash('hex');
paths = table[hash];
for (j = 0; j < paths.length; j++) {
path = paths[j];
if (path.id === id) {
member.path = path;
break;
}
}
}
target.push(member);
}
};
Details.prototype.init = function init(id, table) {
this._insert(this.tx.inputs, this.inputs, id, table);
this._insert(this.tx.outputs, this.outputs, id, table);
};
Details.prototype.toJSON = function toJSON() {
return {
hash: utils.revHex(this.hash),
height: this.height,
block: this.block ? utils.revHex(this.block) : null,
ts: this.ts,
ps: this.ps,
index: this.index,
fee: utils.btc(this.fee),
confirmations: this.confirmations,
inputs: this.inputs.map(function(input) {
return input.toJSON();
}),
outputs: this.outputs.map(function(output) {
return output.toJSON();
}),
tx: this.tx.toRaw().toString('hex')
};
};
function DetailsMember() {
this.value = 0;
this.address = null;
this.path = null;
}
DetailsMember.prototype.toJSON = function toJSON() {
return {
value: utils.btc(this.value),
address: this.address
? this.address.toBase58()
: null,
path: this.path
? this.path.toJSON()
: null
};
};
/*
* Expose
*/

View File

@ -2192,7 +2192,7 @@ utils.toMap = function toMap(obj) {
/**
* Reverse a map.
* @param {Object} map
* @param {Object} Reversed map.
* @returns {Object} Reversed map.
*/
utils.revMap = function revMap(map) {
@ -2208,6 +2208,25 @@ utils.revMap = function revMap(map) {
return reversed;
};
/**
* Get object values.
* @param {Object} map
* @returns {Array} Values.
*/
utils.values = function values(map) {
var keys = Object.keys(map);
var out = [];
var i, key;
for (i = 0; i < keys.length; i++) {
key = keys[i];
out.push(map[key]);
}
return out;
};
/**
* Perform a binary search on a sorted array.
* @param {Array} items