Skip to content

Commit

Permalink
chain: alias all db methods. remove chainentry spaghetti code.
Browse files Browse the repository at this point in the history
  • Loading branch information
chjj committed Sep 6, 2017
1 parent b816434 commit 5f82c0d
Show file tree
Hide file tree
Showing 11 changed files with 641 additions and 480 deletions.
485 changes: 386 additions & 99 deletions lib/blockchain/chain.js

Large diffs are not rendered by default.

230 changes: 143 additions & 87 deletions lib/blockchain/chaindb.js

Large diffs are not rendered by default.

216 changes: 17 additions & 199 deletions lib/blockchain/chainentry.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ const ZERO = new BN(0);
* boot and recalculating the chainworks.
* @alias module:blockchain.ChainEntry
* @constructor
* @param {Chain} chain
* @param {Object} options
* @param {ChainEntry} prev
* @param {Object?} options
* @property {Hash} hash
* @property {Number} version - Transaction version. Note that Bcoin reads
* versions as unsigned even though they are signed at the protocol level.
Expand All @@ -44,11 +42,10 @@ const ZERO = new BN(0);
* @property {ReversedHash} rhash - Reversed block hash (uint256le).
*/

function ChainEntry(chain, options, prev) {
function ChainEntry(options) {
if (!(this instanceof ChainEntry))
return new ChainEntry(chain, options, prev);
return new ChainEntry(options);

this.chain = chain;
this.hash = encoding.NULL_HASH;
this.version = 1;
this.prevBlock = encoding.NULL_HASH;
Expand All @@ -60,7 +57,7 @@ function ChainEntry(chain, options, prev) {
this.chainwork = ZERO;

if (options)
this.fromOptions(options, prev);
this.fromOptions(options);
}

/**
Expand All @@ -70,22 +67,13 @@ function ChainEntry(chain, options, prev) {

ChainEntry.MAX_CHAINWORK = new BN(1).ushln(256);

/**
* Size of set to pick median time from.
* @const {Number}
* @default
*/

ChainEntry.MEDIAN_TIMESPAN = 11;

/**
* Inject properties from options.
* @private
* @param {Object} options
* @param {ChainEntry} prev - Previous entry.
*/

ChainEntry.prototype.fromOptions = function fromOptions(options, prev) {
ChainEntry.prototype.fromOptions = function fromOptions(options) {
assert(options, 'Block data is required.');
assert(typeof options.hash === 'string');
assert(util.isU32(options.version));
Expand All @@ -107,22 +95,18 @@ ChainEntry.prototype.fromOptions = function fromOptions(options, prev) {
this.height = options.height;
this.chainwork = options.chainwork || ZERO;

if (!this.chainwork)
this.chainwork = this.getChainwork(prev);

return this;
};

/**
* Instantiate chainentry from options.
* @param {Chain} chain
* @param {Object} options
* @param {ChainEntry} prev - Previous entry.
* @returns {ChainEntry}
*/

ChainEntry.fromOptions = function fromOptions(chain, options, prev) {
return new ChainEntry(chain).fromOptions(options, prev);
ChainEntry.fromOptions = function fromOptions(options, prev) {
return new ChainEntry().fromOptions(options, prev);
};

/**
Expand Down Expand Up @@ -160,178 +144,23 @@ ChainEntry.prototype.getChainwork = function getChainwork(prev) {
*/

ChainEntry.prototype.isGenesis = function isGenesis() {
return this.hash === this.chain.network.genesis.hash;
};

/**
* Test whether the entry is in the main chain.
* @method
* @returns {Promise} - Return Boolean.
*/

ChainEntry.prototype.isMainChain = async function isMainChain() {
if (this.hash === this.chain.tip.hash
|| this.hash === this.chain.network.genesis.hash) {
return true;
}

const entry = this.chain.db.getCache(this.height);

if (entry) {
if (entry.hash === this.hash)
return true;
return false;
}

if (await this.chain.db.getNextHash(this.hash))
return true;

return false;
};

/**
* Get ancestor by `height`.
* @method
* @param {Number} height
* @returns {Promise} - Returns ChainEntry[].
*/

ChainEntry.prototype.getAncestor = async function getAncestor(height) {
if (height < 0)
return null;

assert(height >= 0);
assert(height <= this.height);

if (await this.isMainChain())
return await this.chain.db.getEntry(height);

let entry = this;
while (entry.height !== height) {
entry = await entry.getPrevious();
assert(entry);
}

return entry;
};

/**
* Get previous entry.
* @returns {Promise} - Returns ChainEntry.
*/

ChainEntry.prototype.getPrevious = function getPrevious() {
return this.chain.db.getEntry(this.prevBlock);
};

/**
* Get previous cached entry.
* @returns {ChainEntry|null}
*/

ChainEntry.prototype.getPrevCache = function getPrevCache() {
return this.chain.db.getCache(this.prevBlock);
};

/**
* Get next entry.
* @method
* @returns {Promise} - Returns ChainEntry.
*/

ChainEntry.prototype.getNext = async function getNext() {
const hash = await this.chain.db.getNextHash(this.hash);

if (!hash)
return null;

return await this.chain.db.getEntry(hash);
};

/**
* Get next entry.
* @method
* @returns {Promise} - Returns ChainEntry.
*/

ChainEntry.prototype.getNextEntry = async function getNextEntry() {
const entry = await this.chain.db.getEntry(this.height + 1);

if (!entry)
return null;

// Not on main chain.
if (entry.prevBlock !== this.hash)
return null;

return entry;
};

/**
* Calculate median time past.
* @method
* @param {Number?} time
* @returns {Promise} - Returns Number.
*/

ChainEntry.prototype.getMedianTime = async function getMedianTime(time) {
let timespan = ChainEntry.MEDIAN_TIMESPAN;
const median = [];

// In case we ever want to check
// the MTP of the _current_ block
// (necessary for BIP148).
if (time != null) {
median.push(time);
timespan -= 1;
}

let entry = this;
for (let i = 0; i < timespan && entry; i++) {
median.push(entry.time);

const cache = entry.getPrevCache();

if (cache) {
entry = cache;
continue;
}

entry = await entry.getPrevious();
}

median.sort(cmp);

return median[median.length >>> 1];
};

/**
* Test whether the entry is potentially
* an ancestor of a checkpoint.
* @returns {Boolean}
*/

ChainEntry.prototype.isHistorical = function isHistorical() {
if (this.chain.options.checkpoints) {
if (this.height + 1 <= this.chain.network.lastCheckpoint)
return true;
}
return false;
return this.prevBlock === encoding.NULL_HASH;
};

/**
* Test whether the entry contains an unknown version bit.
* @param {Network} network
* @returns {Boolean}
*/

ChainEntry.prototype.hasUnknown = function hasUnknown() {
ChainEntry.prototype.hasUnknown = function hasUnknown(network) {
const bits = this.version & consensus.VERSION_TOP_MASK;
const topBits = consensus.VERSION_TOP_BITS;

if ((bits >>> 0) !== topBits)
return false;

return (this.version & this.chain.network.unknownBits) !== 0;
return (this.version & network.unknownBits) !== 0;
};

/**
Expand Down Expand Up @@ -375,14 +204,13 @@ ChainEntry.prototype.fromBlock = function fromBlock(block, prev) {

/**
* Instantiate chainentry from block.
* @param {Chain} chain
* @param {Block|MerkleBlock} block
* @param {ChainEntry} prev - Previous entry.
* @returns {ChainEntry}
*/

ChainEntry.fromBlock = function fromBlock(chain, block, prev) {
return new ChainEntry(chain).fromBlock(block, prev);
ChainEntry.fromBlock = function fromBlock(block, prev) {
return new ChainEntry().fromBlock(block, prev);
};

/**
Expand Down Expand Up @@ -432,13 +260,12 @@ ChainEntry.prototype.fromRaw = function fromRaw(data) {

/**
* Deserialize the entry.
* @param {Chain} chain
* @param {Buffer} data
* @returns {ChainEntry}
*/

ChainEntry.fromRaw = function fromRaw(chain, data) {
return new ChainEntry(chain).fromRaw(data);
ChainEntry.fromRaw = function fromRaw(data) {
return new ChainEntry().fromRaw(data);
};

/**
Expand Down Expand Up @@ -493,13 +320,12 @@ ChainEntry.prototype.fromJSON = function fromJSON(json) {

/**
* Instantiate block from jsonified object.
* @param {Chain} chain
* @param {Object} json
* @returns {ChainEntry}
*/

ChainEntry.fromJSON = function fromJSON(chain, json) {
return new ChainEntry(chain).fromJSON(json);
ChainEntry.fromJSON = function fromJSON(json) {
return new ChainEntry().fromJSON(json);
};

/**
Expand Down Expand Up @@ -541,14 +367,6 @@ ChainEntry.isChainEntry = function isChainEntry(obj) {
return obj instanceof ChainEntry;
};

/*
* Helpers
*/

function cmp(a, b) {
return a - b;
}

/*
* Expose
*/
Expand Down
Loading

0 comments on commit 5f82c0d

Please sign in to comment.