UNPKG

@bpanel/bpanel-utils

Version:
313 lines (246 loc) 8.88 kB
/*! * chain.js - basic utilities for bpanel chain operations * Copyright (c) 2018, Bcoin Devs (MIT License). * https://github.com/bcoin-org/bpanel-utils */ 'use strict'; 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 };