From 02002a9d054d385c117e643fe04c7b01841fcbf7 Mon Sep 17 00:00:00 2001 From: vird Date: Wed, 6 Dec 2023 08:13:21 +0200 Subject: [PATCH] get hashrate from new experimental metrics; hashrate -> networkHashrate; earnings -> avgBlockReward --- main/background.ts | 39 +++++++++++++++++-- renderer/pages/dashboard.tsx | 20 ++++++++-- renderer/store/metricsSlice/metricsSlice.ts | 4 ++ .../store/metricsSlice/metricsSliceHooks.ts | 7 ++++ .../metricsSlice/metricsSliceSelectors.ts | 4 ++ types/metrics.ts | 6 ++- 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/main/background.ts b/main/background.ts index 0b17186..63ae3a8 100644 --- a/main/background.ts +++ b/main/background.ts @@ -58,6 +58,7 @@ ipcMain.on("message", async (event, arg) => { // TODO make generic function for creating pub+sub endpoints // TODO make class for subscription management let cachedMetrics: SetMetricsStateActionPayload | null = null; +let longCachedMetrics: SetMetricsStateActionPayload | null = null; let cachedMetricsStr = ""; // TODO list of webContents // let cachedMetricsSubList = []; @@ -108,10 +109,10 @@ async function getMetrics(): Promise { } }); } - const hashRate = metricStringParse( + const networkHashRate = metricStringParse( parsed.find((item: PrometheusMetricParser) => item.name === "average_network_hash_rate"), ); - const earnings = metricStringParse( + const avgBlockReward = metricStringParse( parsed.find((item: PrometheusMetricParser) => item.name === "average_block_reward"), ); @@ -132,16 +133,40 @@ async function getMetrics(): Promise { const weaveSize = metricStringParse( parsed.find((item: PrometheusMetricParser) => item.name === "weave_size"), ); + + const hashCountWatermark: number = parsed + .filter( + (item: PrometheusMetricParser) => + item.name === "hash_1chunk_counter" || item.name === "hash_2chunk_counter", + ) + .map(metricStringParse) + .filter((t) => t) + .reduce((a, b) => a! + b!, 0)!; + + const ts = Date.now(); + let hashRate = 0; + if (longCachedMetrics) { + const oldTs = longCachedMetrics.ts; + const oldHashCountWatermark = longCachedMetrics.hashCountWatermark; + const deltaHashCount = hashCountWatermark - oldHashCountWatermark; + const deltaTs = ts - oldTs; + hashRate = (deltaHashCount / deltaTs) * 1000; + } + console.log("DEBUG: getMetrics complete"); return { dataUnpacked, dataPacked, storageAvailable, - weaveSize, + hashCountWatermark, hashRate, - earnings, + weaveSize, + networkHashRate, + avgBlockReward, + earnings: 0, // TODO call /balance/ vdfTimeLowerBound, node, + ts, }; } @@ -149,6 +174,12 @@ async function cachedMetricsUpdate() { try { cachedMetricsUpdateInProgress = true; cachedMetrics = await getMetrics(); + if ( + !longCachedMetrics || + longCachedMetrics.hashCountWatermark > cachedMetrics.hashCountWatermark + ) { + longCachedMetrics = cachedMetrics; + } } catch (err) { console.error(err); } diff --git a/renderer/pages/dashboard.tsx b/renderer/pages/dashboard.tsx index f6f414c..5ecb581 100644 --- a/renderer/pages/dashboard.tsx +++ b/renderer/pages/dashboard.tsx @@ -3,7 +3,11 @@ import { useDispatch } from "react-redux"; import ScrollSpy from "react-ui-scrollspy"; import isElectron from "is-electron"; import { MainLayout } from "../layouts/MainLayout"; -import { useEarnings, useHashRate } from "../store/metricsSlice/metricsSliceHooks"; +import { + useEarnings, + useHashRate, + useAvgBlockReward, +} from "../store/metricsSlice/metricsSliceHooks"; import { setMetricsState } from "../store/metricsSlice/metricsSlice"; import { SetMetricsStateActionPayload } from "../../types/metrics"; import DataRelated from "../components/DataRelated"; @@ -26,6 +30,7 @@ const menuItems: MenuItems[] = [ { label: "Data Related", target: "sub-section-1-1" }, { label: "Hash Rate", target: "sub-section-1-2" }, { label: "Earnings", target: "sub-section-1-3" }, + { label: "Average Block Reward", target: "sub-section-1-4" }, ], }, { @@ -43,6 +48,7 @@ export default function DashboardPage() { const dispatch = useDispatch(); const { hashRate } = useHashRate(); const { earnings } = useEarnings(); + const { avgBlockReward } = useAvgBlockReward(); const [activeMenu, setActiveMenu] = useState(); @@ -143,13 +149,21 @@ export default function DashboardPage() {

Hash Rate

{typeof hashRate === "number" && ( -

Hash rate: {hashRate}

+

Hash rate: {hashRate.toFixed(2)}

)}

Earnings

{typeof earnings === "number" && ( -

Earnings: {earnings}

+

Earnings: {earnings} AR

+ )} +
+
+

Average Block Reward

+ {typeof avgBlockReward === "number" && ( +

+ Average Block Reward: {(avgBlockReward / 1e12).toFixed(4)} AR +

)}
diff --git a/renderer/store/metricsSlice/metricsSlice.ts b/renderer/store/metricsSlice/metricsSlice.ts index 53480c6..d942e2a 100644 --- a/renderer/store/metricsSlice/metricsSlice.ts +++ b/renderer/store/metricsSlice/metricsSlice.ts @@ -10,6 +10,7 @@ export interface MetricsSliceReducerState { storageAvailable: number | undefined; weaveSize: number | undefined; hashRate: number | undefined; + avgBlockReward: number | undefined; earnings: number | undefined; vdfTimeLowerBound: number | undefined; } @@ -20,6 +21,7 @@ const initialMetricsState: MetricsSliceReducerState = { storageAvailable: undefined, weaveSize: undefined, hashRate: undefined, + avgBlockReward: undefined, earnings: undefined, vdfTimeLowerBound: undefined, }; @@ -38,6 +40,7 @@ export const metricsSlice = createSlice({ storageAvailable, weaveSize, hashRate, + avgBlockReward, earnings, vdfTimeLowerBound, } = action.payload; @@ -46,6 +49,7 @@ export const metricsSlice = createSlice({ state.storageAvailable = storageAvailable ?? undefined; state.weaveSize = weaveSize ?? undefined; state.hashRate = hashRate ?? undefined; + state.avgBlockReward = avgBlockReward ?? undefined; state.earnings = earnings ?? undefined; state.vdfTimeLowerBound = vdfTimeLowerBound ?? undefined; }, diff --git a/renderer/store/metricsSlice/metricsSliceHooks.ts b/renderer/store/metricsSlice/metricsSliceHooks.ts index 94a585f..79106ca 100644 --- a/renderer/store/metricsSlice/metricsSliceHooks.ts +++ b/renderer/store/metricsSlice/metricsSliceHooks.ts @@ -1,6 +1,7 @@ import { useSelector } from "react-redux"; import { selectHashRate, + selectAvgBlockReward, selectEarnings, selectDataPacked, selectDataUnpacked, @@ -14,6 +15,12 @@ export const useHashRate = () => { }); }; +export const useAvgBlockReward = () => { + return useSelector(selectAvgBlockReward, (prev, current) => { + return prev.avgBlockReward === current.avgBlockReward; + }); +}; + export const useEarnings = () => { return useSelector(selectEarnings, (prev, current) => { return prev.earnings === current.earnings; diff --git a/renderer/store/metricsSlice/metricsSliceSelectors.ts b/renderer/store/metricsSlice/metricsSliceSelectors.ts index 19dbb19..c9c021d 100644 --- a/renderer/store/metricsSlice/metricsSliceSelectors.ts +++ b/renderer/store/metricsSlice/metricsSliceSelectors.ts @@ -4,6 +4,10 @@ export const selectHashRate = (state: AppState) => ({ hashRate: state.metrics.hashRate, }); +export const selectAvgBlockReward = (state: AppState) => ({ + avgBlockReward: state.metrics.avgBlockReward, +}); + export const selectEarnings = (state: AppState) => ({ earnings: state.metrics.earnings, }); diff --git a/types/metrics.ts b/types/metrics.ts index 9e7c996..1f663be 100644 --- a/types/metrics.ts +++ b/types/metrics.ts @@ -3,9 +3,13 @@ export interface SetMetricsStateActionPayload { dataUnpacked: number | null; dataPacked: number | null; storageAvailable: number | null; - weaveSize: number | null; + hashCountWatermark: number; hashRate: number | null; + weaveSize: number | null; + networkHashRate: number | null; + avgBlockReward: number | null; earnings: number | null; vdfTimeLowerBound: number | null; node : ArweaveNodeConfig; + ts: number; }