misc: lint; modernization; tweak mempool cache/keys; tx page: don't show block header JSON tab for unconfirmed

This commit is contained in:
Dan Janosik 2023-03-22 12:07:26 -04:00
parent 81558b5829
commit 4aac1420b9
No known key found for this signature in database
GPG key ID: 70C0B166321C0AF8
16 changed files with 569 additions and 560 deletions

View file

@ -1,6 +1,6 @@
module.exports = {
"env": {
"browser": true,
"node": true,
"commonjs": true,
"es2021": true
},

4
app.js
View file

@ -95,7 +95,7 @@ const auth = require('./app/auth.js');
const sso = require('./app/sso.js');
const markdown = require("markdown-it")();
const v8 = require("v8");
var compression = require("compression");
const compression = require("compression");
const appUtils = require("@janoside/app-utils");
const s3Utils = appUtils.s3Utils;
@ -729,6 +729,8 @@ expressApp.onStartup = async () => {
global.coinConfig = coins[config.coin];
global.coinConfigs = coins;
global.SATS_PER_BTC = global.coinConfig.baseCurrencyUnit.multiplier;
global.specialTransactions = {};
global.specialBlocks = {};
global.specialAddresses = {};

View file

@ -1,8 +1,4 @@
const fs = require('fs');
const path = require('path');
const onHeaders = require('on-headers');
const os = require('os');
const v8 = require('v8');
const debug = require("debug");
const debugLog = debug("monitor");
const utils = require("./utils.js");

View file

@ -15,9 +15,10 @@ const md5 = require("md5");
const statTracker = require("../statTracker.js");
const async = require("async");
// choose one of the below: RPC to a node, or mock data while testing
const rpcApi = require("./rpcApi.js");
//var rpcApi = require("./mockApi.js");
//const rpcApi = require("./mockApi.js");
// this value should be incremented whenever data format changes, to avoid
@ -41,7 +42,6 @@ const SECONDS_PER_DAY = SECONDS_PER_HOUR * 24;
const miscCaches = [];
const blockCaches = [];
const txCaches = [];
@ -161,9 +161,9 @@ function tryCacheThenRpcApi(cache, cacheKey, cacheMaxAge, rpcApiFunction, cacheC
}
return new Promise(function(resolve, reject) {
var cacheResult = null;
let cacheResult = null;
var finallyFunc = function() {
let finallyFunc = function() {
if (cacheResult != null) {
resolve(cacheResult);
@ -346,10 +346,10 @@ async function getNextBlockEstimate() {
let txIndex = 1;
let feeRates = [];
blockTemplate.transactions.forEach(tx => {
var feeRate = tx.fee / tx.weight * 4;
let feeRate = tx.fee / tx.weight * 4;
if (tx.depends && tx.depends.length > 0) {
var totalFee = tx.fee;
var totalWeight = tx.weight;
let totalFee = tx.fee;
let totalWeight = tx.weight;
tx.depends.forEach(index => {
totalFee += blockTemplate.transactions[index - 1].fee;
@ -385,8 +385,8 @@ async function getNextBlockEstimate() {
}
const feeRateGroups = [];
var groupCount = 10;
for (var i = 0; i < groupCount; i++) {
let groupCount = 10;
for (let i = 0; i < groupCount; i++) {
feeRateGroups.push({
minFeeRate: minFeeRate + i * (maxFeeRate - minFeeRate) / groupCount,
maxFeeRate: minFeeRate + (i + 1) * (maxFeeRate - minFeeRate) / groupCount,
@ -396,11 +396,11 @@ async function getNextBlockEstimate() {
});
}
var txIncluded = 0;
let txIncluded = 0;
blockTemplate.transactions.forEach(tx => {
var feeRate = tx.avgFeeRate ? tx.avgFeeRate : (tx.fee / tx.weight * 4);
let feeRate = tx.avgFeeRate ? tx.avgFeeRate : (tx.fee / tx.weight * 4);
for (var i = 0; i < feeRateGroups.length; i++) {
for (let i = 0; i < feeRateGroups.length; i++) {
if (feeRate >= feeRateGroups[i].minFeeRate) {
if (feeRate < feeRateGroups[i].maxFeeRate) {
feeRateGroups[i].totalWeight += tx.weight;
@ -424,7 +424,7 @@ async function getNextBlockEstimate() {
const subsidy = coinConfig.blockRewardFunction(blockTemplate.height, global.activeBlockchain);
const totalFees = new Decimal(blockTemplate.coinbasevalue).dividedBy(coinConfig.baseCurrencyUnit.multiplier).minus(new Decimal(subsidy));
const totalFees = new Decimal(blockTemplate.coinbasevalue).dividedBy(SATS_PER_BTC).minus(new Decimal(subsidy));
return {
blockTemplate: blockTemplate,
@ -463,7 +463,7 @@ async function getDifficultyByBlockHeights(blockHeights) {
const results = {};
const neededBlockHeights = [];
for (var i = 0; i < blockHeights.length; i++) {
for (let i = 0; i < blockHeights.length; i++) {
let blockHeight = blockHeights[i];
let blockHeightStr = `${blockHeight}`;
@ -588,8 +588,8 @@ async function getTxStats(dataPtCount, blockStart, blockEnd) {
function getSmartFeeEstimates(mode, confTargetBlockCounts) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < confTargetBlockCounts.length; i++) {
let promises = [];
for (let i = 0; i < confTargetBlockCounts.length; i++) {
promises.push(getSmartFeeEstimate(mode, confTargetBlockCounts[i]));
}
@ -611,12 +611,12 @@ function getSmartFeeEstimate(mode, confTargetBlockCount) {
function getPeerSummary() {
return new Promise(function(resolve, reject) {
tryCacheThenRpcApi(miscCache, "getpeerinfo", ONE_SEC, rpcApi.getPeerInfo).then(function(getpeerinfo) {
var result = {};
let result = {};
result.getpeerinfo = getpeerinfo;
var versionSummaryMap = {};
for (var i = 0; i < getpeerinfo.length; i++) {
var x = getpeerinfo[i];
let versionSummaryMap = {};
for (let i = 0; i < getpeerinfo.length; i++) {
let x = getpeerinfo[i];
if (versionSummaryMap[x.subver] == null) {
versionSummaryMap[x.subver] = 0;
@ -625,8 +625,8 @@ function getPeerSummary() {
versionSummaryMap[x.subver]++;
}
var versionSummary = [];
for (var prop in versionSummaryMap) {
let versionSummary = [];
for (let prop in versionSummaryMap) {
if (versionSummaryMap.hasOwnProperty(prop)) {
versionSummary.push([prop, versionSummaryMap[prop]]);
}
@ -646,9 +646,9 @@ function getPeerSummary() {
let serviceNamesAvailable = false;
var servicesSummaryMap = {};
for (var i = 0; i < getpeerinfo.length; i++) {
var x = getpeerinfo[i];
let servicesSummaryMap = {};
for (let i = 0; i < getpeerinfo.length; i++) {
let x = getpeerinfo[i];
if (x.servicesnames) {
serviceNamesAvailable = true;
@ -670,8 +670,8 @@ function getPeerSummary() {
}
}
var servicesSummary = [];
for (var prop in servicesSummaryMap) {
let servicesSummary = [];
for (let prop in servicesSummaryMap) {
if (servicesSummaryMap.hasOwnProperty(prop)) {
servicesSummary.push([prop, servicesSummaryMap[prop]]);
}
@ -692,9 +692,9 @@ function getPeerSummary() {
if (getpeerinfo.length > 0 && getpeerinfo[0].connection_type) {
var connectionTypeSummaryMap = {};
for (var i = 0; i < getpeerinfo.length; i++) {
var x = getpeerinfo[i];
let connectionTypeSummaryMap = {};
for (let i = 0; i < getpeerinfo.length; i++) {
let x = getpeerinfo[i];
if (connectionTypeSummaryMap[x.connection_type] == null) {
connectionTypeSummaryMap[x.connection_type] = 0;
@ -703,8 +703,8 @@ function getPeerSummary() {
connectionTypeSummaryMap[x.connection_type]++;
}
var connectionTypeSummary = [];
for (var prop in connectionTypeSummaryMap) {
let connectionTypeSummary = [];
for (let prop in connectionTypeSummaryMap) {
if (connectionTypeSummaryMap.hasOwnProperty(prop)) {
connectionTypeSummary.push([prop, connectionTypeSummaryMap[prop]]);
}
@ -727,9 +727,9 @@ function getPeerSummary() {
if (getpeerinfo.length > 0 && getpeerinfo[0].network) {
var networkTypeSummaryMap = {};
for (var i = 0; i < getpeerinfo.length; i++) {
var x = getpeerinfo[i];
let networkTypeSummaryMap = {};
for (let i = 0; i < getpeerinfo.length; i++) {
let x = getpeerinfo[i];
if (networkTypeSummaryMap[x.network] == null) {
networkTypeSummaryMap[x.network] = 0;
@ -738,8 +738,8 @@ function getPeerSummary() {
networkTypeSummaryMap[x.network]++;
}
var networkTypeSummary = [];
for (var prop in networkTypeSummaryMap) {
let networkTypeSummary = [];
for (let prop in networkTypeSummaryMap) {
if (networkTypeSummaryMap.hasOwnProperty(prop)) {
networkTypeSummary.push([prop, networkTypeSummaryMap[prop]]);
}
@ -776,9 +776,9 @@ function getPeerSummary() {
function getMempoolTxids(limit, offset) {
return new Promise(function(resolve, reject) {
tryCacheThenRpcApi(miscCache, "getMempoolTxids", ONE_SEC, rpcApi.getAllMempoolTxids).then(function(resultTxids) {
var txids = [];
let txids = [];
for (var i = offset; (i < resultTxids.length && i < (offset + limit)); i++) {
for (let i = offset; (i < resultTxids.length && i < (offset + limit)); i++) {
txids.push(resultTxids[i]);
}
@ -804,8 +804,8 @@ function getBlockHashByHeight(blockHeight) {
function getBlocksByHeight(blockHeights) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < blockHeights.length; i++) {
let promises = [];
for (let i = 0; i < blockHeights.length; i++) {
promises.push(getBlockByHeight(blockHeights[i]));
}
@ -832,8 +832,8 @@ function getBlockHeaderByHeight(blockHeight) {
function getBlockHeadersByHeight(blockHeights) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < blockHeights.length; i++) {
let promises = [];
for (let i = 0; i < blockHeights.length; i++) {
promises.push(getBlockHeaderByHeight(blockHeights[i]));
}
@ -848,8 +848,8 @@ function getBlockHeadersByHeight(blockHeights) {
function getBlocksStatsByHeight(blockHeights) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < blockHeights.length; i++) {
let promises = [];
for (let i = 0; i < blockHeights.length; i++) {
promises.push(getBlockStatsByHeight(blockHeights[i]));
}
@ -870,13 +870,13 @@ function getBlockByHash(blockHash) {
function getBlocksByHash(blockHashes) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < blockHashes.length; i++) {
let promises = [];
for (let i = 0; i < blockHashes.length; i++) {
promises.push(getBlockByHash(blockHashes[i]));
}
Promise.all(promises).then(function(results) {
var result = {};
let result = {};
results.forEach(function(item) {
result[item.hash] = item;
@ -891,7 +891,7 @@ function getBlocksByHash(blockHashes) {
}
function getRawTransaction(txid, blockhash) {
var rpcApiFunction = function() {
let rpcApiFunction = function() {
return rpcApi.getRawTransaction(txid, blockhash);
};
@ -902,10 +902,10 @@ function getRawTransaction(txid, blockhash) {
This function pulls raw tx data and then summarizes the outputs. It's used in memory-constrained situations.
*/
function getSummarizedTransactionOutput(txid, voutIndex) {
var rpcApiFunction = function() {
let rpcApiFunction = function() {
return new Promise(function(resolve, reject) {
rpcApi.getRawTransaction(txid).then(function(rawTx) {
var vout = rawTx.vout[voutIndex];
let vout = rawTx.vout[voutIndex];
if (vout.scriptPubKey) {
if (vout.scriptPubKey.asm) {
delete vout.scriptPubKey.asm;
@ -979,8 +979,8 @@ function getAddress(address) {
function getRawTransactions(txids, blockhash) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < txids.length; i++) {
let promises = [];
for (let i = 0; i < txids.length; i++) {
promises.push(getRawTransaction(txids[i], blockhash));
}
@ -995,8 +995,9 @@ function getRawTransactions(txids, blockhash) {
async function getRawTransactionsByHeights(txids, blockHeightsByTxid) {
return Promise.all(txids.map(async txid => {
var blockheight = blockHeightsByTxid[txid];
var blockhash = blockheight ? await getBlockByHeight(blockheight) : null;
let blockheight = blockHeightsByTxid[txid];
let blockhash = blockheight ? await getBlockByHeight(blockheight) : null;
return getRawTransaction(txid, blockhash);
}))
}
@ -1008,7 +1009,7 @@ function buildBlockAnalysisData(blockHeight, blockHash, txids, txIndex, results,
return;
}
var txid = txids[txIndex];
let txid = txids[txIndex];
getRawTransactionsWithInputs([txid], -1, blockHash).then(function(txData) {
results.push(summarizeBlockAnalysisData(blockHeight, txData.transactions[0], txData.txInputsByTransaction[txid]));
@ -1018,7 +1019,7 @@ function buildBlockAnalysisData(blockHeight, blockHash, txids, txIndex, results,
}
function summarizeBlockAnalysisData(blockHeight, tx, inputs) {
var txSummary = {};
let txSummary = {};
txSummary.txid = tx.txid;
txSummary.version = tx.version;
@ -1041,7 +1042,7 @@ function summarizeBlockAnalysisData(blockHeight, tx, inputs) {
txSummary.totalDaysDestroyed = new Decimal(0);
if (txSummary.coinbase) {
var subsidy = global.coinConfig.blockRewardFunction(blockHeight, global.activeBlockchain);
let subsidy = global.coinConfig.blockRewardFunction(blockHeight, global.activeBlockchain);
txSummary.totalInput = txSummary.totalInput.plus(new Decimal(subsidy));
@ -1051,17 +1052,17 @@ function summarizeBlockAnalysisData(blockHeight, tx, inputs) {
});
} else {
for (var i = 0; i < tx.vin.length; i++) {
var vin = tx.vin[i];
for (let i = 0; i < tx.vin.length; i++) {
let vin = tx.vin[i];
var txSummaryVin = {
let txSummaryVin = {
txid: tx.vin[i].txid,
vout: tx.vin[i].vout,
sequence: tx.vin[i].sequence
};
if (inputs) {
var inputVout = inputs[i];
let inputVout = inputs[i];
txSummary.totalInput = txSummary.totalInput.plus(new Decimal(inputVout.value));
@ -1087,7 +1088,7 @@ function summarizeBlockAnalysisData(blockHeight, tx, inputs) {
txSummary.vout = [];
txSummary.totalOutput = new Decimal(0);
for (var i = 0; i < tx.vout.length; i++) {
for (let i = 0; i < tx.vout.length; i++) {
txSummary.totalOutput = txSummary.totalOutput.plus(new Decimal(tx.vout[i].value));
txSummary.vout.push({
@ -1117,7 +1118,7 @@ function getRawTransactionsWithInputs(txids, maxInputs=-1, blockhash) {
return new Promise(function(resolve, reject) {
getRawTransactions(txids, blockhash).then(function(transactions) {
var maxInputsTracked = config.site.txMaxInput;
let maxInputsTracked = config.site.txMaxInput;
if (maxInputs <= 0) {
maxInputsTracked = 1000000;
@ -1126,12 +1127,12 @@ function getRawTransactionsWithInputs(txids, maxInputs=-1, blockhash) {
maxInputsTracked = maxInputs;
}
var vinIds = [];
for (var i = 0; i < transactions.length; i++) {
var transaction = transactions[i];
let vinIds = [];
for (let i = 0; i < transactions.length; i++) {
let transaction = transactions[i];
if (transaction && transaction.vin) {
for (var j = 0; j < Math.min(maxInputsTracked, transaction.vin.length); j++) {
for (let j = 0; j < Math.min(maxInputsTracked, transaction.vin.length); j++) {
if (transaction.vin[j].txid) {
vinIds.push({txid:transaction.vin[j].txid, voutIndex:transaction.vin[j].vout});
}
@ -1139,30 +1140,31 @@ function getRawTransactionsWithInputs(txids, maxInputs=-1, blockhash) {
}
}
var promises = [];
let promises = [];
for (var i = 0; i < vinIds.length; i++) {
var vinId = vinIds[i];
for (let i = 0; i < vinIds.length; i++) {
let vinId = vinIds[i];
promises.push(getSummarizedTransactionOutput(vinId.txid, vinId.voutIndex));
}
Promise.all(promises).then(function(promiseResults) {
var summarizedTxOutputs = {};
for (var i = 0; i < promiseResults.length; i++) {
var summarizedTxOutput = promiseResults[i];
let summarizedTxOutputs = {};
for (let i = 0; i < promiseResults.length; i++) {
let summarizedTxOutput = promiseResults[i];
summarizedTxOutputs[`${summarizedTxOutput.txid}:${summarizedTxOutput.n}`] = summarizedTxOutput;
}
var txInputsByTransaction = {};
let txInputsByTransaction = {};
transactions.forEach(function(tx) {
txInputsByTransaction[tx.txid] = {};
if (tx && tx.vin) {
for (var i = 0; i < Math.min(maxInputsTracked, tx.vin.length); i++) {
var summarizedTxOutput = summarizedTxOutputs[`${tx.vin[i].txid}:${tx.vin[i].vout}`];
for (let i = 0; i < Math.min(maxInputsTracked, tx.vin.length); i++) {
let summarizedTxOutput = summarizedTxOutputs[`${tx.vin[i].txid}:${tx.vin[i].vout}`];
if (summarizedTxOutput) {
txInputsByTransaction[tx.txid][i] = summarizedTxOutput;
}
@ -1179,14 +1181,14 @@ function getRawTransactionsWithInputs(txids, maxInputs=-1, blockhash) {
function getBlockByHashWithTransactions(blockHash, txLimit, txOffset) {
return new Promise(function(resolve, reject) {
getBlockByHash(blockHash).then(function(block) {
var txids = [];
let txids = [];
// to get miner info, always include the coinbase tx in the list
if (txOffset > 0) {
txids.push(block.tx[0]);
}
for (var i = txOffset; i < Math.min(txOffset + txLimit, block.tx.length); i++) {
for (let i = txOffset; i < Math.min(txOffset + txLimit, block.tx.length); i++) {
txids.push(block.tx[i]);
}
@ -1250,7 +1252,7 @@ function buildMiningSummary(statusId, startBlock, endBlock, statusFunc) {
const minerInfoByName = {};
for (var i = startBlock; i <= endBlock; i++) {
for (let i = startBlock; i <= endBlock; i++) {
const height = i;
const cacheKey = `${height}`;
@ -1283,7 +1285,7 @@ function buildMiningSummary(statusId, startBlock, endBlock, statusFunc) {
const totalFees = utils.getBlockTotalFeesFromCoinbaseTxAndBlockHeight(coinbaseTx, height);
const subsidy = coinConfig.blockRewardFunction(height, global.activeBlockchain);
var minerName = "Unknown";
let minerName = "Unknown";
if (minerInfo) {
if (minerInfo.type == "address-only") {
minerName = "address-only:" + minerInfo.name;
@ -1331,7 +1333,7 @@ function buildMiningSummary(statusId, startBlock, endBlock, statusFunc) {
}
var summary = {
let summary = {
miners:{},
minerNamesSortedByBlockCount: [],
overall:{
@ -1339,7 +1341,7 @@ function buildMiningSummary(statusId, startBlock, endBlock, statusFunc) {
}
};
for (var height = startBlock; height <= endBlock; height++) {
for (let height = startBlock; height <= endBlock; height++) {
const blockSummary = summariesByHeight[height];
const miner = blockSummary.mn;
@ -1390,6 +1392,9 @@ function buildMiningSummary(statusId, startBlock, endBlock, statusFunc) {
let mempoolTxSummaryCache = {};
let mempoolCacheKeyForTxid = (txid) => {
return txid.substring(0, 10);
};
function getCachedMempoolTxSummaries() {
return new Promise(async (resolve, reject) => {
@ -1404,9 +1409,9 @@ function getCachedMempoolTxSummaries() {
const results = [];
const txidKeysForCachePurge = {};
for (var i = 0; i < txids.length; i++) {
for (let i = 0; i < txids.length; i++) {
const txid = txids[i];
const key = txid.substring(0, 6);
const key = mempoolCacheKeyForTxid(txid);
txidKeysForCachePurge[key] = 1;
if (mempoolTxSummaryCache[key]) {
@ -1424,8 +1429,9 @@ function getCachedMempoolTxSummaries() {
// cleanup cache, but we don't need to wait for it to finish before resolving
new Promise((resolve, reject) => {
// purge items from cache that are no longer present in mempool
var keysToDelete = [];
for (var key in mempoolTxSummaryCache) {
let keysToDelete = [];
for (let key in mempoolTxSummaryCache) {
if (!txidKeysForCachePurge[key]) {
keysToDelete.push(key);
}
@ -1446,7 +1452,7 @@ function getCachedMempoolTxSummaries() {
}
const mempoolTxFileCache = utils.fileCache(config.filesystemCacheDir, `mempool-tx-summaries`);
const mempoolTxFileCache = utils.fileCache(config.filesystemCacheDir, `mempool-tx-summaries`, 2);
function getMempoolTxSummaries(allTxids, statusId, statusFunc) {
return new Promise(async (resolve, reject) => {
@ -1458,7 +1464,7 @@ function getMempoolTxSummaries(allTxids, statusId, statusFunc) {
const txids = allTxids;
const txidCount = txids.length;
var doneCount = 0;
let doneCount = 0;
const statusUpdate = () => { statusFunc({count: txidCount, done: doneCount}); };
@ -1466,9 +1472,13 @@ function getMempoolTxSummaries(allTxids, statusId, statusFunc) {
const results = [];
const txidKeysForCachePurge = {};
for (var i = 0; i < txids.length; i++) {
const btcToSat = (btcFloat) => {
return parseInt(new Decimal(btcFloat).times(SATS_PER_BTC).toDP(0));
};
for (let i = 0; i < txids.length; i++) {
const txid = txids[i];
const key = txid.substring(0, 6);
const key = mempoolCacheKeyForTxid(txid);
txidKeysForCachePurge[key] = 1;
if (mempoolTxSummaryCache[key]) {
@ -1485,12 +1495,12 @@ function getMempoolTxSummaries(allTxids, statusId, statusFunc) {
try {
const item = await getMempoolTxDetails(txid, false);
const itemSummary = {
f: item.entry.fees.modified,
f: btcToSat(item.entry.fees.modified),
af: item.entry.fees.ancestor,
af: btcToSat(item.entry.fees.ancestor),
asz: item.entry.ancestorsize,
a: item.entry.depends.map(x => x.substring(0, 6)),
a: item.entry.depends.map(x => mempoolCacheKeyForTxid(x)),
t: item.entry.time,
w: item.entry.weight ? item.entry.weight : item.entry.size * 4,
@ -1527,8 +1537,8 @@ function getMempoolTxSummaries(allTxids, statusId, statusFunc) {
// purge items from cache that are no longer present in mempool
var keysToDelete = [];
for (var key in mempoolTxSummaryCache) {
let keysToDelete = [];
for (let key in mempoolTxSummaryCache) {
if (!txidKeysForCachePurge[key]) {
keysToDelete.push(key);
}
@ -1565,23 +1575,21 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
const txids = allTxids;
var summary = [];
let maxFee = 0;
let maxFeePerByte = 0;
let maxAge = 0;
let maxSize = 0;
let ages = [];
let sizes = [];
let topfees = [];
var maxFee = 0;
var maxFeePerByte = 0;
var maxAge = 0;
var maxSize = 0;
var ages = [];
var sizes = [];
var topfees = [];
for (let i = 0; i < txSummaries.length; i++) {
let summary = txSummaries[i];
for (var i = 0; i < txSummaries.length; i++) {
var summary = txSummaries[i];
var fee = summary.f;
var size = summary.w / 4; // TOOD: hack
var feePerByte = summary.f / summary.w;
var age = Date.now() / 1000 - summary.t;
let fee = summary.f;
let size = summary.w / 4; // TOOD: hack
let feePerByte = summary.f / summary.w;
let age = Date.now() / 1000 - summary.t;
if (fee > maxFee) {
maxFee = fee;
@ -1641,16 +1649,16 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
let satoshiPerByteBucketMaxima = feeSatoshiBuckets;
var bucketCount = satoshiPerByteBucketMaxima.length + 1;
let bucketCount = satoshiPerByteBucketMaxima.length + 1;
var satoshiPerByteBuckets = [];
var satoshiPerByteBucketLabels = [];
let satoshiPerByteBuckets = [];
let satoshiPerByteBucketLabels = [];
//satoshiPerByteBucketLabels[0] = ("[0 - " + satoshiPerByteBucketMaxima[0] + ")");
for (var i = 1; i < bucketCount; i++) {
for (let i = 1; i < bucketCount; i++) {
satoshiPerByteBuckets.push({
count: 0,
totalFees: 0,
totalFees: new Decimal(0),
totalBytes: 0,
totalWeight: 0,
minFeeRate: satoshiPerByteBucketMaxima[i - 1],
@ -1662,39 +1670,39 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
}
}
var ageBucketCount = sizeBuckets;
var ageBucketTxCounts = [];
var ageBucketLabels = [];
let ageBucketCount = sizeBuckets;
let ageBucketTxCounts = [];
let ageBucketLabels = [];
var sizeBucketCount = sizeBuckets;
var sizeBucketTxCounts = [];
var sizeBucketLabels = [];
let sizeBucketCount = sizeBuckets;
let sizeBucketTxCounts = [];
let sizeBucketLabels = [];
var topfeeBucketCount = sizeBuckets;
var topfeeBucketTxCounts = [];
var topfeeBucketLabels = [];
let topfeeBucketCount = sizeBuckets;
let topfeeBucketTxCounts = [];
let topfeeBucketLabels = [];
for (var i = 0; i < ageBucketCount; i++) {
var rangeMin = i * maxAge / ageBucketCount;
var rangeMax = (i + 1) * maxAge / ageBucketCount;
for (let i = 0; i < ageBucketCount; i++) {
let rangeMin = i * maxAge / ageBucketCount;
let rangeMax = (i + 1) * maxAge / ageBucketCount;
ageBucketTxCounts.push(0);
if (maxAge > 60 * 60 * 24) {
var rangeMinutesMin = new Decimal(rangeMin / 60 / 60 / 24).toFixed(1);
var rangeMinutesMax = new Decimal(rangeMax / 60 / 60 / 24).toFixed(1);
let rangeMinutesMin = new Decimal(rangeMin / 60 / 60 / 24).toFixed(1);
let rangeMinutesMax = new Decimal(rangeMax / 60 / 60 / 24).toFixed(1);
ageBucketLabels.push(rangeMinutesMax + "d");
} else if (maxAge > 60 * 60) {
var rangeMinutesMin = new Decimal(rangeMin / 60 / 60).toFixed(1);
var rangeMinutesMax = new Decimal(rangeMax / 60 / 60).toFixed(1);
let rangeMinutesMin = new Decimal(rangeMin / 60 / 60).toFixed(1);
let rangeMinutesMax = new Decimal(rangeMax / 60 / 60).toFixed(1);
ageBucketLabels.push(rangeMinutesMax + "m");
} else if (maxAge > 60 * 10) {
var rangeMinutesMin = new Decimal(rangeMin / 60).toFixed(1);
var rangeMinutesMax = new Decimal(rangeMax / 60).toFixed(1);
let rangeMinutesMin = new Decimal(rangeMin / 60).toFixed(1);
let rangeMinutesMax = new Decimal(rangeMax / 60).toFixed(1);
ageBucketLabels.push(rangeMinutesMax + "m");
@ -1703,7 +1711,7 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
}
}
for (var i = 0; i < sizeBucketCount; i++) {
for (let i = 0; i < sizeBucketCount; i++) {
sizeBucketTxCounts.push(0);
if (i == sizeBucketCount - 1) {
@ -1721,9 +1729,9 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
const oldestLargestCount = 20;
var summary = {
let summary = {
"count": 0,
"totalFees": 0,
"totalFees": new Decimal(0),
"totalBytes": 0,
"totalWeight": 0,
"satoshiPerByteBuckets": satoshiPerByteBuckets,
@ -1738,12 +1746,12 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
};
for (var i = 0; i < oldestLargestCount; i++) {
for (let i = 0; i < oldestLargestCount; i++) {
let oldTx = summary.oldestTxs[i];
let largeTx = summary.largestTxs[i];
let topfeeTx = summary.highestFeeTxs[i];
for (var j = 0; j < txSummaries.length; j++) {
for (let j = 0; j < txSummaries.length; j++) {
if (oldTx && txids[j].startsWith(oldTx.txidKey)) {
oldTx.txid = txids[j];
@ -1751,7 +1759,7 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
}
}
for (var j = 0; j < txids.length; j++) {
for (let j = 0; j < txids.length; j++) {
if (largeTx && txids[j].startsWith(largeTx.txidKey)) {
largeTx.txid = txids[j];
@ -1759,7 +1767,7 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
}
}
for (var j = 0; j < txSummaries.length; j++) {
for (let j = 0; j < txSummaries.length; j++) {
if (topfeeTx && txids[j].startsWith(topfeeTx.txidKey)) {
topfeeTx.txid = txids[j];
@ -1768,20 +1776,20 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
}
}
for (var x = 0; x < txSummaries.length; x++) {
var txMempoolInfo = txSummaries[x];
var fee = txMempoolInfo.f;
var size = txMempoolInfo.w / 4;
var weight = txMempoolInfo.w;
var feePerByte = txMempoolInfo.f / weight;
var satoshiPerByte = feePerByte * 100000000; // TODO: magic number - replace with coinConfig.baseCurrencyUnit.multiplier
var age = Date.now() / 1000 - txMempoolInfo.t;
for (let x = 0; x < txSummaries.length; x++) {
let txMempoolInfo = txSummaries[x];
let fee = txMempoolInfo.f;
let size = txMempoolInfo.w / 4;
let weight = txMempoolInfo.w;
let feePerByte = new Decimal(txMempoolInfo.f).dividedBy(SATS_PER_BTC).toNumber() / weight;
let satoshiPerByte = feePerByte * SATS_PER_BTC;
let age = Date.now() / 1000 - txMempoolInfo.t;
var addedToBucket = false;
for (var i = 0; i < satoshiPerByteBuckets.length; i++) {
let addedToBucket = false;
for (let i = 0; i < satoshiPerByteBuckets.length; i++) {
if (satoshiPerByteBuckets[i].maxFeeRate > satoshiPerByte) {
satoshiPerByteBuckets[i]["count"]++;
satoshiPerByteBuckets[i]["totalFees"] += fee;
satoshiPerByteBuckets[i]["totalFees"] = satoshiPerByteBuckets[i]["totalFees"].plus(new Decimal(fee).dividedBy(SATS_PER_BTC));
satoshiPerByteBuckets[i]["totalBytes"] += size;
satoshiPerByteBuckets[i]["totalWeight"] += weight;
@ -1793,27 +1801,27 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
if (!addedToBucket) {
satoshiPerByteBuckets[bucketCount - 2]["count"]++;
satoshiPerByteBuckets[bucketCount - 2]["totalFees"] += fee;
satoshiPerByteBuckets[bucketCount - 2]["totalFees"] = satoshiPerByteBuckets[bucketCount - 2]["totalFees"].plus(new Decimal(fee).dividedBy(SATS_PER_BTC));
satoshiPerByteBuckets[bucketCount - 2]["totalBytes"] += size;
satoshiPerByteBuckets[bucketCount - 2]["totalWeight"] += weight;
}
summary["count"]++;
summary["totalFees"] += fee;
summary["totalFees"] = summary.totalFees.plus(new Decimal(fee).dividedBy(SATS_PER_BTC));
summary["totalBytes"] += size;
summary["totalWeight"] += weight;
var ageBucketIndex = Math.min(ageBucketCount - 1, parseInt(age / (maxAge / ageBucketCount)));
var sizeBucketIndex = Math.min(sizeBucketCount - 1, parseInt(size / (maxSize / sizeBucketCount)));
let ageBucketIndex = Math.min(ageBucketCount - 1, parseInt(age / (maxAge / ageBucketCount)));
let sizeBucketIndex = Math.min(sizeBucketCount - 1, parseInt(size / (maxSize / sizeBucketCount)));
ageBucketTxCounts[ageBucketIndex]++;
sizeBucketTxCounts[sizeBucketIndex]++;
}
var topTargetPercent = 0.25;
var totWeight = 0;
var topIndex = -1;
for (var i = satoshiPerByteBuckets.length - 1; i >= 0; i--) {
let topTargetPercent = 0.25;
let totWeight = 0;
let topIndex = -1;
for (let i = satoshiPerByteBuckets.length - 1; i >= 0; i--) {
totWeight += satoshiPerByteBuckets[i].totalWeight;
if (totWeight / summary.totalWeight * 100 > topTargetPercent) {
@ -1834,9 +1842,9 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
satoshiPerByteBuckets[topIndex].buckets = 0;
// merge the top buckets into one
for (var i = topIndex + 1; i < satoshiPerByteBuckets.length; i++) {
for (let i = topIndex + 1; i < satoshiPerByteBuckets.length; i++) {
satoshiPerByteBuckets[topIndex].count += satoshiPerByteBuckets[i].count;
satoshiPerByteBuckets[topIndex].totalFees += satoshiPerByteBuckets[i].totalFees;
satoshiPerByteBuckets[topIndex].totalFees = satoshiPerByteBuckets[topIndex].totalFees.plus(satoshiPerByteBuckets[i].totalFees);
satoshiPerByteBuckets[topIndex].totalBytes += satoshiPerByteBuckets[i].totalBytes;
satoshiPerByteBuckets[topIndex].totalWeight += satoshiPerByteBuckets[i].totalWeight;
satoshiPerByteBuckets[topIndex].buckets++;
@ -1854,7 +1862,7 @@ function buildMempoolSummary(statusId, ageBuckets, sizeBuckets, statusFunc) {
summary["satoshiPerByteBucketCounts"] = [];
summary["satoshiPerByteBucketTotalFees"] = [];
for (var i = 0; i < satoshiPerByteBuckets.length; i++) {
for (let i = 0; i < satoshiPerByteBuckets.length; i++) {
summary["satoshiPerByteBucketCounts"].push(summary["satoshiPerByteBuckets"][i]["count"]);
summary["satoshiPerByteBucketTotalFees"].push(summary["satoshiPerByteBuckets"][i]["totalFees"]);
}
@ -1914,7 +1922,7 @@ function buildPredictedBlocks(statusId, statusFunc) {
for (let i = 0; i < txSummaries.length; i++) {
let tx = txSummaries[i];
let feeRate = 4 * 100000000 * (tx.f + tx.af) / (tx.w + tx.asz * 4);
let feeRate = 4 * (tx.f + tx.af) / (tx.w + tx.asz * 4);
//console.log("fr: " + feeRate);
txSummariesByKey[tx.key] = tx;
@ -1934,7 +1942,7 @@ function buildPredictedBlocks(statusId, statusFunc) {
while (unAddedTxIndexes.length > 0 && blocks.length < 20) {
//console.log("txids: " + addedTxids.length);
var currentBlock = {
let currentBlock = {
weight: 0,
totalFees: new Decimal(0),
vB: 0,
@ -1995,7 +2003,7 @@ function buildPredictedBlocks(statusId, statusFunc) {
currentBlock.totalFees = currentBlock.totalFees.plus(new Decimal(tx.f)).plus(new Decimal(tx.af));
currentBlock.vB += weightWithAncestors / 4;
let feeRate = tx.frw * 100000000;
let feeRate = tx.frw;
if (feeRate > currentBlock.maxFeeRate) {
currentBlock.maxFeeRate = feeRate;
@ -2105,18 +2113,18 @@ function getTxOut(txid, vout) {
function getHelp() {
return new Promise(function(resolve, reject) {
tryCacheThenRpcApi(miscCache, "getHelp", ONE_DAY, rpcApi.getHelp).then(function(helpContent) {
var lines = helpContent.split("\n");
var sections = [];
let lines = helpContent.split("\n");
let sections = [];
lines.forEach(function(line) {
if (line.startsWith("==")) {
var sectionName = line.substring(2);
let sectionName = line.substring(2);
sectionName = sectionName.substring(0, sectionName.length - 2).trim();
sections.push({name:sectionName, methods:[]});
} else if (line.trim().length > 0) {
var methodName = line.trim();
let methodName = line.trim();
if (methodName.includes(" ")) {
methodName = methodName.substring(0, methodName.indexOf(" "));
@ -2135,20 +2143,20 @@ function getHelp() {
}
function getRpcMethodHelp(methodName) {
var rpcApiFunction = function() {
let rpcApiFunction = function() {
return rpcApi.getRpcMethodHelp(methodName);
};
return new Promise(function(resolve, reject) {
tryCacheThenRpcApi(miscCache, "getHelp-" + methodName, ONE_DAY, rpcApiFunction).then(function(helpContent) {
var output = {};
let output = {};
output.string = helpContent;
var str = helpContent;
let str = helpContent;
var lines = str.split("\n");
var argumentLines = [];
var catchArgs = false;
let lines = str.split("\n");
let argumentLines = [];
let catchArgs = false;
lines.forEach(function(line) {
if (line.trim().length == 0) {
catchArgs = false;
@ -2163,13 +2171,13 @@ function getRpcMethodHelp(methodName) {
}
});
var args = [];
var argX = null;
let args = [];
let argX = null;
// looking for line starting with "N. " where N is an integer (1-2 digits)
argumentLines.forEach(function(line) {
var regex = /^([0-9]+)\.\s*"?(\w+)"?\s*\(([^,)]*),?\s*([^,)]*),?\s*([^,)]*),?\s*([^,)]*)?\s*\)\s*(.+)?$/;
let regex = /^([0-9]+)\.\s*"?(\w+)"?\s*\(([^,)]*),?\s*([^,)]*),?\s*([^,)]*),?\s*([^,)]*)?\s*\)\s*(.+)?$/;
var match = regex.exec(line);
let match = regex.exec(line);
if (match) {
argX = {};
@ -2217,9 +2225,9 @@ function getRpcMethodHelp(methodName) {
}
function logCacheSizes() {
var itemCounts = [ miscCache.itemCount, blockCache.itemCount, txCache.itemCount ];
let itemCounts = [ miscCache.itemCount, blockCache.itemCount, txCache.itemCount ];
var stream = fs.createWriteStream("memoryUsage.csv", {flags:'a'});
let stream = fs.createWriteStream("memoryUsage.csv", {flags:'a'});
stream.write("itemCounts: " + JSON.stringify(itemCounts) + "\n");
stream.end();
}

View file

@ -35,7 +35,7 @@ function connectToServers() {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < config.electrumServers.length; i++) {
for (let i = 0; i < config.electrumServers.length; i++) {
var { host, port, protocol } = config.electrumServers[i];
promises.push(connectToServer(host, port, protocol));
@ -89,7 +89,7 @@ function connectToServer(host, port, protocol) {
statTracker.trackEvent("electrum.disconnected");
var index = electrumClients.indexOf(client);
let index = electrumClients.indexOf(client);
if (index > -1) {
electrumClients.splice(index, 1);
@ -152,7 +152,7 @@ function runOnAllServers(f) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < electrumClients.length; i++) {
for (let i = 0; i < electrumClients.length; i++) {
promises.push(runOnServer(electrumClients[i], f));
}
@ -224,7 +224,7 @@ function getAddressDetails(address, scriptPubkey, sort, limit, offset) {
txidData.reverse();
}
for (var i = offset; i < Math.min(txidData.length, limit + offset); i++) {
for (let i = offset; i < Math.min(txidData.length, limit + offset); i++) {
addressDetails.txids.push(txidData[i].tx_hash);
addressDetails.blockHeightsByTxid[txidData[i].tx_hash] = txidData[i].height;
}
@ -245,7 +245,7 @@ function getAddressDetails(address, scriptPubkey, sort, limit, offset) {
errors.push(x);
errorStrs.push(JSON.stringify(x));
}
});
});
resolve({addressDetails:addressDetails, errors:errors});
});
@ -265,7 +265,7 @@ function getAddressTxids(addrScripthash) {
logStats("blockchainScripthash_getHistory", new Date().getTime() - startTime, true);
if (addrScripthash == coinConfig.genesisCoinbaseOutputAddressScripthash) {
for (var i = 0; i < results.length; i++) {
for (let i = 0; i < results.length; i++) {
results[i].result.unshift({tx_hash:coinConfig.genesisCoinbaseTransactionIdsByNetwork[global.activeBlockchain], height:0});
}
}
@ -273,7 +273,7 @@ function getAddressTxids(addrScripthash) {
var first = results[0];
var done = false;
for (var i = 1; i < results.length; i++) {
for (let i = 1; i < results.length; i++) {
if (results[i].length != first.length) {
resolve({conflictedResults:results});
@ -305,7 +305,7 @@ function getAddressBalance(addrScripthash) {
logStats("blockchainScripthash_getBalance", new Date().getTime() - startTime, true);
if (addrScripthash == coinConfig.genesisCoinbaseOutputAddressScripthash) {
for (var i = 0; i < results.length; i++) {
for (let i = 0; i < results.length; i++) {
var coinbaseBlockReward = coinConfig.blockRewardFunction(0, global.activeBlockchain);
results[i].result.confirmed += (coinbaseBlockReward * coinConfig.baseCurrencyUnit.multiplier);
@ -315,7 +315,7 @@ function getAddressBalance(addrScripthash) {
var first = results[0];
var done = false;
for (var i = 1; i < results.length; i++) {
for (let i = 1; i < results.length; i++) {
if (results[i].confirmed != first.confirmed) {
resolve({conflictedResults:results});

View file

@ -20,7 +20,7 @@ const trackAppStats = (name, stats) => {
downsampledAppStats[name] = [];
}
dataset = appStats[name];
let dataset = appStats[name];
if (stats.max) {
dataset.push({time:new Date().getTime(), value: stats.max});

View file

@ -129,9 +129,9 @@ module.exports = {
},
rpcBlacklist:
process.env.BTCEXP_RPC_ALLOWALL.toLowerCase() == "true" ? []
: process.env.BTCEXP_RPC_BLACKLIST ? process.env.BTCEXP_RPC_BLACKLIST.split(',').filter(Boolean)
: [
process.env.BTCEXP_RPC_ALLOWALL.toLowerCase() == "true" ? []
: process.env.BTCEXP_RPC_BLACKLIST ? process.env.BTCEXP_RPC_BLACKLIST.split(',').filter(Boolean)
: [
"addnode",
"backupwallet",
"bumpfee",

View file

@ -1,19 +1,19 @@
const buildNormalizingRegexes = (baseUrl) => {
return [
{ regex: new RegExp(`^${baseUrl}$`, "i"), action:"index" },
{ regex: new RegExp(`^${baseUrl}block-height\/.*`, "i"), action: "block-height" },
{ regex: new RegExp(`^${baseUrl}block\/.*`, "i"), action: "block-hash" },
{ regex: new RegExp(`^${baseUrl}block-analysis\/.*`, "i"), action: "block-analysis" },
{ regex: new RegExp(`^${baseUrl}tx\/.*`, "i"), action: "transaction" },
{ regex: new RegExp(`^${baseUrl}address\/.*`, "i"), action: "address" },
{ regex: new RegExp(`^${baseUrl}block-height/.*`, "i"), action: "block-height" },
{ regex: new RegExp(`^${baseUrl}block/.*`, "i"), action: "block-hash" },
{ regex: new RegExp(`^${baseUrl}block-analysis/.*`, "i"), action: "block-analysis" },
{ regex: new RegExp(`^${baseUrl}tx/.*`, "i"), action: "transaction" },
{ regex: new RegExp(`^${baseUrl}address/.*`, "i"), action: "address" },
{ regex: new RegExp(`^${baseUrl}api/blocks-by-height\/.*`, "i"), action: "api.blocks-by-height" },
{ regex: new RegExp(`^${baseUrl}api/block-headers-by-height\/.*`, "i"), action: "api.block-headers-by-height" },
{ regex: new RegExp(`^${baseUrl}api/block-stats-by-height\/.*`, "i"), action: "api.block-stats-by-height" },
{ regex: new RegExp(`^${baseUrl}api/mempool-txs\/.*`, "i"), action: "api.mempool-txs" },
{ regex: new RegExp(`^${baseUrl}api/raw-tx-with-inputs\/.*`, "i"), action: "api.raw-tx-with-inputs" },
{ regex: new RegExp(`^${baseUrl}api/block-tx-summaries\/.*`, "i"), action: "api.block-tx-summaries" },
{ regex: new RegExp(`^${baseUrl}api/utils\/.*`, "i"), action: "api.utils-func" },
{ regex: new RegExp(`^${baseUrl}api/blocks-by-height/.*`, "i"), action: "api.blocks-by-height" },
{ regex: new RegExp(`^${baseUrl}api/block-headers-by-height/.*`, "i"), action: "api.block-headers-by-height" },
{ regex: new RegExp(`^${baseUrl}api/block-stats-by-height/.*`, "i"), action: "api.block-stats-by-height" },
{ regex: new RegExp(`^${baseUrl}api/mempool-txs/.*`, "i"), action: "api.mempool-txs" },
{ regex: new RegExp(`^${baseUrl}api/raw-tx-with-inputs/.*`, "i"), action: "api.raw-tx-with-inputs" },
{ regex: new RegExp(`^${baseUrl}api/block-tx-summaries/.*`, "i"), action: "api.block-tx-summaries" },
{ regex: new RegExp(`^${baseUrl}api/utils/.*`, "i"), action: "api.utils-func" },
{ regex: new RegExp(`^${baseUrl}admin/dashboard`, "i"), action: "admin.dashboard" },
];

View file

@ -103,7 +103,7 @@ setInterval(() => {
fs.writeFileSync(ipCacheFile, JSON.stringify(ipMemoryCache, null, 4));
} catch (e) {
utils.logError("24308tew7hgde", e);
logError("24308tew7hgde", e);
}
ipMemoryCacheNewItems = false;
@ -166,10 +166,10 @@ function formatHex(hex, outputFormat="utf8") {
}
function splitArrayIntoChunks(array, chunkSize) {
var j = array.length;
var chunks = [];
let j = array.length;
let chunks = [];
for (var i = 0; i < j; i += chunkSize) {
for (let i = 0; i < j; i += chunkSize) {
chunks.push(array.slice(i, i + chunkSize));
}
@ -177,14 +177,14 @@ function splitArrayIntoChunks(array, chunkSize) {
}
function splitArrayIntoChunksByChunkCount(array, chunkCount) {
var bigChunkSize = Math.ceil(array.length / chunkCount);
var bigChunkCount = chunkCount - (chunkCount * bigChunkSize - array.length);
let bigChunkSize = Math.ceil(array.length / chunkCount);
let bigChunkCount = chunkCount - (chunkCount * bigChunkSize - array.length);
var chunks = [];
let chunks = [];
var chunkStart = 0;
for (var chunk = 0; chunk < chunkCount; chunk++) {
var chunkSize = (chunk < bigChunkCount ? bigChunkSize : (bigChunkSize - 1));
let chunkStart = 0;
for (let chunk = 0; chunk < chunkCount; chunk++) {
let chunkSize = (chunk < bigChunkCount ? bigChunkSize : (bigChunkSize - 1));
chunks.push(array.slice(chunkStart, chunkStart + chunkSize));
@ -195,7 +195,7 @@ function splitArrayIntoChunksByChunkCount(array, chunkCount) {
}
function getRandomString(length, chars) {
var mask = '';
let mask = '';
if (chars.indexOf('a') > -1) {
mask += 'abcdefghijklmnopqrstuvwxyz';
@ -213,8 +213,8 @@ function getRandomString(length, chars) {
mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
}
var result = '';
for (var i = length; i > 0; --i) {
let result = '';
for (let i = length; i > 0; --i) {
result += mask[Math.floor(Math.random() * mask.length)];
}
@ -224,15 +224,15 @@ function getRandomString(length, chars) {
function formatCurrencyAmountWithForcedDecimalPlaces(amount, formatType, forcedDecimalPlaces) {
formatType = formatType.toLowerCase();
var currencyType = global.currencyTypes[formatType];
let currencyType = global.currencyTypes[formatType];
if (currencyType == null) {
throw `Unknown currency type: ${formatType}`;
}
var dec = new Decimal(amount);
let dec = new Decimal(amount);
var decimalPlaces = currencyType.decimalPlaces;
let decimalPlaces = currencyType.decimalPlaces;
//if (decimalPlaces == 0 && dec < 1) {
// decimalPlaces = 5;
//}
@ -246,7 +246,7 @@ function formatCurrencyAmountWithForcedDecimalPlaces(amount, formatType, forcedD
if (forcedDecimalPlaces >= 0) {
// toFixed will keep trailing zeroes
var baseStr = addThousandsSeparators(dec.toFixed(decimalPlaces));
let baseStr = addThousandsSeparators(dec.toFixed(decimalPlaces));
return {val:baseStr, currencyUnit:currencyType.name, simpleVal:baseStr, intVal:parseInt(dec)};
@ -254,13 +254,13 @@ function formatCurrencyAmountWithForcedDecimalPlaces(amount, formatType, forcedD
// toDP excludes trailing zeroes but doesn't "fix" numbers like 1e-8
// instead, we use toFixed and manually strip trailing zeroes
// old method is kept for reference since this is sensitive, high-volume code
var baseStr = addThousandsSeparators(dec.toFixed(decimalPlaces).replace(/0+$/, "").replace(/\.$/, ""));
//var baseStr = addThousandsSeparators(dec.toDP(decimalPlaces)); // old version, failed to properly format "1e-8" (left unchanged)
let baseStr = addThousandsSeparators(dec.toFixed(decimalPlaces).replace(/0+$/, "").replace(/\.$/, ""));
//let baseStr = addThousandsSeparators(dec.toDP(decimalPlaces)); // old version, failed to properly format "1e-8" (left unchanged)
var returnVal = {currencyUnit:currencyType.name, simpleVal:baseStr, intVal:parseInt(dec)};
let returnVal = {currencyUnit:currencyType.name, simpleVal:baseStr, intVal:parseInt(dec)};
// max digits in "val"
var maxValDigits = config.site.valueDisplayMaxLargeDigits;
let maxValDigits = config.site.valueDisplayMaxLargeDigits;
// todo: make this section locale-aware (don't hardcode ".")
@ -284,7 +284,7 @@ function formatCurrencyAmountWithForcedDecimalPlaces(amount, formatType, forcedD
if (global.exchangeRates != null && global.exchangeRates[currencyType.id] != null) {
dec = dec.times(global.exchangeRates[currencyType.id]);
var baseStr = addThousandsSeparators(dec.toDecimalPlaces(decimalPlaces));
let baseStr = addThousandsSeparators(dec.toDecimalPlaces(decimalPlaces));
return {val:baseStr, currencyUnit:currencyType.name, simpleVal:baseStr, intVal:parseInt(dec)};
@ -306,7 +306,7 @@ function formatCurrencyAmountInSmallestUnits(amount, forcedDecimalPlaces) {
// ref: https://stackoverflow.com/a/2901298/673828
function addThousandsSeparators(x) {
var parts = x.toString().split(".");
let parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
@ -314,28 +314,28 @@ function addThousandsSeparators(x) {
function satoshisPerUnitOfLocalCurrency(localCurrency) {
if (global.exchangeRates != null) {
var exchangeType = localCurrency;
let exchangeType = localCurrency;
if (!global.exchangeRates[localCurrency]) {
// if current display currency is a native unit, default to USD for exchange values
exchangeType = "usd";
}
var dec = new Decimal(1);
var one = new Decimal(1);
let dec = new Decimal(1);
let one = new Decimal(1);
dec = dec.times(global.exchangeRates[exchangeType]);
// USD/BTC -> BTC/USD
dec = one.dividedBy(dec);
var unitName = coins[config.coin].baseCurrencyUnit.name;
var satCurrencyType = global.currencyTypes["sat"];
var localCurrencyType = global.currencyTypes[localCurrency];
let unitName = coins[config.coin].baseCurrencyUnit.name;
let satCurrencyType = global.currencyTypes["sat"];
let localCurrencyType = global.currencyTypes[localCurrency];
// BTC/USD -> sat/USD
dec = dec.times(satCurrencyType.multiplier);
var exchangedAmt = parseInt(dec);
let exchangedAmt = parseInt(dec);
return {amt:addThousandsSeparators(exchangedAmt),amtRaw:exchangedAmt, unit:`sat/${localCurrencyType.symbol}`}
}
@ -345,9 +345,9 @@ function satoshisPerUnitOfLocalCurrency(localCurrency) {
function getExchangedCurrencyFormatData(amount, exchangeType, includeUnit=true) {
if (global.exchangeRates != null && global.exchangeRates[exchangeType.toLowerCase()] != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates[exchangeType.toLowerCase()]);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
return {
symbol: global.currencySymbols[exchangeType],
@ -357,9 +357,9 @@ function getExchangedCurrencyFormatData(amount, exchangeType, includeUnit=true)
} else if (exchangeType == "au") {
if (global.exchangeRates != null && global.goldExchangeRates != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates.usd).dividedBy(global.goldExchangeRates.usd);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
return {
symbol: "AU",
@ -374,9 +374,9 @@ function getExchangedCurrencyFormatData(amount, exchangeType, includeUnit=true)
function formatExchangedCurrency(amount, exchangeType, decimals=2) {
if (global.exchangeRates != null && global.exchangeRates[exchangeType.toLowerCase()] != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates[exchangeType.toLowerCase()]);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(decimals);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(decimals);
return {
val: addThousandsSeparators(exchangedAmt),
@ -386,9 +386,9 @@ function formatExchangedCurrency(amount, exchangeType, decimals=2) {
};
} else if (exchangeType == "au") {
if (global.exchangeRates != null && global.goldExchangeRates != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates.usd).dividedBy(global.goldExchangeRates.usd);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(decimals);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(decimals);
return {
val: addThousandsSeparators(exchangedAmt),
@ -403,12 +403,12 @@ function formatExchangedCurrency(amount, exchangeType, decimals=2) {
}
function seededRandom(seed) {
var x = Math.sin(seed++) * 10000;
let x = Math.sin(seed++) * 10000;
return x - Math.floor(x);
}
function seededRandomIntBetween(seed, min, max) {
var rand = seededRandom(seed);
let rand = seededRandom(seed);
return (min + (max - min) * rand);
}
@ -472,10 +472,10 @@ function shortenTimeDiff(str) {
}
function logMemoryUsage() {
var mbUsed = process.memoryUsage().heapUsed / 1024 / 1024;
let mbUsed = process.memoryUsage().heapUsed / 1024 / 1024;
mbUsed = Math.round(mbUsed * 100) / 100;
var mbTotal = process.memoryUsage().heapTotal / 1024 / 1024;
let mbTotal = process.memoryUsage().heapTotal / 1024 / 1024;
mbTotal = Math.round(mbTotal * 100) / 100;
//debugLog("memoryUsage: heapUsed=" + mbUsed + ", heapTotal=" + mbTotal + ", ratio=" + parseInt(mbUsed / mbTotal * 100));
@ -487,14 +487,14 @@ function identifyMiner(coinbaseTx, blockHeight) {
}
if (global.miningPoolsConfigs) {
for (var i = 0; i < global.miningPoolsConfigs.length; i++) {
var miningPoolsConfig = global.miningPoolsConfigs[i];
for (let i = 0; i < global.miningPoolsConfigs.length; i++) {
let miningPoolsConfig = global.miningPoolsConfigs[i];
for (var payoutAddress in miningPoolsConfig.payout_addresses) {
for (let payoutAddress in miningPoolsConfig.payout_addresses) {
if (miningPoolsConfig.payout_addresses.hasOwnProperty(payoutAddress)) {
if (coinbaseTx.vout && coinbaseTx.vout.length > 0) {
if (getVoutAddresses(coinbaseTx.vout[0]).includes(payoutAddress)) {
var minerInfo = miningPoolsConfig.payout_addresses[payoutAddress];
let minerInfo = miningPoolsConfig.payout_addresses[payoutAddress];
minerInfo.identifiedBy = "payout address " + payoutAddress;
return minerInfo;
@ -503,10 +503,10 @@ function identifyMiner(coinbaseTx, blockHeight) {
}
}
for (var coinbaseTag in miningPoolsConfig.coinbase_tags) {
for (let coinbaseTag in miningPoolsConfig.coinbase_tags) {
if (miningPoolsConfig.coinbase_tags.hasOwnProperty(coinbaseTag)) {
if (formatHex(coinbaseTx.vin[0].coinbase, "utf8").indexOf(coinbaseTag) != -1) {
var minerInfo = miningPoolsConfig.coinbase_tags[coinbaseTag];
let minerInfo = miningPoolsConfig.coinbase_tags[coinbaseTag];
minerInfo.identifiedBy = "coinbase tag '" + coinbaseTag + "'";
return minerInfo;
@ -514,9 +514,9 @@ function identifyMiner(coinbaseTx, blockHeight) {
}
}
for (var blockHash in miningPoolsConfig.block_hashes) {
for (let blockHash in miningPoolsConfig.block_hashes) {
if (blockHash == coinbaseTx.blockhash) {
var minerInfo = miningPoolsConfig.block_hashes[blockHash];
let minerInfo = miningPoolsConfig.block_hashes[blockHash];
minerInfo.identifiedBy = "known block hash '" + blockHash + "'";
return minerInfo;
@ -524,8 +524,8 @@ function identifyMiner(coinbaseTx, blockHeight) {
}
if (global.activeBlockchain == "main" && miningPoolsConfig.block_heights) {
for (var minerName in miningPoolsConfig.block_heights) {
var minerInfo = miningPoolsConfig.block_heights[minerName];
for (let minerName in miningPoolsConfig.block_heights) {
let minerInfo = miningPoolsConfig.block_heights[minerName];
minerInfo.name = minerName;
if (minerInfo.heights.includes(blockHeight)) {
@ -539,7 +539,7 @@ function identifyMiner(coinbaseTx, blockHeight) {
}
if (coinbaseTx.vout && coinbaseTx.vout.length > 0) {
for (var i = 0; i < coinbaseTx.vout.length; i++) {
for (let i = 0; i < coinbaseTx.vout.length; i++) {
const vout = coinbaseTx.vout[i];
const voutValue = new Decimal(vout.value);
@ -561,21 +561,21 @@ function identifyMiner(coinbaseTx, blockHeight) {
}
function getTxTotalInputOutputValues(tx, txInputs, blockHeight) {
var totalInputValue = new Decimal(0);
var totalOutputValue = new Decimal(0);
let totalInputValue = new Decimal(0);
let totalOutputValue = new Decimal(0);
try {
if (txInputs) {
for (var i = 0; i < tx.vin.length; i++) {
for (let i = 0; i < tx.vin.length; i++) {
if (tx.vin[i].coinbase) {
totalInputValue = totalInputValue.plus(new Decimal(coinConfig.blockRewardFunction(blockHeight, global.activeBlockchain)));
} else {
var txInput = txInputs[i];
let txInput = txInputs[i];
if (txInput) {
try {
var vout = txInput;
let vout = txInput;
if (vout.value) {
totalInputValue = totalInputValue.plus(new Decimal(vout.value));
@ -590,9 +590,9 @@ function getTxTotalInputOutputValues(tx, txInputs, blockHeight) {
totalInputValue = null
}
for (var i = 0; i < tx.vout.length; i++) {
totalOutputValue = totalOutputValue.plus(new Decimal(tx.vout[i].value));
}
for (let i = 0; i < tx.vout.length; i++) {
totalOutputValue = totalOutputValue.plus(new Decimal(tx.vout[i].value));
}
} catch (err) {
logError("2308sh0sg44", err, {tx:tx, txInputs:txInputs, blockHeight:blockHeight});
}
@ -605,11 +605,11 @@ function getBlockTotalFeesFromCoinbaseTxAndBlockHeight(coinbaseTx, blockHeight)
return 0;
}
var blockReward = coinConfig.blockRewardFunction(blockHeight, global.activeBlockchain);
let blockReward = coinConfig.blockRewardFunction(blockHeight, global.activeBlockchain);
var totalOutput = new Decimal(0);
for (var i = 0; i < coinbaseTx.vout.length; i++) {
var outputValue = coinbaseTx.vout[i].value;
let totalOutput = new Decimal(0);
for (let i = 0; i < coinbaseTx.vout.length; i++) {
let outputValue = coinbaseTx.vout[i].value;
if (outputValue > 0) {
totalOutput = totalOutput.plus(new Decimal(outputValue));
}
@ -669,7 +669,7 @@ async function refreshExchangeRates() {
try {
const response = await axios.get(coins[config.coin].exchangeRateData.jsonUrl);
var exchangeRates = coins[config.coin].exchangeRateData.responseBodySelectorFunction(response.data);
let exchangeRates = coins[config.coin].exchangeRateData.responseBodySelectorFunction(response.data);
if (exchangeRates != null) {
global.exchangeRates = exchangeRates;
global.exchangeRatesUpdateTime = new Date();
@ -695,7 +695,7 @@ async function refreshExchangeRates() {
try {
const response = await axios.get(coins[config.coin].goldExchangeRateData.jsonUrl);
var exchangeRates = coins[config.coin].goldExchangeRateData.responseBodySelectorFunction(response.data);
let exchangeRates = coins[config.coin].goldExchangeRateData.responseBodySelectorFunction(response.data);
if (exchangeRates != null) {
global.goldExchangeRates = exchangeRates;
global.goldExchangeRatesUpdateTime = new Date();
@ -721,11 +721,11 @@ function geoLocateIpAddresses(ipAddresses, provider) {
return;
}
var ipDetails = {ips:ipAddresses, detailsByIp:{}};
let ipDetails = {ips:ipAddresses, detailsByIp:{}};
var promises = [];
for (var i = 0; i < ipAddresses.length; i++) {
var ipStr = ipAddresses[i];
let promises = [];
for (let i = 0; i < ipAddresses.length; i++) {
let ipStr = ipAddresses[i];
if (ipStr.endsWith(".onion")) {
// tor, no location possible
@ -745,12 +745,12 @@ function geoLocateIpAddresses(ipAddresses, provider) {
promises.push(new Promise(function(resolve2, reject2) {
ipCache.get(ipStr).then(async function(result) {
if (result.value == null) {
var apiUrl = "http://api.ipstack.com/" + result.key + "?access_key=" + config.credentials.ipStackComApiAccessKey;
let apiUrl = "http://api.ipstack.com/" + result.key + "?access_key=" + config.credentials.ipStackComApiAccessKey;
try {
const response = await axios.get(apiUrl);
var ip = response.data.ip;
let ip = response.data.ip;
ipDetails.detailsByIp[ip] = response.data;
@ -796,7 +796,7 @@ function geoLocateIpAddresses(ipAddresses, provider) {
}
function parseExponentStringDouble(val) {
var [lead,decimal,pow] = val.toString().split(/e|\./);
let [lead,decimal,pow] = val.toString().split(/e|\./);
return +pow <= 0
? "0." + "0".repeat(Math.abs(pow)-1) + lead + decimal
: lead + ( +pow >= decimal.length ? (decimal + "0".repeat(+pow-decimal.length)) : (decimal.slice(0,+pow)+"."+decimal.slice(+pow)));
@ -804,10 +804,10 @@ function parseExponentStringDouble(val) {
function formatLargeNumber(n, decimalPlaces) {
try {
for (var i = 0; i < exponentScales.length; i++) {
var item = exponentScales[i];
for (let i = 0; i < exponentScales.length; i++) {
let item = exponentScales[i];
var fraction = new Decimal(n / item.val);
let fraction = new Decimal(n / item.val);
if (fraction >= 1) {
return [fraction.toDP(decimalPlaces), item];
}
@ -824,10 +824,10 @@ function formatLargeNumber(n, decimalPlaces) {
function formatLargeNumberSignificant(n, significantDigits) {
try {
for (var i = 0; i < exponentScales.length; i++) {
var item = exponentScales[i];
for (let i = 0; i < exponentScales.length; i++) {
let item = exponentScales[i];
var fraction = new Decimal(n / item.val);
let fraction = new Decimal(n / item.val);
if (fraction >= 1) {
return [fraction.toDP(Math.max(0, significantDigits - `${Math.floor(fraction)}`.length)), item];
}
@ -844,13 +844,13 @@ function formatLargeNumberSignificant(n, significantDigits) {
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
let max = Math.max(r, g, b), min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
let d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
@ -865,12 +865,12 @@ function rgbToHsl(r, g, b) {
function colorHexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
let shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
@ -879,7 +879,7 @@ function colorHexToRgb(hex) {
}
function colorHexToHsl(hex) {
var rgb = colorHexToRgb(hex);
let rgb = colorHexToRgb(hex);
return rgbToHsl(rgb.r, rgb.g, rgb.b);
}
@ -941,7 +941,7 @@ function logError(errorId, err, optionalUserData = {}, logStacktrace=true) {
}
var returnVal = {errorId:errorId, error:err};
let returnVal = {errorId:errorId, error:err};
if (optionalUserData) {
returnVal.userData = optionalUserData;
}
@ -951,10 +951,10 @@ function logError(errorId, err, optionalUserData = {}, logStacktrace=true) {
function buildQrCodeUrls(strings) {
return new Promise(function(resolve, reject) {
var promises = [];
var qrcodeUrls = {};
let promises = [];
let qrcodeUrls = {};
for (var i = 0; i < strings.length; i++) {
for (let i = 0; i < strings.length; i++) {
promises.push(new Promise(function(resolve2, reject2) {
buildQrCodeUrl(strings[i], qrcodeUrls).then(function() {
resolve2();
@ -993,7 +993,7 @@ function buildQrCodeUrl(str, results) {
}
function outputTypeAbbreviation(outputType) {
var map = {
const map = {
"pubkey": "P2PK",
"pubkeyhash": "P2PKH",
"scripthash": "P2SH",
@ -1013,7 +1013,7 @@ function outputTypeAbbreviation(outputType) {
}
function outputTypeName(outputType) {
var map = {
const map = {
"pubkey": "Pay to Public Key",
"pubkeyhash": "Pay to Public Key Hash",
"scripthash": "Pay to Script Hash",
@ -1185,8 +1185,8 @@ function iterateProperties(obj, action) {
}
function stringifySimple(object) {
var simpleObject = {};
for (var prop in object) {
let simpleObject = {};
for (let prop in object) {
if (!object.hasOwnProperty(prop)) {
continue;
}
@ -1265,7 +1265,7 @@ function xpubChangeVersionBytes(xpub, targetFormat) {
// trim whitespace
xpub = xpub.trim();
var data = bs58check.decode(xpub);
let data = bs58check.decode(xpub);
data = data.slice(4);
data = Buffer.concat([Buffer.from(xpubPrefixes.get(targetFormat), 'hex'), data]);

6
npm-shrinkwrap.json generated
View file

@ -4309,9 +4309,9 @@
}
},
"node_modules/js-sdsl": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
"integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
"integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
"dev": true,
"funding": {
"type": "opencollective",

View file

@ -150,7 +150,7 @@ router.get("/tx/:txid", asyncHandler(async (req, res, next) => {
let txInputLimit = (res.locals.crawlerBot) ? 3 : -1;
try {
var results = await coreApi.getRawTransactionsWithInputs([txid], txInputLimit);
let results = await coreApi.getRawTransactionsWithInputs([txid], txInputLimit);
let outJson = results.transactions[0];
let txInputs = results.txInputsByTransaction[txid] || {};
@ -223,7 +223,7 @@ router.get("/tx/volume/24h", function(req, res, next) {
router.get("/blockchain/coins", function(req, res, next) {
if (global.utxoSetSummary) {
var supply = parseFloat(global.utxoSetSummary.total_amount).toString();
let supply = parseFloat(global.utxoSetSummary.total_amount).toString();
res.send(supply.toString());
@ -232,7 +232,7 @@ router.get("/blockchain/coins", function(req, res, next) {
} else {
// estimated supply
coreApi.getBlockchainInfo().then(function(getblockchaininfo){
var estimatedSupply = utils.estimatedSupply(getblockchaininfo.blocks);
let estimatedSupply = utils.estimatedSupply(getblockchaininfo.blocks);
res.send(estimatedSupply.toString());
}).catch(next);
}
@ -259,9 +259,9 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
const { perfId, perfResults } = utils.perfLogNewItem({action:"api.address"});
res.locals.perfId = perfId;
var limit = config.site.addressTxPageSize;
var offset = 0;
var sort = "desc";
let limit = config.site.addressTxPageSize;
let offset = 0;
let sort = "desc";
res.locals.maxTxOutputDisplayCount = config.site.addressPage.txOutputMaxDefaultDisplay;
@ -346,7 +346,7 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
}
if (global.miningPoolsConfigs) {
for (var i = 0; i < global.miningPoolsConfigs.length; i++) {
for (let i = 0; i < global.miningPoolsConfigs.length; i++) {
if (global.miningPoolsConfigs[i].payout_addresses[address]) {
let note = global.miningPoolsConfigs[i].payout_addresses[address];
note.type = "payout address for miner";
@ -369,7 +369,7 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
const promises = [];
var addrScripthash = hexEnc.stringify(sha256(hexEnc.parse(validateaddressResult.scriptPubKey)));
let addrScripthash = hexEnc.stringify(sha256(hexEnc.parse(validateaddressResult.scriptPubKey)));
addrScripthash = addrScripthash.match(/.{2}/g).reverse().join("");
result.electrumScripthash = addrScripthash;
@ -377,7 +377,7 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
promises.push(utils.timePromise("address.getAddressDetails", async () => {
const addressDetailsResult = await addressApi.getAddressDetails(address, validateaddressResult.scriptPubKey, sort, limit, offset);
var addressDetails = addressDetailsResult.addressDetails;
let addressDetails = addressDetailsResult.addressDetails;
result.txHistory = addressDetails;
result.txHistory.request = {};
@ -551,16 +551,16 @@ router.get("/xyzpub/addresses/:extendedPubkey", asyncHandler(async (req, res, ne
router.get("/mining/hashrate", asyncHandler(async (req, res, next) => {
try {
var decimals = 3;
let decimals = 3;
if (req.query.decimals) {
decimals = parseInt(req.query.decimals);
}
var blocksPerDay = 24 * 60 * 60 / coinConfig.targetBlockTimeSeconds;
var rates = [];
let blocksPerDay = 24 * 60 * 60 / coinConfig.targetBlockTimeSeconds;
let rates = [];
var timePeriods = [
let timePeriods = [
1 * blocksPerDay,
7 * blocksPerDay,
30 * blocksPerDay,
@ -568,16 +568,16 @@ router.get("/mining/hashrate", asyncHandler(async (req, res, next) => {
365 * blocksPerDay,
];
var promises = [];
let promises = [];
for (var i = 0; i < timePeriods.length; i++) {
for (let i = 0; i < timePeriods.length; i++) {
const index = i;
const x = timePeriods[i];
promises.push(new Promise(async (resolve, reject) => {
try {
const hashrate = await coreApi.getNetworkHashrate(x);
var summary = utils.formatLargeNumber(hashrate, decimals);
let summary = utils.formatLargeNumber(hashrate, decimals);
rates[index] = {
val: parseFloat(summary[0]),
@ -627,11 +627,11 @@ router.get("/mining/diff-adj-estimate", asyncHandler(async (req, res, next) => {
const { perfId, perfResults } = utils.perfLogNewItem({action:"api.diff-adj-estimate"});
res.locals.perfId = perfId;
var promises = [];
let promises = [];
const getblockchaininfo = await utils.timePromise("api_diffAdjEst_getBlockchainInfo", coreApi.getBlockchainInfo);
var currentBlock;
var difficultyPeriod = parseInt(Math.floor(getblockchaininfo.blocks / coinConfig.difficultyAdjustmentBlockCount));
var difficultyPeriodFirstBlockHeader;
let currentBlock;
let difficultyPeriod = parseInt(Math.floor(getblockchaininfo.blocks / coinConfig.difficultyAdjustmentBlockCount));
let difficultyPeriodFirstBlockHeader;
promises.push(utils.timePromise("api.diff-adj-est.getBlockHeaderByHeight", async () => {
currentBlock = await coreApi.getBlockHeaderByHeight(getblockchaininfo.blocks);
@ -644,29 +644,30 @@ router.get("/mining/diff-adj-estimate", asyncHandler(async (req, res, next) => {
await utils.awaitPromises(promises);
var firstBlockHeader = difficultyPeriodFirstBlockHeader;
var heightDiff = currentBlock.height - firstBlockHeader.height;
var blockCount = heightDiff + 1;
var timeDiff = currentBlock.mediantime - firstBlockHeader.mediantime;
var timePerBlock = timeDiff / heightDiff;
var dt = new Date().getTime() / 1000 - firstBlockHeader.time;
var predictedBlockCount = dt / coinConfig.targetBlockTimeSeconds;
var timePerBlock2 = dt / heightDiff;
let firstBlockHeader = difficultyPeriodFirstBlockHeader;
let heightDiff = currentBlock.height - firstBlockHeader.height;
let blockCount = heightDiff + 1;
let timeDiff = currentBlock.mediantime - firstBlockHeader.mediantime;
let timePerBlock = timeDiff / heightDiff;
let dt = new Date().getTime() / 1000 - firstBlockHeader.time;
let predictedBlockCount = dt / coinConfig.targetBlockTimeSeconds;
let timePerBlock2 = dt / heightDiff;
var blockRatioPercent = new Decimal(blockCount / predictedBlockCount).times(100);
let blockRatioPercent = new Decimal(blockCount / predictedBlockCount).times(100);
if (blockRatioPercent > 400) {
blockRatioPercent = new Decimal(400);
}
if (blockRatioPercent < 25) {
blockRatioPercent = new Decimal(25);
}
let diffAdjPercent = 0;
if (predictedBlockCount > blockCount) {
var diffAdjPercent = new Decimal(100).minus(blockRatioPercent).times(-1);
diffAdjPercent = new Decimal(100).minus(blockRatioPercent).times(-1);
//diffAdjPercent = diffAdjPercent * -1;
} else {
var diffAdjPercent = blockRatioPercent.minus(new Decimal(100));
diffAdjPercent = blockRatioPercent.minus(new Decimal(100));
}
res.send(diffAdjPercent.toFixed(2).toString());
@ -805,12 +806,12 @@ router.get("/mempool/summary", function(req, res, next) {
});
router.get("/mempool/fees", function(req, res, next) {
var feeConfTargets = [1, 3, 6, 144];
let feeConfTargets = [1, 3, 6, 144];
coreApi.getSmartFeeEstimates("CONSERVATIVE", feeConfTargets).then(function(rawSmartFeeEstimates){
var smartFeeEstimates = {};
let smartFeeEstimates = {};
for (var i = 0; i < feeConfTargets.length; i++) {
var rawSmartFeeEstimate = rawSmartFeeEstimates[i];
for (let i = 0; i < feeConfTargets.length; i++) {
let rawSmartFeeEstimate = rawSmartFeeEstimates[i];
if (rawSmartFeeEstimate.errors) {
smartFeeEstimates[feeConfTargets[i]] = "?";
@ -819,7 +820,7 @@ router.get("/mempool/fees", function(req, res, next) {
}
}
var results = {
let results = {
"nextBlock":smartFeeEstimates[1],
"30min":smartFeeEstimates[3],
"60min":smartFeeEstimates[6],
@ -840,18 +841,18 @@ router.get("/mempool/fees", function(req, res, next) {
/// PRICE
router.get("/price/:currency/sats", function(req, res, next) {
var result = 0;
var amount = 1.0;
var currency = req.params.currency.toLowerCase();
let result = 0;
let amount = 1.0;
let currency = req.params.currency.toLowerCase();
if (global.exchangeRates != null && global.exchangeRates[currency] != null) {
var satsRateData = utils.satoshisPerUnitOfLocalCurrency(currency);
let satsRateData = utils.satoshisPerUnitOfLocalCurrency(currency);
result = satsRateData.amtRaw;
} else if (currency == "xau" && global.exchangeRates != null && global.goldExchangeRates != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates.usd).dividedBy(global.goldExchangeRates.usd);
var satCurrencyType = global.currencyTypes["sat"];
var one = new Decimal(1);
let satCurrencyType = global.currencyTypes["sat"];
let one = new Decimal(1);
dec = one.dividedBy(dec);
dec = dec.times(satCurrencyType.multiplier);
@ -863,22 +864,22 @@ router.get("/price/:currency/sats", function(req, res, next) {
});
router.get("/price/:currency/marketcap", function(req, res, next) {
var result = 0;
let result = 0;
coreApi.getBlockchainInfo().then(function(getblockchaininfo){
var estimatedSupply = utils.estimatedSupply(getblockchaininfo.blocks);
var price = 0;
let estimatedSupply = utils.estimatedSupply(getblockchaininfo.blocks);
let price = 0;
var amount = 1.0;
var currency = req.params.currency.toLowerCase();
let amount = 1.0;
let currency = req.params.currency.toLowerCase();
if (global.exchangeRates != null && global.exchangeRates[currency] != null) {
var formatData = utils.formatExchangedCurrency(amount, currency);
let formatData = utils.formatExchangedCurrency(amount, currency);
price = parseFloat(formatData.valRaw).toFixed(2);
} else if (currency == "xau" && global.exchangeRates != null && global.goldExchangeRates != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates.usd).dividedBy(global.goldExchangeRates.usd);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
price = exchangedAmt;
}
@ -890,13 +891,13 @@ router.get("/price/:currency/marketcap", function(req, res, next) {
});
router.get("/price/:currency", function(req, res, next) {
var result = 0;
var amount = 1.0;
var currency = req.params.currency.toLowerCase();
let result = 0;
let amount = 1.0;
let currency = req.params.currency.toLowerCase();
let format = (req.query.format == "true");
if (global.exchangeRates != null && global.exchangeRates[currency] != null) {
var formatData = utils.formatExchangedCurrency(amount, currency);
let formatData = utils.formatExchangedCurrency(amount, currency);
if (format) {
result = formatData.val;
@ -905,9 +906,9 @@ router.get("/price/:currency", function(req, res, next) {
result = formatData.valRaw;
}
} else if (currency == "xau" && global.exchangeRates != null && global.goldExchangeRates != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates.usd).dividedBy(global.goldExchangeRates.usd);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
result = utils.addThousandsSeparators(exchangedAmt);
}
@ -917,13 +918,13 @@ router.get("/price/:currency", function(req, res, next) {
});
router.get("/price", function(req, res, next) {
var amount = 1.0;
var result = {};
let amount = 1.0;
let result = {};
let format = (req.query.format == "true");
["usd", "eur", "gbp", "xau"].forEach(currency => {
if (global.exchangeRates != null && global.exchangeRates[currency] != null) {
var formatData = utils.formatExchangedCurrency(amount, currency);
let formatData = utils.formatExchangedCurrency(amount, currency);
if (format) {
result[currency] = formatData.val;
@ -932,9 +933,9 @@ router.get("/price", function(req, res, next) {
result[currency] = formatData.valRaw;
}
} else if (currency == "xau" && global.exchangeRates != null && global.goldExchangeRates != null) {
var dec = new Decimal(amount);
let dec = new Decimal(amount);
dec = dec.times(global.exchangeRates.usd).dividedBy(global.goldExchangeRates.usd);
var exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
let exchangedAmt = parseFloat(Math.round(dec * 100) / 100).toFixed(2);
result[currency] = utils.addThousandsSeparators(exchangedAmt);
}
});
@ -951,7 +952,7 @@ router.get("/price", function(req, res, next) {
/// FUN
router.get("/quotes/random", function(req, res, next) {
var index = utils.randomInt(0, btcQuotes.items.length);
let index = utils.randomInt(0, btcQuotes.items.length);
let quote = null;
let done = false;

View file

@ -31,7 +31,7 @@ const btcQuotes = require("./../app/coins/btcQuotes.js");
const forceCsrf = csurf({ ignoreMethods: [] });
var noTxIndexMsg = "\n\nYour node does not have **txindex** enabled. Without it, you can only lookup wallet, mempool, and recently confirmed transactions by their **txid**. Searching for non-wallet transactions that were confirmed more than "+config.noTxIndexSearchDepth+" blocks ago is only possible if the confirmed block height is available.";
let noTxIndexMsg = "\n\nYour node does not have **txindex** enabled. Without it, you can only lookup wallet, mempool, and recently confirmed transactions by their **txid**. Searching for non-wallet transactions that were confirmed more than "+config.noTxIndexSearchDepth+" blocks ago is only possible if the confirmed block height is available.";
router.get("/", asyncHandler(async (req, res, next) => {
try {
@ -67,11 +67,11 @@ router.get("/", asyncHandler(async (req, res, next) => {
res.locals.offset = 0;
res.locals.sort = "desc";
var feeConfTargets = [1, 6, 144, 1008];
let feeConfTargets = [1, 6, 144, 1008];
res.locals.feeConfTargets = feeConfTargets;
var promises = [];
let promises = [];
promises.push(utils.timePromise("homepage.getMempoolInfo", async () => {
res.locals.mempoolInfo = await coreApi.getMempoolInfo();
@ -88,10 +88,10 @@ router.get("/", asyncHandler(async (req, res, next) => {
promises.push(utils.timePromise("homepage.getSmartFeeEstimates", async () => {
const rawSmartFeeEstimates = await coreApi.getSmartFeeEstimates("CONSERVATIVE", feeConfTargets);
var smartFeeEstimates = {};
let smartFeeEstimates = {};
for (var i = 0; i < feeConfTargets.length; i++) {
var rawSmartFeeEstimate = rawSmartFeeEstimates[i];
for (let i = 0; i < feeConfTargets.length; i++) {
let rawSmartFeeEstimate = rawSmartFeeEstimates[i];
if (rawSmartFeeEstimate.errors) {
smartFeeEstimates[feeConfTargets[i]] = "?";
@ -124,10 +124,10 @@ router.get("/", asyncHandler(async (req, res, next) => {
res.locals.difficultyPeriod = parseInt(Math.floor(getblockchaininfo.blocks / coinConfig.difficultyAdjustmentBlockCount));
var blockHeights = [];
let blockHeights = [];
if (getblockchaininfo.blocks) {
// +1 to page size here so we have the next block to calculate T.T.M.
for (var i = 0; i < (config.site.homepage.recentBlocksCount + 1); i++) {
for (let i = 0; i < (config.site.homepage.recentBlocksCount + 1); i++) {
blockHeights.push(getblockchaininfo.blocks - i);
}
} else if (global.activeBlockchain == "regtest") {
@ -142,8 +142,8 @@ router.get("/", asyncHandler(async (req, res, next) => {
if (rawblockstats && rawblockstats.length > 0 && rawblockstats[0] != null) {
res.locals.blockstatsByHeight = {};
for (var i = 0; i < rawblockstats.length; i++) {
var blockstats = rawblockstats[i];
for (let i = 0; i < rawblockstats.length; i++) {
let blockstats = rawblockstats[i];
res.locals.blockstatsByHeight[blockstats.height] = blockstats;
}
@ -163,7 +163,7 @@ router.get("/", asyncHandler(async (req, res, next) => {
}));
var targetBlocksPerDay = 24 * 60 * 60 / global.coinConfig.targetBlockTimeSeconds;
let targetBlocksPerDay = 24 * 60 * 60 / global.coinConfig.targetBlockTimeSeconds;
res.locals.targetBlocksPerDay = targetBlocksPerDay;
if (false && getblockchaininfo.chain !== 'regtest') {
@ -173,11 +173,11 @@ router.get("/", asyncHandler(async (req, res, next) => {
resolve();
}));*/
var chainTxStatsIntervals = [ [targetBlocksPerDay, "24 hours"], [7 * targetBlocksPerDay, "7 days"], [30 * targetBlocksPerDay, "30 days"] ]
let chainTxStatsIntervals = [ [targetBlocksPerDay, "24 hours"], [7 * targetBlocksPerDay, "7 days"], [30 * targetBlocksPerDay, "30 days"] ]
.filter(dat => dat[0] <= getblockchaininfo.blocks);
res.locals.chainTxStats = {};
for (var i = 0; i < chainTxStatsIntervals.length; i++) {
for (let i = 0; i < chainTxStatsIntervals.length; i++) {
promises.push(utils.timePromise(`homepage.getChainTxStats.${chainTxStatsIntervals[i][0]}`, async () => {
res.locals.chainTxStats[chainTxStatsIntervals[i][0]] = await coreApi.getChainTxStats(chainTxStatsIntervals[i][0]);
}, perfResults));
@ -213,24 +213,24 @@ router.get("/", asyncHandler(async (req, res, next) => {
await utils.awaitPromises(promises);
var firstBlockHeader = res.locals.difficultyPeriodFirstBlockHeader;
var currentBlock = res.locals.latestBlocks[0];
var heightDiff = currentBlock.height - firstBlockHeader.height;
var blockCount = heightDiff + 1;
var timeDiff = currentBlock.mediantime - firstBlockHeader.mediantime;
var timePerBlock = timeDiff / heightDiff;
var timePerBlockDuration = moment.duration(timePerBlock * 1000);
var daysUntilAdjustment = new Decimal(res.locals.blocksUntilDifficultyAdjustment).times(timePerBlock).dividedBy(60 * 60 * 24);
var hoursUntilAdjustment = new Decimal(res.locals.blocksUntilDifficultyAdjustment).times(timePerBlock).dividedBy(60 * 60);
var duaDP1 = daysUntilAdjustment.toDP(1);
var daysUntilAdjustmentStr = daysUntilAdjustment > 1 ? `~${duaDP1} day${duaDP1 == "1" ? "" : "s"}` : "< 1 day";
var hoursUntilAdjustmentStr = hoursUntilAdjustment > 1 ? `~${hoursUntilAdjustment.toDP(0)} hr${hoursUntilAdjustment.toDP(1) == "1" ? "" : "s"}` : "< 1 hr";
var nowTime = new Date().getTime() / 1000;
var dt = nowTime - firstBlockHeader.time;
var timePerBlock2 = dt / heightDiff;
var predictedBlockCount = dt / coinConfig.targetBlockTimeSeconds;
let firstBlockHeader = res.locals.difficultyPeriodFirstBlockHeader;
let currentBlock = res.locals.latestBlocks[0];
let heightDiff = currentBlock.height - firstBlockHeader.height;
let blockCount = heightDiff + 1;
let timeDiff = currentBlock.mediantime - firstBlockHeader.mediantime;
let timePerBlock = timeDiff / heightDiff;
let timePerBlockDuration = moment.duration(timePerBlock * 1000);
let daysUntilAdjustment = new Decimal(res.locals.blocksUntilDifficultyAdjustment).times(timePerBlock).dividedBy(60 * 60 * 24);
let hoursUntilAdjustment = new Decimal(res.locals.blocksUntilDifficultyAdjustment).times(timePerBlock).dividedBy(60 * 60);
let duaDP1 = daysUntilAdjustment.toDP(1);
let daysUntilAdjustmentStr = daysUntilAdjustment > 1 ? `~${duaDP1} day${duaDP1 == "1" ? "" : "s"}` : "< 1 day";
let hoursUntilAdjustmentStr = hoursUntilAdjustment > 1 ? `~${hoursUntilAdjustment.toDP(0)} hr${hoursUntilAdjustment.toDP(1) == "1" ? "" : "s"}` : "< 1 hr";
let nowTime = new Date().getTime() / 1000;
let dt = nowTime - firstBlockHeader.time;
let timePerBlock2 = dt / heightDiff;
let predictedBlockCount = dt / coinConfig.targetBlockTimeSeconds;
var blockRatioPercent = new Decimal(blockCount / predictedBlockCount).times(100);
let blockRatioPercent = new Decimal(blockCount / predictedBlockCount).times(100);
if (blockRatioPercent > 400) {
blockRatioPercent = new Decimal(400);
}
@ -238,17 +238,17 @@ router.get("/", asyncHandler(async (req, res, next) => {
blockRatioPercent = new Decimal(25);
}
if (predictedBlockCount > blockCount) {
var diffAdjPercent = new Decimal(100).minus(blockRatioPercent).times(-1);
var diffAdjText = `Blocks during the current difficulty epoch have taken this long, on average, to be mined. If this pace continues, then in ${res.locals.blocksUntilDifficultyAdjustment.toLocaleString()} block${res.locals.blocksUntilDifficultyAdjustment == 1 ? "" : "s"} (${daysUntilAdjustmentStr}) the difficulty will adjust downward: -${diffAdjPercent.toDP(1)}%`;
var diffAdjSign = "-";
var textColorClass = "text-danger";
} else {
var diffAdjPercent = blockRatioPercent.minus(new Decimal(100));
var diffAdjText = `Blocks during the current difficulty epoch have taken this long, on average, to be mined. If this pace continues, then in ${res.locals.blocksUntilDifficultyAdjustment.toLocaleString()} block${res.locals.blocksUntilDifficultyAdjustment == 1 ? "" : "s"} (${daysUntilAdjustmentStr}) the difficulty will adjust upward: +${diffAdjPercent.toDP(1)}%`;
var diffAdjSign = "+";
var textColorClass = "text-success";
let diffAdjPercent = blockRatioPercent.minus(new Decimal(100));
let diffAdjText = `Blocks during the current difficulty epoch have taken this long, on average, to be mined. If this pace continues, then in ${res.locals.blocksUntilDifficultyAdjustment.toLocaleString()} block${res.locals.blocksUntilDifficultyAdjustment == 1 ? "" : "s"} (${daysUntilAdjustmentStr}) the difficulty will adjust upward: +${diffAdjPercent.toDP(1)}%`;
let diffAdjSign = "+";
let textColorClass = "text-success";
if (predictedBlockCount > blockCount) {
diffAdjPercent = new Decimal(100).minus(blockRatioPercent).times(-1);
diffAdjText = `Blocks during the current difficulty epoch have taken this long, on average, to be mined. If this pace continues, then in ${res.locals.blocksUntilDifficultyAdjustment.toLocaleString()} block${res.locals.blocksUntilDifficultyAdjustment == 1 ? "" : "s"} (${daysUntilAdjustmentStr}) the difficulty will adjust downward: -${diffAdjPercent.toDP(1)}%`;
diffAdjSign = "-";
textColorClass = "text-danger";
}
res.locals.difficultyAdjustmentData = {
@ -382,13 +382,13 @@ router.get("/peers", asyncHandler(async (req, res, next) => {
await utils.awaitPromises(promises);
var peerSummary = res.locals.peerSummary;
let peerSummary = res.locals.peerSummary;
var peerIps = [];
for (var i = 0; i < peerSummary.getpeerinfo.length; i++) {
var ipWithPort = peerSummary.getpeerinfo[i].addr;
let peerIps = [];
for (let i = 0; i < peerSummary.getpeerinfo.length; i++) {
let ipWithPort = peerSummary.getpeerinfo[i].addr;
if (ipWithPort.lastIndexOf(":") >= 0) {
var ip = ipWithPort.substring(0, ipWithPort.lastIndexOf(":"));
let ip = ipWithPort.substring(0, ipWithPort.lastIndexOf(":"));
if (ip.trim().length > 0) {
peerIps.push(ip.trim());
}
@ -424,10 +424,10 @@ router.get("/peers", asyncHandler(async (req, res, next) => {
}));
router.post("/connect", function(req, res, next) {
var host = req.body.host;
var port = req.body.port;
var username = req.body.username;
var password = req.body.password;
let host = req.body.host;
let port = req.body.port;
let username = req.body.username;
let password = req.body.password;
res.cookie('rpc-host', host);
res.cookie('rpc-port', port);
@ -437,7 +437,7 @@ router.post("/connect", function(req, res, next) {
req.session.port = port;
req.session.username = username;
var newClient = new bitcoinCore({
let newClient = new bitcoinCore({
host: host,
port: port,
username: username,
@ -496,7 +496,7 @@ router.get("/changeSetting", function(req, res, next) {
req.session.userSettings[req.query.name.toString()] = req.query.value.toString();
var userSettings = JSON.parse(req.cookies["user-settings"] || "{}");
let userSettings = JSON.parse(req.cookies["user-settings"] || "{}");
userSettings[req.query.name] = req.query.value;
res.cookie("user-settings", JSON.stringify(userSettings));
@ -549,9 +549,9 @@ router.get("/blocks", asyncHandler(async (req, res, next) => {
const { perfId, perfResults } = utils.perfLogNewItem({action:"blocks"});
res.locals.perfId = perfId;
var limit = config.site.browseBlocksPageSize;
var offset = 0;
var sort = "desc";
let limit = config.site.browseBlocksPageSize;
let offset = 0;
let sort = "desc";
if (req.query.limit) {
limit = parseInt(req.query.limit);
@ -573,20 +573,20 @@ router.get("/blocks", asyncHandler(async (req, res, next) => {
// if pruning is active, global.pruneHeight is used when displaying this page
// global.pruneHeight is updated whenever we send a getblockchaininfo RPC to the node
var getblockchaininfo = await utils.timePromise("blocks.geoLocateIpAddresses", coreApi.getBlockchainInfo, perfResults);
let getblockchaininfo = await utils.timePromise("blocks.geoLocateIpAddresses", coreApi.getBlockchainInfo, perfResults);
res.locals.blockCount = getblockchaininfo.blocks;
res.locals.blockOffset = offset;
var blockHeights = [];
let blockHeights = [];
if (sort == "desc") {
for (var i = (getblockchaininfo.blocks - offset); i > (getblockchaininfo.blocks - offset - limit - 1); i--) {
for (let i = (getblockchaininfo.blocks - offset); i > (getblockchaininfo.blocks - offset - limit - 1); i--) {
if (i >= 0) {
blockHeights.push(i);
}
}
} else {
for (var i = offset - 1; i < (offset + limit); i++) {
for (let i = offset - 1; i < (offset + limit); i++) {
if (i >= 0) {
blockHeights.push(i);
}
@ -598,7 +598,7 @@ router.get("/blocks", asyncHandler(async (req, res, next) => {
});
var promises = [];
let promises = [];
promises.push(utils.timePromise("blocks.getBlocksByHeight", async () => {
res.locals.blocks = await coreApi.getBlocksByHeight(blockHeights);
@ -607,13 +607,13 @@ router.get("/blocks", asyncHandler(async (req, res, next) => {
promises.push(utils.timePromise("blocks.getBlocksByHeight", async () => {
try {
var rawblockstats = await coreApi.getBlocksStatsByHeight(blockHeights);
let rawblockstats = await coreApi.getBlocksStatsByHeight(blockHeights);
if (rawblockstats != null && rawblockstats.length > 0 && rawblockstats[0] != null) {
res.locals.blockstatsByHeight = {};
for (var i = 0; i < rawblockstats.length; i++) {
var blockstats = rawblockstats[i];
for (let i = 0; i < rawblockstats.length; i++) {
let blockstats = rawblockstats[i];
res.locals.blockstatsByHeight[blockstats.height] = blockstats;
}
@ -653,7 +653,7 @@ router.get("/blocks", asyncHandler(async (req, res, next) => {
router.get("/mining-summary", asyncHandler(async (req, res, next) => {
try {
var getblockchaininfo = await utils.timePromise("mining-summary.getBlockchainInfo", coreApi.getBlockchainInfo);
let getblockchaininfo = await utils.timePromise("mining-summary.getBlockchainInfo", coreApi.getBlockchainInfo);
res.locals.currentBlockHeight = getblockchaininfo.blocks;
@ -911,8 +911,8 @@ router.get("/next-block", asyncHandler(async (req, res, next) => {
let feeRate = tx.fee / tx.weight * 4;
if (tx.depends && tx.depends.length > 0) {
var totalFee = tx.fee;
var totalWeight = tx.weight;
let totalFee = tx.fee;
let totalWeight = tx.weight;
tx.depends.forEach(index => {
totalFee += blockTemplate.transactions[index - 1].fee;
@ -970,8 +970,8 @@ router.post("/search", function(req, res, next) {
return;
}
var query = req.body.query.toLowerCase().trim();
var rawCaseQuery = req.body.query.trim();
let query = req.body.query.toLowerCase().trim();
let rawCaseQuery = req.body.query.trim();
req.session.query = req.body.query;
@ -1043,14 +1043,14 @@ router.get("/block-height/:blockHeight", asyncHandler(async (req, res, next) =>
const { perfId, perfResults } = utils.perfLogNewItem({action:"block-height"});
res.locals.perfId = perfId;
var blockHeight = parseInt(req.params.blockHeight);
let blockHeight = parseInt(req.params.blockHeight);
res.locals.blockHeight = blockHeight;
res.locals.result = {};
var limit = config.site.blockTxPageSize;
var offset = 0;
let limit = config.site.blockTxPageSize;
let offset = 0;
res.locals.maxTxOutputDisplayCount = 15;
@ -1080,7 +1080,7 @@ router.get("/block-height/:blockHeight", asyncHandler(async (req, res, next) =>
res.locals.result.getblockbyheight = result;
var promises = [];
let promises = [];
promises.push(utils.timePromise("block-height.getBlockByHashWithTransactions", async () => {
const blockWithTransactions = await coreApi.getBlockByHashWithTransactions(result.hash, limit, offset);
@ -1152,14 +1152,14 @@ router.get("/block/:blockHash", asyncHandler(async (req, res, next) => {
const { perfId, perfResults } = utils.perfLogNewItem({action:"block"});
res.locals.perfId = perfId;
var blockHash = utils.asHash(req.params.blockHash);
let blockHash = utils.asHash(req.params.blockHash);
res.locals.blockHash = blockHash;
res.locals.result = {};
var limit = config.site.blockTxPageSize;
var offset = 0;
let limit = config.site.blockTxPageSize;
let offset = 0;
res.locals.maxTxOutputDisplayCount = 15;
@ -1182,7 +1182,7 @@ router.get("/block/:blockHash", asyncHandler(async (req, res, next) => {
res.locals.offset = offset;
res.locals.paginationBaseUrl = "./block/" + blockHash;
var promises = [];
let promises = [];
promises.push(utils.timePromise("block.getBlockByHashWithTransactions", async () => {
const blockWithTransactions = await coreApi.getBlockByHashWithTransactions(blockHash, limit, offset);
@ -1295,7 +1295,7 @@ router.get("/predicted-blocks-old", asyncHandler(async (req, res, next) => {
let currentBlock = Object.assign({}, blockTemplate);
for (var i = 0; i < mempoolTxSummaries.length; i++) {
for (let i = 0; i < mempoolTxSummaries.length; i++) {
const tx = mempoolTxSummaries[i];
tx.frw = tx.f / tx.w;
@ -1337,18 +1337,16 @@ router.get("/predicted-blocks-old", asyncHandler(async (req, res, next) => {
}));
router.get("/block-analysis/:blockHashOrHeight", function(req, res, next) {
var blockHashOrHeight = utils.asHashOrHeight(req.params.blockHashOrHeight);
var goWithBlockHash = function(blockHash) {
var blockHash = blockHash;
let blockHashOrHeight = utils.asHashOrHeight(req.params.blockHashOrHeight);
let goWithBlockHash = function(blockHash) {
res.locals.blockHash = blockHash;
res.locals.result = {};
var txResults = [];
let txResults = [];
var promises = [];
let promises = [];
res.locals.result = {};
@ -1397,9 +1395,9 @@ router.get("/tx/:transactionId", asyncHandler(async (req, res, next) => {
const { perfId, perfResults } = utils.perfLogNewItem({action:"transaction"});
res.locals.perfId = perfId;
var txid = utils.asHash(req.params.transactionId);
let txid = utils.asHash(req.params.transactionId);
var output = -1;
let output = -1;
if (req.query.output) {
output = parseInt(req.query.output);
}
@ -1419,7 +1417,7 @@ router.get("/tx/:transactionId", asyncHandler(async (req, res, next) => {
let txInputLimit = (res.locals.crawlerBot) ? 3 : -1;
var txPromise = req.query.blockHeight ?
let txPromise = req.query.blockHeight ?
async () => {
const block = await coreApi.getBlockByHeight(parseInt(req.query.blockHeight));
res.locals.block = block;
@ -1432,7 +1430,7 @@ router.get("/tx/:transactionId", asyncHandler(async (req, res, next) => {
const rawTxResult = await utils.timePromise("tx.getRawTransactionsWithInputs", txPromise, perfResults);
var tx = rawTxResult.transactions[0];
let tx = rawTxResult.transactions[0];
res.locals.tx = tx;
res.locals.isCoinbaseTx = tx.vin[0].coinbase;
@ -1516,9 +1514,9 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
const { perfId, perfResults } = utils.perfLogNewItem({action:"address"});
res.locals.perfId = perfId;
var limit = config.site.addressTxPageSize;
var offset = 0;
var sort = "desc";
let limit = config.site.addressTxPageSize;
let offset = 0;
let sort = "desc";
res.locals.maxTxOutputDisplayCount = config.site.addressPage.txOutputMaxDefaultDisplay;
@ -1543,7 +1541,7 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
}
var address = utils.asAddress(req.params.address);
let address = utils.asAddress(req.params.address);
res.locals.metaTitle = `Bitcoin Address ${address}`;
@ -1557,11 +1555,11 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
res.locals.result = {};
var addressEncoding = "unknown";
let addressEncoding = "unknown";
var base58Error = null;
var bech32Error = null;
var bech32mError = null;
let base58Error = null;
let bech32Error = null;
let bech32mError = null;
let b58prefix = (global.activeBlockchain == "main" ? /^[13].*$/ : /^[2mn].*$/);
if (address.match(b58prefix)) {
@ -1618,7 +1616,7 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
res.locals.addressEncoding = addressEncoding;
if (global.miningPoolsConfigs) {
for (var i = 0; i < global.miningPoolsConfigs.length; i++) {
for (let i = 0; i < global.miningPoolsConfigs.length; i++) {
if (global.miningPoolsConfigs[i].payout_addresses[address]) {
res.locals.payoutAddressForMiner = global.miningPoolsConfigs[i].payout_addresses[address];
}
@ -1630,17 +1628,17 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
const validateaddressResult = await coreApi.getAddress(address);
res.locals.result.validateaddress = validateaddressResult;
var promises = [];
let promises = [];
if (!res.locals.crawlerBot) {
var addrScripthash = hexEnc.stringify(sha256(hexEnc.parse(validateaddressResult.scriptPubKey)));
let addrScripthash = hexEnc.stringify(sha256(hexEnc.parse(validateaddressResult.scriptPubKey)));
addrScripthash = addrScripthash.match(/.{2}/g).reverse().join("");
res.locals.electrumScripthash = addrScripthash;
promises.push(utils.timePromise("address.getAddressDetails", async () => {
const addressDetailsResult = await addressApi.getAddressDetails(address, validateaddressResult.scriptPubKey, sort, limit, offset);
var addressDetails = addressDetailsResult.addressDetails;
let addressDetails = addressDetailsResult.addressDetails;
if (addressDetailsResult.errors) {
res.locals.addressDetailsErrors = addressDetailsResult.errors;
@ -1660,10 +1658,10 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
}
if (addressDetails.txids) {
var txids = addressDetails.txids;
let txids = addressDetails.txids;
// if the active addressApi gives us blockHeightsByTxid, it saves us work, so try to use it
var blockHeightsByTxid = {};
let blockHeightsByTxid = {};
if (addressDetails.blockHeightsByTxid) {
blockHeightsByTxid = addressDetails.blockHeightsByTxid;
}
@ -1681,11 +1679,11 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
// for coinbase txs, we need the block height in order to calculate subsidy to display
var coinbaseTxs = [];
for (var i = 0; i < rawTxResult.transactions.length; i++) {
var tx = rawTxResult.transactions[i];
let coinbaseTxs = [];
for (let i = 0; i < rawTxResult.transactions.length; i++) {
let tx = rawTxResult.transactions[i];
for (var j = 0; j < tx.vin.length; j++) {
for (let j = 0; j < tx.vin.length; j++) {
if (tx.vin[j].coinbase) {
// addressApi sometimes has blockHeightByTxid already available, otherwise we need to query for it
if (!blockHeightsByTxid[tx.txid]) {
@ -1696,19 +1694,19 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
}
var coinbaseTxBlockHashes = [];
var blockHashesByTxid = {};
let coinbaseTxBlockHashes = [];
let blockHashesByTxid = {};
coinbaseTxs.forEach(function(tx) {
coinbaseTxBlockHashes.push(tx.blockhash);
blockHashesByTxid[tx.txid] = tx.blockhash;
});
var blockHeightsPromises = [];
let blockHeightsPromises = [];
if (coinbaseTxs.length > 0) {
// we need to query some blockHeights by hash for some coinbase txs
blockHeightsPromises.push(utils.timePromise("address.getBlocksByHash", async () => {
const blocksByHashResult = await coreApi.getBlocksByHash(coinbaseTxBlockHashes);
for (var txid in blockHashesByTxid) {
for (let txid in blockHashesByTxid) {
if (blockHashesByTxid.hasOwnProperty(txid)) {
blockHeightsByTxid[txid] = blocksByHashResult[blockHashesByTxid[txid]].height;
}
@ -1718,17 +1716,17 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
await utils.awaitPromises(blockHeightsPromises);
var addrGainsByTx = {};
var addrLossesByTx = {};
let addrGainsByTx = {};
let addrLossesByTx = {};
res.locals.addrGainsByTx = addrGainsByTx;
res.locals.addrLossesByTx = addrLossesByTx;
var handledTxids = [];
let handledTxids = [];
for (var i = 0; i < rawTxResult.transactions.length; i++) {
var tx = rawTxResult.transactions[i];
var txInputs = rawTxResult.txInputsByTransaction[tx.txid] || {};
for (let i = 0; i < rawTxResult.transactions.length; i++) {
let tx = rawTxResult.transactions[i];
let txInputs = rawTxResult.txInputsByTransaction[tx.txid] || {};
if (handledTxids.includes(tx.txid)) {
continue;
@ -1736,7 +1734,7 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
handledTxids.push(tx.txid);
for (var j = 0; j < tx.vout.length; j++) {
for (let j = 0; j < tx.vout.length; j++) {
if (tx.vout[j].value > 0 && tx.vout[j].scriptPubKey) {
if (utils.getVoutAddresses(tx.vout[j]).includes(address)) {
if (addrGainsByTx[tx.txid] == null) {
@ -1748,9 +1746,9 @@ router.get("/address/:address", asyncHandler(async (req, res, next) => {
}
}
for (var j = 0; j < tx.vin.length; j++) {
var txInput = txInputs[j];
var vinJ = tx.vin[j];
for (let j = 0; j < tx.vin.length; j++) {
let txInput = txInputs[j];
let vinJ = tx.vin[j];
if (txInput != null) {
if (txInput && txInput.scriptPubKey) {
@ -1833,9 +1831,9 @@ router.post("/rpc-terminal", asyncHandler(async (req, res, next) => {
return;
}
var params = req.body.cmd.trim().split(/\s+/);
var cmd = params.shift();
var parsedParams = [];
let params = req.body.cmd.trim().split(/\s+/);
let cmd = params.shift();
let parsedParams = [];
params.forEach((param, i) => {
try {
@ -1896,8 +1894,9 @@ router.get("/rpc-browser", asyncHandler(async (req, res, next) => {
const helpContent = await coreApi.getHelp();
res.locals.gethelp = helpContent;
var method = "unknown";
var argValues = [];
let method = "unknown";
let argValues = [];
if (req.query.method) {
method = req.query.method;
@ -1919,16 +1918,16 @@ router.get("/rpc-browser", asyncHandler(async (req, res, next) => {
res.locals.methodhelp = methodHelp;
if (req.query.execute) {
var argDetails = methodHelp.args;
let argDetails = methodHelp.args;
if (req.query.args) {
debugLog("ARGS: " + JSON.stringify(req.query.args));
for (var i = 0; i < req.query.args.length; i++) {
var argProperties = argDetails[i].properties;
for (let i = 0; i < req.query.args.length; i++) {
let argProperties = argDetails[i].properties;
debugLog(`ARG_PROPS[${i}]: ` + JSON.stringify(argProperties));
for (var j = 0; j < argProperties.length; j++) {
for (let j = 0; j < argProperties.length; j++) {
if (argProperties[j] === "numeric") {
if (req.query.args[i] == null || req.query.args[i] == "") {
argValues.push(null);
@ -1986,7 +1985,7 @@ router.get("/rpc-browser", asyncHandler(async (req, res, next) => {
return;
}
//var csurfPromise =
//let csurfPromise =
await new Promise((resolve, reject) => {
forceCsrf(req, res, async (err) => {
@ -2058,13 +2057,13 @@ router.get("/terminal", function(req, res, next) {
});
router.post("/terminal", function(req, res, next) {
var params = req.body.cmd.trim().split(/\s+/);
var cmd = params.shift();
var paramsStr = req.body.cmd.trim().substring(cmd.length).trim();
let params = req.body.cmd.trim().split(/\s+/);
let cmd = params.shift();
let paramsStr = req.body.cmd.trim().substring(cmd.length).trim();
if (cmd == "parsescript") {
const nbs = require('node-bitcoin-script');
var parsedScript = nbs.parseRawScript(paramsStr, "hex");
let parsedScript = nbs.parseRawScript(paramsStr, "hex");
res.write(JSON.stringify({"parsed":parsedScript}, null, 4), function() {
res.end();
@ -2083,9 +2082,9 @@ router.post("/terminal", function(req, res, next) {
router.get("/mempool-transactions", asyncHandler(async (req, res, next) => {
try {
var limit = config.site.browseMempoolTransactionsPageSize;
var offset = 0;
var sort = "desc";
let limit = config.site.browseMempoolTransactionsPageSize;
let offset = 0;
let sort = "desc";
if (req.query.limit) {
limit = parseInt(req.query.limit);
@ -2264,7 +2263,7 @@ router.get("/fun", function(req, res, next) {
return 1;
} else {
var x = a.type.localeCompare(b.type);
let x = a.type.localeCompare(b.type);
if (x == 0) {
if (a.type == "blockheight") {
@ -2372,8 +2371,8 @@ router.get("/bitcoin.pdf", function(req, res, next) {
Promise.all([...Array(946).keys()].map(vout => coreApi.getTxOut(whitepaperTxid, vout)))
.then(function (vouts) {
// concatenate all multisig pubkeys
var pdfData = vouts.map((out, n) => {
var parts = out.scriptPubKey.asm.split(" ")
let pdfData = vouts.map((out, n) => {
let parts = out.scriptPubKey.asm.split(" ")
// the last output is a 1-of-1
return n == 945 ? parts[1] : parts.slice(1,4).join('')
}).join('')

View file

@ -28,10 +28,10 @@ const forceCsrf = csurf({ ignoreMethods: [] });
router.get("/blocks-by-height/:blockHeights", function(req, res, next) {
var blockHeightStrs = req.params.blockHeights.split(",");
let blockHeightStrs = req.params.blockHeights.split(",");
var blockHeights = [];
for (var i = 0; i < blockHeightStrs.length; i++) {
let blockHeights = [];
for (let i = 0; i < blockHeightStrs.length; i++) {
blockHeights.push(parseInt(blockHeightStrs[i]));
}
@ -41,10 +41,10 @@ router.get("/blocks-by-height/:blockHeights", function(req, res, next) {
});
router.get("/block-headers-by-height/:blockHeights", function(req, res, next) {
var blockHeightStrs = req.params.blockHeights.split(",");
let blockHeightStrs = req.params.blockHeights.split(",");
var blockHeights = [];
for (var i = 0; i < blockHeightStrs.length; i++) {
let blockHeights = [];
for (let i = 0; i < blockHeightStrs.length; i++) {
blockHeights.push(parseInt(blockHeightStrs[i]));
}
@ -56,10 +56,10 @@ router.get("/block-headers-by-height/:blockHeights", function(req, res, next) {
});
router.get("/block-stats-by-height/:blockHeights", function(req, res, next) {
var blockHeightStrs = req.params.blockHeights.split(",");
let blockHeightStrs = req.params.blockHeights.split(",");
var blockHeights = [];
for (var i = 0; i < blockHeightStrs.length; i++) {
let blockHeights = [];
for (let i = 0; i < blockHeightStrs.length; i++) {
blockHeights.push(parseInt(blockHeightStrs[i]));
}
@ -71,11 +71,11 @@ router.get("/block-stats-by-height/:blockHeights", function(req, res, next) {
});
router.get("/mempool-txs/:txids", function(req, res, next) {
var txids = req.params.txids.split(",").map(utils.asHash);
let txids = req.params.txids.split(",").map(utils.asHash);
var promises = [];
let promises = [];
for (var i = 0; i < txids.length; i++) {
for (let i = 0; i < txids.length; i++) {
promises.push(coreApi.getMempoolTxDetails(txids[i], false));
}
@ -126,7 +126,7 @@ router.get("/get-predicted-blocks", asyncHandler(async (req, res, next) => {
const statusId = req.query.statusId;
if (statusId && predictedBlocksOutputs[statusId]) {
var output = predictedBlocksOutputs[statusId];
let output = predictedBlocksOutputs[statusId];
res.json(output);
@ -158,7 +158,7 @@ router.get("/build-predicted-blocks", asyncHandler(async (req, res, next) => {
next();
var output = await coreApi.buildPredictedBlocks(statusId, (update) => {
let output = await coreApi.buildPredictedBlocks(statusId, (update) => {
predictedBlocksStatuses[statusId] = update;
});
@ -193,7 +193,7 @@ router.get("/get-mempool-summary", asyncHandler(async (req, res, next) => {
const statusId = req.query.statusId;
if (statusId && mempoolSummaries[statusId]) {
var summary = mempoolSummaries[statusId];
let summary = mempoolSummaries[statusId];
res.json(summary);
@ -221,22 +221,23 @@ router.get("/build-mempool-summary", asyncHandler(async (req, res, next) => {
mempoolSummaryStatuses[statusId] = {};
}
res.json({success:true, status:"started"});
next();
const ageBuckets = req.query.ageBuckets ? parseInt(req.query.ageBuckets) : 100;
const sizeBuckets = req.query.sizeBuckets ? parseInt(req.query.sizeBuckets) : 100;
var summary = await coreApi.buildMempoolSummary(statusId, ageBuckets, sizeBuckets, (update) => {
let summary = await coreApi.buildMempoolSummary(statusId, ageBuckets, sizeBuckets, (update) => {
mempoolSummaryStatuses[statusId] = update;
});
// store summary until it's retrieved via /api/get-mempool-summary
mempoolSummaries[statusId] = summary;
res.json({success:true, status:"started"});
next();
} catch (err) {
utils.logError("329r7whegee", err);
}
@ -266,7 +267,7 @@ router.get("/get-mining-summary", asyncHandler(async (req, res, next) => {
const statusId = req.query.statusId;
if (statusId && miningSummaries[statusId]) {
var summary = miningSummaries[statusId];
let summary = miningSummaries[statusId];
res.json(summary);
@ -289,9 +290,8 @@ router.get("/build-mining-summary/:startBlock/:endBlock", asyncHandler(async (re
res.connection.setTimeout(600000);
var startBlock = parseInt(req.params.startBlock);
var endBlock = parseInt(req.params.endBlock);
let startBlock = parseInt(req.params.startBlock);
let endBlock = parseInt(req.params.endBlock);
const statusId = req.query.statusId;
if (statusId) {
@ -304,7 +304,7 @@ router.get("/build-mining-summary/:startBlock/:endBlock", asyncHandler(async (re
var summary = await coreApi.buildMiningSummary(statusId, startBlock, endBlock, (update) => {
let summary = await coreApi.buildMiningSummary(statusId, startBlock, endBlock, (update) => {
miningSummaryStatuses[statusId] = update;
});
@ -328,7 +328,7 @@ router.get("/mempool-tx-summaries/:txids", asyncHandler(async (req, res, next) =
const promises = [];
const results = [];
for (var i = 0; i < txids.length; i++) {
for (let i = 0; i < txids.length; i++) {
const txid = txids[i];
const key = txid.substring(0, 6);
@ -372,9 +372,9 @@ router.get("/mempool-tx-summaries/:txids", asyncHandler(async (req, res, next) =
}));
router.get("/raw-tx-with-inputs/:txid", function(req, res, next) {
var txid = utils.asHash(req.params.txid);
let txid = utils.asHash(req.params.txid);
var promises = [];
let promises = [];
promises.push(coreApi.getRawTransactionsWithInputs([txid]));
@ -391,13 +391,13 @@ router.get("/raw-tx-with-inputs/:txid", function(req, res, next) {
});
router.get("/block-tx-summaries/:blockHash/:blockHeight/:txids", function(req, res, next) {
var blockHash = req.params.blockHash;
var blockHeight = parseInt(req.params.blockHeight);
var txids = req.params.txids.split(",").map(utils.asHash);
let blockHash = req.params.blockHash;
let blockHeight = parseInt(req.params.blockHeight);
let txids = req.params.txids.split(",").map(utils.asHash);
var promises = [];
let promises = [];
var results = [];
let results = [];
promises.push(new Promise(function(resolve, reject) {
coreApi.buildBlockAnalysisData(blockHeight, blockHash, txids, 0, results, resolve);
@ -416,14 +416,14 @@ router.get("/block-tx-summaries/:blockHash/:blockHeight/:txids", function(req, r
});
router.get("/utils/:func/:params", function(req, res, next) {
var func = req.params.func;
var params = req.params.params;
let func = req.params.func;
let params = req.params.params;
var data = null;
let data = null;
if (func == "formatLargeNumber") {
if (params.indexOf(",") > -1) {
var parts = params.split(",");
let parts = params.split(",");
data = utils.formatLargeNumber(parseInt(parts[0]), parseInt(parts[1]));
@ -431,7 +431,7 @@ router.get("/utils/:func/:params", function(req, res, next) {
data = utils.formatLargeNumber(parseInt(params));
}
} else if (func == "formatCurrencyAmountInSmallestUnits") {
var parts = params.split(",");
let parts = params.split(",");
data = utils.formatCurrencyAmountInSmallestUnits(new Decimal(parts[0]), parseInt(parts[1]));

View file

@ -9,16 +9,11 @@ const router = express.Router();
const util = require('util');
const moment = require('moment');
const bitcoinCore = require("btc-rpc-client");
const qrcode = require('qrcode');
const bitcoinjs = require('bitcoinjs-lib');
const bip32 = require('bip32');
const bs58check = require('bs58check');
const { bech32, bech32m } = require("bech32");
const sha256 = require("crypto-js/sha256");
const hexEnc = require("crypto-js/enc-hex");
const Decimal = require("decimal.js");
const semver = require("semver");
const markdown = require("markdown-it")();
const asyncHandler = require("express-async-handler");
const utils = require('./../app/utils.js');

View file

@ -536,7 +536,7 @@ block endOfBody
row.find(".data-txid").html(`<a href="./tx/${topfeeTx.txid}">${topfeeTx.txid.substring(0, 16)}...</a>`);
row.find(".data-feerate").text(new Decimal(topfeeTx.feePerByte).times(100000000).times(4).toDP(1));
row.find(".data-feerate").text(new Decimal(topfeeTx.feePerByte).times(4).toDP(1));
row.show();
@ -687,7 +687,7 @@ block endOfBody
if (resultList && resultList.length > 0) {
var result = resultList[0];
var feeRate = new Decimal(result.f).times(100000000).dividedBy(result.sz); // TODO: magic number, sat/BTC
var feeRate = new Decimal(result.f).dividedBy(result.sz); // TODO: magic number, sat/BTC
estimateMempoolDepth(feeRate);

View file

@ -391,10 +391,18 @@ block content
+pageTab("JSON")
if (result.getrawtransaction.hex.length <= 50000)
- var pillTabs = ["Transaction", "Block Header", "UTXOs"];
- var pillTabs = ["Transaction"];
if (!mempoolDetails)
- pillTabs.push("Block Header");
- pillTabs.push("UTXOs");
if (mempoolDetails)
- pillTabs.push("Mempool Details");
else
+pillTabs(pillTabs)
.tab-content