chainentry refactor.
This commit is contained in:
parent
634290687b
commit
1aa70f8ff0
@ -25,7 +25,7 @@ var InvItem = bcoin.packets.InvItem;
|
||||
* @exports ChainEntry
|
||||
* @constructor
|
||||
* @param {Chain} chain
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
* @param {ChainEntry} prev
|
||||
* @property {Hash} hash
|
||||
* @property {Number} version - Transaction version. Note that BCoin reads
|
||||
@ -41,27 +41,73 @@ var InvItem = bcoin.packets.InvItem;
|
||||
* @property {ReversedHash} rhash - Reversed block hash (uint256le).
|
||||
*/
|
||||
|
||||
function ChainEntry(chain, data, prev) {
|
||||
function ChainEntry(chain, options, prev) {
|
||||
if (!(this instanceof ChainEntry))
|
||||
return new ChainEntry(chain, data);
|
||||
return new ChainEntry(chain, options, prev);
|
||||
|
||||
this.chain = chain;
|
||||
this.network = chain ? chain.network : bcoin.network.get();
|
||||
|
||||
this.network = this.chain
|
||||
? this.chain.network
|
||||
: bcoin.network.get();
|
||||
this.hash = constants.NULL_HASH;
|
||||
this.version = 1;
|
||||
this.prevBlock = constants.NULL_HASH;
|
||||
this.merkleRoot = constants.NULL_HASH;
|
||||
this.ts = 0;
|
||||
this.bits = 0;
|
||||
this.nonce = 0;
|
||||
this.height = -1;
|
||||
this.chainwork = null;
|
||||
|
||||
this.hash = data.hash;
|
||||
this.version = data.version;
|
||||
this.prevBlock = data.prevBlock;
|
||||
this.merkleRoot = data.merkleRoot;
|
||||
this.ts = data.ts;
|
||||
this.bits = data.bits;
|
||||
this.nonce = data.nonce;
|
||||
this.height = data.height;
|
||||
this.chainwork = data.chainwork || this.getChainwork(prev);
|
||||
if (options)
|
||||
this.fromOptions(options, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from options.
|
||||
* @private
|
||||
* @param {Object} options
|
||||
* @param {ChainEntry} prev - Previous entry.
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.fromOptions = function fromOptions(options, prev) {
|
||||
assert(options, 'Block data is required.');
|
||||
assert(typeof options.hash === 'string');
|
||||
assert(utils.isNumber(options.version));
|
||||
assert(typeof options.prevBlock === 'string');
|
||||
assert(typeof options.merkleRoot === 'string');
|
||||
assert(utils.isNumber(options.ts));
|
||||
assert(utils.isNumber(options.bits));
|
||||
assert(utils.isNumber(options.nonce));
|
||||
assert(!options.chainwork || bn.isBN(options.chainwork));
|
||||
|
||||
this.hash = options.hash;
|
||||
this.version = options.version;
|
||||
this.prevBlock = options.prevBlock;
|
||||
this.merkleRoot = options.merkleRoot;
|
||||
this.ts = options.ts;
|
||||
this.bits = options.bits;
|
||||
this.nonce = options.nonce;
|
||||
this.height = options.height;
|
||||
this.chainwork = options.chainwork;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* The max chainwork (1 << 256).
|
||||
* @const {BN}
|
||||
@ -401,6 +447,41 @@ ChainEntry.prototype.__defineGetter__('rhash', function() {
|
||||
return utils.revHex(this.hash);
|
||||
});
|
||||
|
||||
/**
|
||||
* Inject properties from block.
|
||||
* @private
|
||||
* @param {Block|MerkleBlock} block
|
||||
* @param {ChainEntry} prev - Previous entry.
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.fromBlock = function fromBlock(block, prev) {
|
||||
assert(block.height !== -1);
|
||||
|
||||
this.hash = block.hash('hex');
|
||||
this.version = block.version;
|
||||
this.prevBlock = block.prevBlock;
|
||||
this.merkleRoot = block.merkleRoot;
|
||||
this.ts = block.ts;
|
||||
this.bits = block.bits;
|
||||
this.nonce = block.nonce;
|
||||
this.height = block.height;
|
||||
this.chainwork = this.getChainwork(prev);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the entry to internal database format.
|
||||
* @returns {Buffer}
|
||||
@ -425,29 +506,39 @@ ChainEntry.prototype.toRaw = function toRaw(writer) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize the entry.
|
||||
* @param {Chain} chain
|
||||
* @param {Buffer} buf
|
||||
* @returns {ChainEntry}
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
ChainEntry.fromRaw = function fromRaw(chain, buf) {
|
||||
var p = new BufferReader(buf, true);
|
||||
ChainEntry.prototype.fromRaw = function fromRaw(data) {
|
||||
var p = new BufferReader(data, true);
|
||||
var hash = utils.hash256(p.readBytes(80));
|
||||
|
||||
p.seek(-80);
|
||||
|
||||
return new ChainEntry(chain, {
|
||||
hash: hash.toString('hex'),
|
||||
version: p.readU32(), // Technically signed
|
||||
prevBlock: p.readHash('hex'),
|
||||
merkleRoot: p.readHash('hex'),
|
||||
ts: p.readU32(),
|
||||
bits: p.readU32(),
|
||||
nonce: p.readU32(),
|
||||
height: p.readU32(),
|
||||
chainwork: new bn(p.readBytes(32), 'le')
|
||||
});
|
||||
this.hash = hash.toString('hex');
|
||||
this.version = p.readU32(); // Technically signed
|
||||
this.prevBlock = p.readHash('hex');
|
||||
this.merkleRoot = p.readHash('hex');
|
||||
this.ts = p.readU32();
|
||||
this.bits = p.readU32();
|
||||
this.nonce = p.readU32();
|
||||
this.height = p.readU32();
|
||||
this.chainwork = new bn(p.readBytes(32), 'le');
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize the entry.
|
||||
* @param {Chain} chain
|
||||
* @param {Buffer} data
|
||||
* @returns {ChainEntry}
|
||||
*/
|
||||
|
||||
ChainEntry.fromRaw = function fromRaw(chain, data) {
|
||||
return new ChainEntry(chain).fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -470,6 +561,36 @@ ChainEntry.prototype.toJSON = function toJSON() {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from json object.
|
||||
* @private
|
||||
* @param {Object} json
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.fromJSON = function fromJSON(json) {
|
||||
assert(json, 'Block data is required.');
|
||||
assert(typeof json.hash === 'string');
|
||||
assert(utils.isNumber(json.version));
|
||||
assert(typeof json.prevBlock === 'string');
|
||||
assert(typeof json.merkleRoot === 'string');
|
||||
assert(utils.isNumber(json.ts));
|
||||
assert(utils.isNumber(json.bits));
|
||||
assert(utils.isNumber(json.nonce));
|
||||
assert(typeof json.chainwork === 'string');
|
||||
|
||||
this.hash = utils.revHex(json.hash);
|
||||
this.version = json.version;
|
||||
this.prevBlock = utils.revHex(json.prevBlock);
|
||||
this.merkleRoot = utils.revHex(json.merkleRoot);
|
||||
this.ts = json.ts;
|
||||
this.bits = json.bits;
|
||||
this.nonce = json.nonce;
|
||||
this.height = json.height;
|
||||
this.chainwork = new bn(json.chainwork, 10);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate block from jsonified object.
|
||||
* @param {Chain} chain
|
||||
@ -478,17 +599,7 @@ ChainEntry.prototype.toJSON = function toJSON() {
|
||||
*/
|
||||
|
||||
ChainEntry.fromJSON = function fromJSON(chain, json) {
|
||||
return new ChainEntry(chain, {
|
||||
hash: utils.revHex(json.hash),
|
||||
version: json.version,
|
||||
prevBlock: utils.revHex(json.prevBlock),
|
||||
merkleRoot: utils.revHex(json.merkleRoot),
|
||||
ts: json.ts,
|
||||
bits: json.bits,
|
||||
nonce: json.nonce,
|
||||
height: json.height,
|
||||
chainwork: new bn(json.chainwork, 10)
|
||||
});
|
||||
return new ChainEntry(chain).fromJSON(json);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -526,7 +637,7 @@ ChainEntry.prototype.inspect = function inspect() {
|
||||
|
||||
ChainEntry.isChainEntry = function isChainEntry(obj) {
|
||||
return obj
|
||||
&& bn.isBN(obj.chainwork)
|
||||
&& obj.chainwork !== undefined
|
||||
&& typeof obj.getMedianTime === 'function';
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user