fcoin/lib/indexer/records.js
Javed Khan 05794f5cb3
indexer: add module indexer
module indexer introduces a extensible architecture for indexing the
chain. It provides a base class which handles syncing with the chain,
handling re-orgs, interruptions, dynamic toggling, etc. TXIndexer
and AddrIndexer are provided for indexing transactions and addresses,
using the same flags as before i.e --index-tx and --index-address.
Indexes are stored in a different database and can be maintained
independently of the chain.
2019-05-15 12:02:41 -07:00

222 lines
3.6 KiB
JavaScript

/*!
* records.js - indexer records
* Copyright (c) 2018, the bcoin developers (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
/**
* @module lib/records
*/
const bio = require('bufio');
const util = require('../utils/util');
const consensus = require('../protocol/consensus');
/**
* Chain State
* @alias module:indexer.ChainState
*/
class ChainState {
/**
* Create a chain state.
* @constructor
*/
constructor() {
this.startHeight = 0;
this.height = 0;
}
/**
* Clone the state.
* @returns {ChainState}
*/
clone() {
const state = new ChainState();
state.startHeight = this.startHeight;
state.height = this.height;
return state;
}
/**
* Inject properties from serialized data.
* @private
* @param {Buffer} data
*/
fromRaw(data) {
const br = bio.read(data);
this.startHeight = br.readU32();
this.height = br.readU32();
return this;
}
/**
* Instantiate chain state from serialized data.
* @param {Buffer} data
* @returns {ChainState}
*/
static fromRaw(data) {
return new this().fromRaw(data);
}
/**
* Serialize the chain state.
* @returns {Buffer}
*/
toRaw() {
const bw = bio.write(8);
bw.writeU32(this.startHeight);
bw.writeU32(this.height);
return bw.render();
}
}
/**
* Block Meta
* @alias module:indexer.BlockMeta
*/
class BlockMeta {
/**
* Create block meta.
* @constructor
* @param {Hash} hash
* @param {Number} height
*/
constructor(hash, height) {
this.hash = hash || consensus.NULL_HASH;
this.height = height != null ? height : -1;
}
/**
* Clone the block.
* @returns {BlockMeta}
*/
clone() {
return new this.constructor(this.hash, this.height);
}
/**
* Get block meta hash as a buffer.
* @returns {Buffer}
*/
toHash() {
return Buffer.from(this.hash, 'hex');
}
/**
* Instantiate block meta from chain entry.
* @private
* @param {IndexEntry} entry
*/
fromEntry(entry) {
this.hash = entry.hash;
this.height = entry.height;
return this;
}
/**
* Instantiate block meta from json object.
* @private
* @param {Object} json
*/
fromJSON(json) {
this.hash = util.revHex(json.hash);
this.height = json.height;
return this;
}
/**
* Instantiate block meta from serialized tip data.
* @private
* @param {Buffer} data
*/
fromRaw(data) {
const br = bio.read(data);
this.hash = br.readHash('hex');
this.height = br.readI32();
return this;
}
/**
* Instantiate block meta from chain entry.
* @param {IndexEntry} entry
* @returns {BlockMeta}
*/
static fromEntry(entry) {
return new this().fromEntry(entry);
}
/**
* Instantiate block meta from json object.
* @param {Object} json
* @returns {BlockMeta}
*/
static fromJSON(json) {
return new this().fromJSON(json);
}
/**
* Instantiate block meta from serialized data.
* @param {Hash} hash
* @param {Buffer} data
* @returns {BlockMeta}
*/
static fromRaw(data) {
return new this().fromRaw(data);
}
/**
* Serialize the block meta.
* @returns {Buffer}
*/
toRaw() {
const bw = bio.write(36);
bw.writeHash(this.hash);
bw.writeI32(this.height);
return bw.render();
}
/**
* Convert the block meta to a more json-friendly object.
* @returns {Object}
*/
toJSON() {
return {
hash: util.revHex(this.hash),
height: this.height
};
}
}
/*
* Expose
*/
exports.ChainState = ChainState;
exports.BlockMeta = BlockMeta;
module.exports = exports;