itns-sidechain/lib/primitives/headers.js

285 lines
5.7 KiB
JavaScript
Raw Normal View History

/*!
2016-02-24 06:41:16 -08:00
* headers.js - headers object for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
2017-02-03 22:47:26 -08:00
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
2016-06-09 16:18:50 -07:00
* https://github.com/bcoin-org/bcoin
2016-02-24 06:41:16 -08:00
*/
2016-06-13 01:06:01 -07:00
'use strict';
2017-11-16 11:43:24 -08:00
const bio = require('bufio');
2017-06-29 20:54:07 -07:00
const util = require('../utils/util');
const AbstractBlock = require('./abstractblock');
2016-02-24 06:41:16 -08:00
/**
2017-11-15 18:54:47 -08:00
* Headers
* Represents block headers obtained
* from the network via `headers`.
2017-02-03 22:47:26 -08:00
* @alias module:primitives.Headers
* @extends AbstractBlock
2016-02-24 06:41:16 -08:00
*/
2017-11-15 18:54:47 -08:00
class Headers extends AbstractBlock {
/**
* Create headers.
* @constructor
* @param {Object} options
*/
constructor(options) {
super();
if (options)
this.parseOptions(options);
}
/**
* Perform non-contextual
* verification on the headers.
* @returns {Boolean}
*/
verifyBody() {
return true;
}
/**
* Get size of the headers.
* @returns {Number}
*/
getSize() {
2017-12-31 15:08:01 -08:00
return this.sizeHead();
2017-11-15 18:54:47 -08:00
}
/**
* Serialize the headers to a buffer writer.
* @param {BufferWriter} bw
*/
toWriter(bw) {
this.writeHead(bw);
return bw;
}
/**
* Serialize the headers.
* @returns {Buffer|String}
*/
toRaw() {
const size = this.getSize();
2017-11-16 11:43:24 -08:00
return this.toWriter(bio.write(size)).render();
2017-11-15 18:54:47 -08:00
}
/**
* Inject properties from buffer reader.
* @private
* @param {Buffer} data
*/
fromReader(br) {
this.readHead(br);
return this;
}
/**
* Inject properties from serialized data.
* @private
* @param {Buffer} data
*/
fromRaw(data) {
2017-11-16 11:43:24 -08:00
return this.fromReader(bio.read(data));
2017-11-15 18:54:47 -08:00
}
/**
* Instantiate headers from buffer reader.
* @param {BufferReader} br
* @returns {Headers}
*/
static fromReader(br) {
return new this().fromReader(br);
}
/**
* Instantiate headers from serialized data.
* @param {Buffer} data
* @param {String?} enc - Encoding, can be `'hex'` or null.
* @returns {Headers}
*/
static fromRaw(data, enc) {
if (typeof data === 'string')
data = Buffer.from(data, enc);
return new this().fromRaw(data);
}
/**
* Instantiate headers from serialized data.
* @param {Buffer} data
* @param {String?} enc - Encoding, can be `'hex'` or null.
* @returns {Headers}
*/
static fromHead(data, enc) {
if (typeof data === 'string')
data = Buffer.from(data, enc);
return new this().fromHead(data);
}
/**
* Instantiate headers from a chain entry.
* @param {ChainEntry} entry
* @returns {Headers}
*/
static fromEntry(entry) {
const headers = new this();
headers.version = entry.version;
headers.prevBlock = entry.prevBlock;
headers.merkleRoot = entry.merkleRoot;
2017-12-31 15:08:01 -08:00
headers.witnessRoot = entry.witnessRoot;
headers.trieRoot = entry.trieRoot;
2017-11-15 18:54:47 -08:00
headers.time = entry.time;
headers.bits = entry.bits;
headers.nonce = entry.nonce;
2017-12-31 15:08:01 -08:00
headers.solution = entry.solution;
2017-11-15 18:54:47 -08:00
headers._hash = Buffer.from(entry.hash, 'hex');
headers._hhash = entry.hash;
return headers;
}
/**
* Convert the block to a headers object.
* @returns {Headers}
*/
toHeaders() {
return this;
}
/**
* Convert the block to a headers object.
* @param {Block|MerkleBlock} block
* @returns {Headers}
*/
static fromBlock(block) {
const headers = new this(block);
headers._hash = block._hash;
headers._hhash = block._hhash;
return headers;
}
/**
* Convert the block to an object suitable
* for JSON serialization.
* @returns {Object}
*/
toJSON() {
return this.getJSON();
}
/**
* Convert the block to an object suitable
* for JSON serialization. Note that the hashes
* will be reversed to abide by bitcoind's legacy
* of little-endian uint256s.
* @param {Network} network
* @param {CoinView} view
* @param {Number} height
* @returns {Object}
*/
getJSON(network, view, height) {
return {
hash: this.rhash(),
height: height,
version: this.version,
2017-11-17 00:00:36 -08:00
prevBlock: util.revHex(this.prevBlock),
merkleRoot: util.revHex(this.merkleRoot),
2017-12-31 15:08:01 -08:00
witnessRoot: util.revHex(this.witnessRoot),
trieRoot: util.revHex(this.trieRoot),
2017-11-15 18:54:47 -08:00
time: this.time,
bits: this.bits,
2017-12-31 15:08:01 -08:00
nonce: this.nonce.toString('hex'),
solution: this.solution.toJSON()
2017-11-15 18:54:47 -08:00
};
}
/**
* Inject properties from json object.
* @private
* @param {Object} json
*/
fromJSON(json) {
this.parseJSON(json);
return this;
}
/**
* Instantiate a merkle block from a jsonified block object.
* @param {Object} json - The jsonified block object.
* @returns {Headers}
*/
static fromJSON(json) {
return new this().fromJSON(json);
}
/**
* Inspect the headers and return a more
* user-friendly representation of the data.
* @returns {Object}
*/
inspect() {
return this.format();
}
/**
* Inspect the headers and return a more
* user-friendly representation of the data.
* @param {CoinView} view
* @param {Number} height
* @returns {Object}
*/
format(view, height) {
return {
hash: this.rhash(),
height: height != null ? height : -1,
date: util.date(this.time),
version: this.version.toString(16),
2017-11-17 00:00:36 -08:00
prevBlock: util.revHex(this.prevBlock),
merkleRoot: util.revHex(this.merkleRoot),
2017-12-31 15:08:01 -08:00
witnessRoot: util.revHex(this.witnessRoot),
trieRoot: util.revHex(this.trieRoot),
2017-11-15 18:54:47 -08:00
time: this.time,
bits: this.bits,
2017-12-31 15:08:01 -08:00
nonce: this.nonce.toString('hex'),
solution: this.solution
2017-11-15 18:54:47 -08:00
};
}
/**
* Test an object to see if it is a Headers object.
* @param {Object} obj
* @returns {Boolean}
*/
static isHeaders(obj) {
return obj instanceof Headers;
}
2016-02-24 06:41:16 -08:00
}
2016-05-15 18:07:06 -07:00
/*
* Expose
*/
2016-05-13 09:23:57 -07:00
module.exports = Headers;