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