Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas page #401

Merged
merged 13 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"ace-mode-solidity": "^0.1.1",
"axios": "^0.21.1",
"axios-cache-interceptor": "1",
"chart.js": "3.9.1",
"chart.js": "^4.4.7",
"chartjs-plugin-zoom": "^2.0.1",
"chokidar": "^3.5.0",
"codemirror": "^6.0.1",
Expand All @@ -67,7 +67,7 @@
"util": "^0.12.5",
"v-stripe-elements": "^1.2.0",
"vue": "^3.5.1",
"vue-chartjs": "4.1.2",
"vue-chartjs": "^5.3.2",
"vue-json-pretty": "^2.2.4",
"vue-moment": "^4.1.0",
"vue-router": "4",
Expand Down
127 changes: 127 additions & 0 deletions run/api/gas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
const express = require('express');
const router = express.Router();
const db = require('../lib/firebase');
const workspaceAuthMiddleware = require('../middlewares/workspaceAuth');
const { unmanagedError } = require('../lib/errors');

/*
Return gas stats for the explorer

@returns {object} - The gas stats
- blockNumber: The block number it was calculated on
- averageBlockSize: The average block size in transactions
- averageUtilization: The average quantity of gas used per block
- averageBlockTime: The average block time in seconds
- latestBlockNumber: The number of the latest block used for this calculation
- baseFeePerGas: The base fee per gas for the latest block
- priorityFeePerGas: The three levels of priority fee per gas for the latest block (slow, average, fast)
*/
router.get('/stats', workspaceAuthMiddleware, async (req, res, next) => {
const data = req.query;

try {
const result = await db.getLatestGasStats(data.workspace.id, data.intervalInMinutes);

res.status(200).json(result);
} catch(error) {
unmanagedError(error, req, next);
}
});

/*
Return gas price history for the explorer

@returns {array} - The gas price history
*/
router.get('/priceHistory', workspaceAuthMiddleware, async (req, res, next) => {
const data = req.query;

try {
const result = await db.getGasPriceHistory(data.workspace.id, data.from, data.to);

res.status(200).json(result);
} catch(error) {
unmanagedError(error, req, next);
}
});

/*
Return gas limit history for the explorer

@returns {array} - The gas limit history
- day: The day of the gas limit history
- gasLimit: The average gas limit for the day
*/
router.get('/limitHistory', workspaceAuthMiddleware, async (req, res, next) => {
const data = req.query;

try {
const result = await db.getGasLimitHistory(data.workspace.id, data.from, data.to);

res.status(200).json(result);
} catch(error) {
unmanagedError(error, req, next);
}
});

/*
Return gas utilization ratio history for the explorer

@returns {array} - The gas utilization ratio history
- day: The day of the gas utilization ratio history
- gasUtilizationRatio: The average gas utilization ratio for the day
*/
router.get('/utilizationRatioHistory', workspaceAuthMiddleware, async (req, res, next) => {
const data = req.query;

try {
const result = await db.getGasUtilizationRatioHistory(data.workspace.id, data.from, data.to);

res.status(200).json(result);
} catch(error) {
unmanagedError(error, req, next);
}
});

/*
Return the latest biggest gas consumers for the explorer:

@returns {array} - The latest biggest gas consumers
- to: The address of the gas consumer
- gasUsed: The total gas used by the gas consumer
- gasCost: Cost of total gas used
*/
router.get('/consumers', workspaceAuthMiddleware, async (req, res, next) => {
const data = req.query;

try {
const result = await db.getLatestGasConsumers(data.workspace.id, data.intervalInHours, data.limit);

res.status(200).json(result);
} catch(error) {
unmanagedError(error, req, next);
}
});

/*
Return the latest biggest gas spenders for the explorer:

@returns {array} - The latest biggest gas spenders
- from: The address of the gas spender
- gasUsed: The total gas used by the gas spender
- gasCost: Cost of total gas used
- percentUsed: The percentage of total gas used by the gas spender
*/
router.get('/spenders', workspaceAuthMiddleware, async (req, res, next) => {
const data = req.query;

try {
const result = await db.getLatestGasSpenders(data.workspace.id, data.intervalInHours, data.limit);

res.status(200).json(result);
} catch(error) {
unmanagedError(error, req, next);
}
});

module.exports = router;
2 changes: 2 additions & 0 deletions run/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const external = require('./external');
const domains = require('./domains');
const faucets = require('./faucets');
const v2Dexes = require('./v2Dexes');
const gas = require('./gas');

router.use('/blocks', blocks);
router.use('/contracts', contracts);
Expand All @@ -41,6 +42,7 @@ router.use('/external', external);
router.use('/domains', domains);
router.use('/faucets', faucets);
router.use('/v2_dexes', v2Dexes);
router.use('/gas', gas);

if (isDemoEnabled()) {
const demo = require('./demo');
Expand Down
158 changes: 157 additions & 1 deletion run/lib/firebase.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
This file contains all the methods to interact with
models from the API. They check for parameters,
make sure the required resources exist and can
be accessed by the user.
APIs should use methods from this file and not interact
with the models directly.
Background jobs do not need to use methods here and
can interact with the models directly, as they are not
exposed to the user.
*/
const Sequelize = require('sequelize');
const { getDemoUserId, getMaxBlockForSyncReset } = require('./env');
const models = require('../models');
Expand All @@ -21,6 +32,145 @@ const ExplorerFaucet = models.ExplorerFaucet;
const ExplorerV2Dex = models.ExplorerV2Dex;
const V2DexPair = models.V2DexPair;

/*
This method is used to get the latest biggest gas spenders for a workspace
for a given interval (now - intervalInHours).

@param {number} workspaceId - The ID of the workspace
@param {number} intervalInHours - The interval in hours to get the gas spenders for
@param {number} limit - The limit of gas spenders to return
@returns {array} - The gas spenders
- from: The address of the gas spender
- gasUsed: The total gas used by the gas spender
- gasCost: Cost of total gas used
- percentUsed: The percentage of total gas used by the gas spender
*/
const getLatestGasSpenders = async (workspaceId, intervalInHours = 24, limit = 50) => {
if (!workspaceId)
throw new Error('Missing parameter');

const workspace = await Workspace.findByPk(workspaceId);
if (!workspace)
throw new Error('Could not find workspace');

return workspace.getLatestGasSpenders(intervalInHours, limit);
};

/*
This method is used to get the latest biggest gas consumers for a workspace
for a given interval (now - intervalInHours).

@param {number} workspaceId - The ID of the workspace
@param {number} intervalInHours - The interval in hours to get the gas consumers for
@param {number} limit - The limit of gas consumers to return
@returns {array} - The gas consumers
- to: The address of the gas consumer
- gasUsed: The total gas used by the gas consumer
- gasCost: Cost of total gas used
*/
const getLatestGasConsumers = async (workspaceId, intervalInHours = 24, limit = 50) => {
if (!workspaceId)
throw new Error('Missing parameter');

const workspace = await Workspace.findByPk(workspaceId);
if (!workspace)
throw new Error('Could not find workspace');

return workspace.getLatestGasConsumers(intervalInHours, limit);
};

/*
This method is used to get the gas utilization ratio history for a workspace.

@param {number} workspaceId - The ID of the workspace
@param {string} from - The start date of the gas utilization ratio history
@param {string} to - The end date of the gas utilization ratio history
@returns {array} - The gas utilization ratio history
- day: The day of the gas utilization ratio history
- gasUtilizationRatio: The average gas utilization ratio for the day
*/
const getGasUtilizationRatioHistory = async (workspaceId, from, to) => {
if (!workspaceId || !from || !to)
throw new Error('Missing parameter');

const workspace = await Workspace.findByPk(workspaceId);
if (!workspace)
throw new Error('Could not find workspace');

return workspace.getGasUtilizationRatioHistory(from, to);
};

/*
This method is used to get the gas limit history for a workspace.

@param {number} workspaceId - The ID of the workspace
@param {string} from - The start date of the gas limit history
@param {string} to - The end date of the gas limit history
@returns {array} - The gas limit history
- day: The day of the gas limit history
- gasLimit: The average gas limit for the day
*/
const getGasLimitHistory = async (workspaceId, from, to) => {
if (!workspaceId || !from || !to)
throw new Error('Missing parameter');

const workspace = await Workspace.findByPk(workspaceId);
if (!workspace)
throw new Error('Could not find workspace');

return workspace.getGasLimitHistory(from, to);
};

/*
This method is used to get the gas price history for a workspace.

@param {number} workspaceId - The ID of the workspace
@param {string} from - The start date of the gas price history
@param {string} to - The end date of the gas price history
@returns {array} - The gas price history
- day: The day of the gas price history
- minSlow: The minimum slow gas price
- slow: The average slow gas price
- maxSlow: The maximum slow gas price
- minAverage: The minimum average gas price
- average: The average average gas price
- maxAverage: The maximum average gas price
- minFast: The minimum fast gas price
- fast: The average fast gas price
- maxFast: The maximum fast gas price
*/
const getGasPriceHistory = async (workspaceId, from, to) => {
if (!workspaceId || !from || !to)
throw new Error('Missing parameter');

const workspace = await Workspace.findByPk(workspaceId);
if (!workspace)
throw new Error('Could not find workspace');

return workspace.getGasPriceHistory(from, to);
};

/*
This method is used to get the latest gas stats for a workspace.

@param {number} workspaceId - The ID of the workspace
@param {number} intervalInMinutes - The interval in minutes to get the gas stats for
@returns {object} - The gas stats object
- averageBlockSize: The average block size in transactions
- averageUtilization: The average quantity of gas used per block
- averageBlockTime: The average block time in seconds
- latestBlockNumber: The number of the latest block used for this calculation
- baseFeePerGas: The base fee per gas for the latest block
- priorityFeePerGas: The three levels of priority fee per gas for the latest block (slow, average, fast)
*/
const getLatestGasStats = async (workspaceId, intervalInMinutes = 1) => {
const workspace = await Workspace.findByPk(workspaceId);
if (!workspace)
throw new Error('Could not find workspace');

return workspace.getLatestGasStats(intervalInMinutes);
};

const createUserStripeSubscription = (userId, stripeSubscription, stripePlan) => {
if (!userId || !stripeSubscription || !stripePlan)
throw new Error('Missing parameter');
Expand Down Expand Up @@ -2495,5 +2645,11 @@ module.exports = {
deleteV2Dex: deleteV2Dex,
getV2DexPairCount: getV2DexPairCount,
getUserStripeSubscription: getUserStripeSubscription,
createUserStripeSubscription: createUserStripeSubscription
createUserStripeSubscription: createUserStripeSubscription,
getLatestGasStats: getLatestGasStats,
getGasPriceHistory: getGasPriceHistory,
getGasLimitHistory: getGasLimitHistory,
getGasUtilizationRatioHistory: getGasUtilizationRatioHistory,
getLatestGasConsumers: getLatestGasConsumers,
getLatestGasSpenders: getLatestGasSpenders
};
9 changes: 8 additions & 1 deletion run/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ const ethers = require('ethers');

const DEFAULT_PROMISE_TIMEOUT = 10 * 1000;

const avg = (arr) => {
const sum = arr.reduce((a, v) => a + v);
return Math.round(sum/arr.length);
};


const sleep = (ms) => {
return new Promise((r) => setTimeout(r, ms))
};
Expand Down Expand Up @@ -181,5 +187,6 @@ module.exports = {
processRawRpcObject,
formatErc721Metadata,
validateBNString,
sleep
sleep,
avg
};
Loading