216 lines
4.7 KiB
JavaScript
216 lines
4.7 KiB
JavaScript
/*!
|
|
* headers.js - headers object for hsd
|
|
* Copyright (c) 2017-2018, Christopher Jeffrey (MIT License).
|
|
* https://github.com/handshake-org/hsd
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const util = require('../utils/util');
|
|
const AbstractBlock = require('./abstractblock');
|
|
|
|
/** @typedef {import('bufio').BufferReader} BufferReader */
|
|
/** @typedef {import('../types').BufioWriter} BufioWriter */
|
|
/** @typedef {import('../types').NetworkType} NetworkType */
|
|
/** @typedef {import('../protocol/network')} Network */
|
|
/** @typedef {import('../blockchain/chainentry')} ChainEntry */
|
|
/** @typedef {import('../coins/coinview')} CoinView */
|
|
/** @typedef {import('./block')} Block */
|
|
/** @typedef {import('./merkleblock')} MerkleBlock */
|
|
|
|
/**
|
|
* Headers
|
|
* Represents block headers obtained
|
|
* from the network via `headers`.
|
|
* @alias module:primitives.Headers
|
|
* @extends AbstractBlock
|
|
*/
|
|
|
|
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() {
|
|
return this.sizeHead();
|
|
}
|
|
|
|
/**
|
|
* Serialize the headers to a buffer writer.
|
|
* @param {BufioWriter} bw
|
|
* @returns {BufioWriter}
|
|
*/
|
|
|
|
write(bw) {
|
|
this.writeHead(bw);
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Inject properties from buffer reader.
|
|
* @param {BufferReader} br
|
|
*/
|
|
|
|
read(br) {
|
|
this.readHead(br);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantiate headers from serialized data.
|
|
* @param {Buffer} data
|
|
* @returns {Headers}
|
|
*/
|
|
|
|
static fromHead(data) {
|
|
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;
|
|
headers.witnessRoot = entry.witnessRoot;
|
|
headers.treeRoot = entry.treeRoot;
|
|
headers.reservedRoot = entry.reservedRoot;
|
|
headers.time = entry.time;
|
|
headers.bits = entry.bits;
|
|
headers.nonce = entry.nonce;
|
|
headers.extraNonce = entry.extraNonce;
|
|
headers.mask = entry.mask;
|
|
headers._hash = 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;
|
|
return headers;
|
|
}
|
|
|
|
/**
|
|
* Convert the block to an object suitable
|
|
* for JSON serialization.
|
|
* @param {(NetworkType|Network)?} [network]
|
|
* @param {CoinView} [view]
|
|
* @param {Number} [height]
|
|
* @returns {Object}
|
|
*/
|
|
|
|
getJSON(network, view, height) {
|
|
return {
|
|
hash: this.hash().toString('hex'),
|
|
height: height,
|
|
version: this.version,
|
|
prevBlock: this.prevBlock.toString('hex'),
|
|
merkleRoot: this.merkleRoot.toString('hex'),
|
|
witnessRoot: this.witnessRoot.toString('hex'),
|
|
treeRoot: this.treeRoot.toString('hex'),
|
|
reservedRoot: this.reservedRoot.toString('hex'),
|
|
time: this.time,
|
|
bits: this.bits,
|
|
nonce: this.nonce,
|
|
extraNonce: this.extraNonce.toString('hex'),
|
|
mask: this.mask.toString('hex')
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Inject properties from json object.
|
|
* @param {Object} json
|
|
*/
|
|
|
|
fromJSON(json) {
|
|
this.parseJSON(json);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* 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.hash().toString('hex'),
|
|
height: height != null ? height : -1,
|
|
date: util.date(this.time),
|
|
version: this.version.toString(16),
|
|
prevBlock: this.prevBlock.toString('hex'),
|
|
merkleRoot: this.merkleRoot.toString('hex'),
|
|
witnessRoot: this.witnessRoot.toString('hex'),
|
|
treeRoot: this.treeRoot.toString('hex'),
|
|
reservedRoot: this.reservedRoot.toString('hex'),
|
|
time: this.time,
|
|
bits: this.bits,
|
|
nonce: this.nonce,
|
|
extraNonce: this.extraNonce.toString('hex'),
|
|
mask: this.mask.toString('hex')
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Test an object to see if it is a Headers object.
|
|
* @param {Object} obj
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
static isHeaders(obj) {
|
|
return obj instanceof Headers;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Expose
|
|
*/
|
|
|
|
module.exports = Headers;
|