@bpanel/bpanel-utils
Version:
Utilities for bpanel
313 lines (246 loc) • 8.88 kB
JavaScript
/*!
* chain.js - basic utilities for bpanel chain operations
* Copyright (c) 2018, Bcoin Devs (MIT License).
* https://github.com/bcoin-org/bpanel-utils
*/
;
exports.__esModule = true;
exports.getBlocksInRange = exports.getBlockHeaderInfo = exports.getBlockInfo = exports.getBlock = undefined;
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
// utility to get a range of blocks (or just headers, in SPV mode)
var getBlocksInRange = exports.getBlocksInRange = function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(start, end) {
var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var SPV = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var blocks, height, block, _step, _block;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
// get all blocks from blockHeight `start` up to `start`+ n
// create an array of the blocks
blocks = [];
height = start;
if (!(start < end)) {
_context2.next = 28;
break;
}
// counting up
(0, _bsert2.default)(step > 0, 'Step needs to be greater than zero to count up');
case 4:
if (!(height < end)) {
_context2.next = 26;
break;
}
_context2.prev = 5;
if (!SPV) {
_context2.next = 12;
break;
}
_context2.next = 9;
return getBlockHeaderInfo(height);
case 9:
_context2.t0 = _context2.sent;
_context2.next = 15;
break;
case 12:
_context2.next = 14;
return getBlockInfo(height);
case 14:
_context2.t0 = _context2.sent;
case 15:
block = _context2.t0;
blocks.push(block);
height += step;
_context2.next = 24;
break;
case 20:
_context2.prev = 20;
_context2.t1 = _context2['catch'](5);
// eslint-disable-next-line no-console
console.log('Error retrieving block: ', _context2.t1);
return _context2.abrupt('return', blocks);
case 24:
_context2.next = 4;
break;
case 26:
_context2.next = 54;
break;
case 28:
if (!(start > end)) {
_context2.next = 54;
break;
}
// counting down
_step = step;
if (step >= 1) {
_step = -1;
} else {
(0, _bsert2.default)(step < 1, 'Step must be negative to countdown');
}
case 31:
if (!(height > end)) {
_context2.next = 54;
break;
}
_context2.prev = 32;
if (!SPV) {
_context2.next = 39;
break;
}
_context2.next = 36;
return getBlockHeaderInfo(height);
case 36:
_context2.t2 = _context2.sent;
_context2.next = 42;
break;
case 39:
_context2.next = 41;
return getBlockInfo(height);
case 41:
_context2.t2 = _context2.sent;
case 42:
_block = _context2.t2;
;
blocks.push(_block);
height += _step;
_context2.next = 52;
break;
case 48:
_context2.prev = 48;
_context2.t3 = _context2['catch'](32);
// eslint-disable-next-line no-console
console.log('Error retrieving block: ', _context2.t3);
height += _step;
// return blocks;
case 52:
_context2.next = 31;
break;
case 54:
return _context2.abrupt('return', blocks);
case 55:
case 'end':
return _context2.stop();
}
}
}, _callee2, this, [[5, 20], [32, 48]]);
}));
return function getBlocksInRange(_x8, _x9) {
return _ref2.apply(this, arguments);
};
}();
/*
* @const
* supported chains
*/
exports.calcProgress = calcProgress;
exports.isChainSupported = isChainSupported;
var _bsert = require('bsert');
var _bsert2 = _interopRequireDefault(_bsert);
var _clients = require('./clients');
var _helpers = require('./helpers');
var _helpers2 = _interopRequireDefault(_helpers);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Simple API call to retrieve a block at specified height or hash
// returns a promise
var getBlock = exports.getBlock = function getBlock(hashOrHeight) {
try {
var client = (0, _clients.getClient)();
return client.node.getBlock(hashOrHeight);
} catch (e) {
// eslint-disable-next-line no-console
console.error('There was a problem retrieving block: ', e);
}
};
/*
* Returns a promise to make an api call for block info
* @param {number|string} hashOrHeight - if number getblockbyheight
* else getblock (by hash)
* @param {boolean=true} [verbose] - true to get block details,
* false for just hex
* @param {boolean=false} [details] - true for tx details
* @returns {Promise}
*/
var getBlockInfo = exports.getBlockInfo = function getBlockInfo(hashOrHeight) {
var verbose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var details = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var client = (0, _clients.getClient)();
try {
if (typeof hashOrHeight === 'number') return client.node.execute('getblockbyheight', [hashOrHeight, verbose, details]);
if (typeof hashOrHeight === 'string') return client.node.execute('getblock', [hashOrHeight, verbose, details]);
throw new Error('Must pass either string for block hash or number for block height');
} catch (e) {
// eslint-disable-next-line no-console
console.error('There was a problem retrieving block: ', e);
}
};
/*
* SPV equivalent to getBlockInfo above
*/
var getBlockHeaderInfo = exports.getBlockHeaderInfo = function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(hashOrHeight) {
var verbose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var details = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var client, hash, blockHeader;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
client = (0, _clients.getClient)();
_context.prev = 1;
// If we're in SPV mode, try and get the block header
hash = hashOrHeight;
if (!(typeof hashOrHeight === 'number')) {
_context.next = 7;
break;
}
_context.next = 6;
return client.node.execute('getblockhash', [hashOrHeight]);
case 6:
hash = _context.sent;
case 7:
_context.next = 9;
return client.node.execute('getblockheader', [hash, true]);
case 9:
blockHeader = _context.sent;
return _context.abrupt('return', blockHeader);
case 13:
_context.prev = 13;
_context.t0 = _context['catch'](1);
// eslint-disable-next-line no-console
console.error('There was a problem retrieving block header: ', _context.t0);
case 16:
case 'end':
return _context.stop();
}
}
}, _callee, undefined, [[1, 13]]);
}));
return function getBlockHeaderInfo(_x5) {
return _ref.apply(this, arguments);
};
}();
function calcProgress(start, tip) {
var current = tip - start;
var end = _helpers2.default.now() - start - 40 * 60;
return Math.min(1, current / end);
}var CHAINS = ['bitcoin', 'bitcoincash', 'handshake'];
/*
* Whether or not the chain is supported
* @param {String} - chain
* @returns bool
*/
function isChainSupported(chain) {
return CHAINS.includes(chain);
}
exports.default = {
calcProgress: calcProgress,
getBlockInfo: getBlockInfo,
getBlock: getBlock,
getBlocksInRange: getBlocksInRange,
isChainSupported: isChainSupported,
CHAINS: CHAINS
};