mirror of
https://github.com/janoside/btc-rpc-explorer.git
synced 2026-08-13 12:33:13 +02:00
misc: lint; modernization; tweak mempool cache/keys; tx page: don't show block header JSON tab for unconfirmed
This commit is contained in:
parent
81558b5829
commit
4aac1420b9
16 changed files with 569 additions and 560 deletions
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"commonjs": true,
|
||||
"es2021": true
|
||||
},
|
||||
|
|
|
|||
4
app.js
4
app.js
|
|
@ -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 = {};
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
];
|
||||
|
|
|
|||
190
app/utils.js
190
app/utils.js
|
|
@ -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
6
npm-shrinkwrap.json
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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('')
|
||||
|
|
|
|||
|
|
@ -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]));
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue