Skip to content

Commit b550c7c

Browse files
committed
fix logic
1 parent fd43339 commit b550c7c

File tree

1 file changed

+122
-88
lines changed

1 file changed

+122
-88
lines changed

src/App.tsx

Lines changed: 122 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,44 @@ import { PROOF_SIZE_MB, MB_TO_GAS, GAS_TO_MGAS } from './constants';
1818

1919
const ALPHA = 0.3;
2020
const TARGET_WINDOW_SIZE = 30000; // 30s
21-
const MAX_BLOCKS_STORE = 2000;
21+
const MAX_BLOCKS_STORE = 1000;
22+
23+
type RelayType = 'Polkadot' | 'Kusama';
24+
25+
interface BlockRecord {
26+
chainKey: string;
27+
blockNumber: number;
28+
timestamp: number;
29+
extrinsics: number;
30+
proofSize: number;
31+
}
2232

23-
// standard ema
2433
function calculateEma(oldValue: number, newValue: number) {
2534
return ALPHA * newValue + (1 - ALPHA) * oldValue;
2635
}
2736

28-
// compute rolling tps, mbs, gas from blocks in the last 30s
29-
function calculateRollingMetrics(
30-
blocks: Array<{ blockNumber: number; timestamp: number; extrinsics: number; proofSize: number }>
31-
) {
32-
if (blocks.length < 2) return { tps: 0, mbs: 0, gas: 0 };
37+
// compute rolling tps, mbs, gas from last 30s
38+
function calculateRollingMetrics(blocks: BlockRecord[]) {
39+
if (blocks.length < 2) {
40+
// console.log('debug: not enough blocks to calc rolling metrics -> returning 0');
41+
return { tps: 0, mbs: 0, gas: 0 };
42+
}
3343

3444
const now = Date.now();
3545
const cutoff = now - TARGET_WINDOW_SIZE;
3646
const relevant = blocks.filter(b => b.timestamp >= cutoff);
37-
if (relevant.length === 0) return { tps: 0, mbs: 0, gas: 0 };
47+
if (relevant.length === 0) {
48+
// console.log('debug: no blocks in last 30s -> returning 0');
49+
return { tps: 0, mbs: 0, gas: 0 };
50+
}
3851

3952
relevant.sort((a, b) => a.timestamp - b.timestamp);
4053
const timeWindow = relevant[relevant.length - 1].timestamp - relevant[0].timestamp;
41-
if (timeWindow <= 0) return { tps: 0, mbs: 0, gas: 0 };
54+
if (timeWindow <= 0) {
55+
// console.log('debug: timeWindow <= 0, weird data -> returning 0');
56+
return { tps: 0, mbs: 0, gas: 0 };
57+
}
4258

43-
// adjust extrinsics with -2 offset if desired
4459
const sumExtrinsics = relevant.reduce((acc, b) => acc + Math.max(0, b.extrinsics - 2), 0);
4560
const sumProofSize = relevant.reduce((acc, b) => acc + b.proofSize, 0);
4661

@@ -51,70 +66,67 @@ function calculateRollingMetrics(
5166
return { tps, mbs, gas };
5267
}
5368

54-
interface BlockRecord {
55-
chainKey: string;
56-
blockNumber: number;
57-
timestamp: number;
58-
extrinsics: number;
59-
proofSize: number;
60-
}
61-
6269
const App: React.FC = () => {
63-
const [selectedRelay, setSelectedRelay] = useState<'Polkadot' | 'Kusama'>('Polkadot');
70+
// user picks polkadot or kusama
71+
const [selectedRelay, setSelectedRelay] = useState<RelayType>('Polkadot');
6472

65-
// data feed
6673
const consumptionData = useWeightConsumption('https://stream.freeside.network/events');
6774

68-
// figure out which chains we're interested in
75+
// separate chain arrays for polkadot vs. kusama
76+
// do the same for blockNumber dedupe
77+
const blocksByRelayRef = useRef<{ Polkadot: BlockRecord[]; Kusama: BlockRecord[] }>({
78+
Polkadot: [],
79+
Kusama: [],
80+
});
81+
82+
const lastBlockNumberByRelayRef = useRef<{
83+
Polkadot: Record<string, number>;
84+
Kusama: Record<string, number>;
85+
}>({
86+
Polkadot: {},
87+
Kusama: {},
88+
});
89+
90+
// rolling totals for whichever relay is selected
91+
//const [rollingTps, setRollingTps] = useState(0);
92+
const [rollingTpsEma, setRollingTpsEma] = useState(0);
93+
//const [rollingMbs, setRollingMbs] = useState(0);
94+
const [rollingMbsEma, setRollingMbsEma] = useState(0);
95+
//const [rollingGas, setRollingGas] = useState(0);
96+
const [rollingGasEma, setRollingGasEma] = useState(0);
97+
98+
// figure out chain lists
6999
const chainNames = selectedRelay === 'Polkadot' ? polkadotChainNames : kusamaChainNames;
70100
const paraIdToChainName =
71101
selectedRelay === 'Polkadot' ? polkadotParaIdToChainName : kusamaParaIdToChainName;
72102

73-
// gather the "weightData" for all chains (just the mandatory + total_proof_size, for example)
103+
// gather "weightData" for chain table
74104
const weightData: Record<PolkadotChainName | KusamaChainName, number> = chainNames.reduce(
75105
(acc, chain) => {
76-
const paraId = Object.keys(paraIdToChainName).find(
77-
(key) => paraIdToChainName[Number(key)] === chain
78-
);
106+
const paraId = Object.keys(paraIdToChainName).find(k => paraIdToChainName[Number(k)] === chain);
79107
if (paraId) {
80108
const key = `${selectedRelay}-${paraId}`;
81109
const chainData = consumptionData[key]?.current;
82110
if (chainData) {
83-
// example: combine mandatory + total_proof_size
84111
const mandatorySize = chainData.ref_time?.mandatory ?? 0;
85112
const totalSize = chainData.total_proof_size ?? 0;
86-
const combinedProof = mandatorySize + totalSize;
87-
return { ...acc, [chain]: combinedProof };
113+
const totalProof = mandatorySize + totalSize;
114+
acc[chain] = totalProof;
88115
}
89116
}
90117
return acc;
91118
},
92119
{} as Record<PolkadotChainName | KusamaChainName, number>
93120
);
94121

95-
// store rolling metrics
96-
//const [rollingTps, setRollingTps] = useState(0);
97-
const [rollingTpsEma, setRollingTpsEma] = useState(0);
98-
99-
//const [rollingMbs, setRollingMbs] = useState(0);
100-
const [rollingMbsEma, setRollingMbsEma] = useState(0);
101-
102-
//const [rollingGas, setRollingGas] = useState(0);
103-
const [rollingGasEma, setRollingGasEma] = useState(0);
104-
105-
// dedup blocks
106-
const blocksRef = useRef<BlockRecord[]>([]);
107-
const lastBlockNumberByChain = useRef<Record<string, number>>({});
108-
109-
// we also want the immediate (non-ema) relay data
122+
// immediate (non-ema) relay stats for whichever relay is selected
110123
let weightRelay = 0;
111124
let tpsRelay = 0;
112125
let gasRelay = 0;
113126

114-
// figure out the relay chain's data
115127
const relayChainName = selectedRelay === 'Polkadot' ? 'Polkadot' : 'Kusama';
116128
const relayParaId = Object.keys(paraIdToChainName).find(
117-
(k) => paraIdToChainName[Number(k)] === relayChainName
129+
k => paraIdToChainName[Number(k)] === relayChainName
118130
);
119131
if (relayParaId) {
120132
const relayKey = `${selectedRelay}-${relayParaId}`;
@@ -125,67 +137,96 @@ const App: React.FC = () => {
125137
const totalSize = relayData.total_proof_size ?? 0;
126138
weightRelay = mandatorySize + totalSize;
127139
tpsRelay = (relayData.extrinsics_num ?? 0) / blockTime;
128-
129140
const chainMbs = (weightRelay * PROOF_SIZE_MB) / blockTime;
130141
gasRelay = chainMbs * (MB_TO_GAS / PROOF_SIZE_MB / GAS_TO_MGAS);
131142
}
132143
}
133144

134145
useEffect(() => {
135-
const newBlocks: BlockRecord[] = [];
146+
// console.log('debug: consumptionData or selectedRelay changed -> updating polkadot + kusama blocks');
136147

137-
chainNames.forEach((chain) => {
138-
const paraId = Object.keys(paraIdToChainName).find(
139-
(key) => paraIdToChainName[Number(key)] === chain
148+
// step 1: process polkadot chain data
149+
polkadotChainNames.forEach(chain => {
150+
const paraId = Object.keys(polkadotParaIdToChainName).find(
151+
k => polkadotParaIdToChainName[Number(k)] === chain
140152
);
141153
if (!paraId) return;
142-
const key = `${selectedRelay}-${paraId}`;
154+
const key = `Polkadot-${paraId}`;
143155
const chainData = consumptionData[key]?.current;
144156
if (!chainData) return;
145157

146158
const blockNum = chainData.block_number;
147159
const ts = chainData.timestamp;
148-
// only add if we haven't seen this block_number before for this chain
149-
if (
150-
typeof blockNum === 'number' &&
151-
ts &&
152-
(lastBlockNumberByChain.current[key] === undefined ||
153-
blockNum > lastBlockNumberByChain.current[key])
154-
) {
155-
lastBlockNumberByChain.current[key] = blockNum;
156-
157-
// combine mandatory + total_proof_size
160+
const lastSeen = lastBlockNumberByRelayRef.current['Polkadot'][key];
161+
162+
if (typeof blockNum === 'number' && ts && (lastSeen === undefined || blockNum > lastSeen)) {
163+
lastBlockNumberByRelayRef.current['Polkadot'][key] = blockNum;
158164
const mandatorySize = chainData.ref_time?.mandatory ?? 0;
159165
const totalSize = chainData.total_proof_size ?? 0;
160166
const totalProof = mandatorySize + totalSize;
161167

162-
newBlocks.push({
163-
chainKey: key,
164-
blockNumber: blockNum,
165-
timestamp: ts,
166-
extrinsics: chainData.extrinsics_num ?? 0,
167-
proofSize: totalProof,
168-
});
168+
blocksByRelayRef.current['Polkadot'] = [
169+
...blocksByRelayRef.current['Polkadot'],
170+
{
171+
chainKey: key,
172+
blockNumber: blockNum,
173+
timestamp: ts,
174+
extrinsics: chainData.extrinsics_num ?? 0,
175+
proofSize: totalProof,
176+
},
177+
].slice(-MAX_BLOCKS_STORE);
178+
169179
}
170180
});
171181

172-
// if we actually have new blocks, compute rolling metrics
173-
if (newBlocks.length > 0) {
174-
// add them, prune old
175-
blocksRef.current = [...blocksRef.current, ...newBlocks].slice(-MAX_BLOCKS_STORE);
182+
// step 2: process kusama chain data
183+
kusamaChainNames.forEach(chain => {
184+
const paraId = Object.keys(kusamaParaIdToChainName).find(
185+
k => kusamaParaIdToChainName[Number(k)] === chain
186+
);
187+
if (!paraId) return;
188+
const key = `Kusama-${paraId}`;
189+
const chainData = consumptionData[key]?.current;
190+
if (!chainData) return;
191+
192+
const blockNum = chainData.block_number;
193+
const ts = chainData.timestamp;
194+
const lastSeen = lastBlockNumberByRelayRef.current['Kusama'][key];
195+
196+
if (typeof blockNum === 'number' && ts && (lastSeen === undefined || blockNum > lastSeen)) {
197+
lastBlockNumberByRelayRef.current['Kusama'][key] = blockNum;
198+
const mandatorySize = chainData.ref_time?.mandatory ?? 0;
199+
const totalSize = chainData.total_proof_size ?? 0;
200+
const totalProof = mandatorySize + totalSize;
201+
202+
blocksByRelayRef.current['Kusama'] = [
203+
...blocksByRelayRef.current['Kusama'],
204+
{
205+
chainKey: key,
206+
blockNumber: blockNum,
207+
timestamp: ts,
208+
extrinsics: chainData.extrinsics_num ?? 0,
209+
proofSize: totalProof,
210+
},
211+
].slice(-MAX_BLOCKS_STORE);
176212

177-
const { tps, mbs, gas } = calculateRollingMetrics(blocksRef.current);
213+
}
214+
});
178215

179-
//setRollingTps(tps);
180-
setRollingTpsEma((prev) => calculateEma(prev || tps, tps));
216+
// step 3: compute rolling metrics for whichever relay is selected
217+
const blocks = blocksByRelayRef.current[selectedRelay] || [];
218+
// console.log(`debug: computing rolling metrics for ${selectedRelay}, block array length = ${blocks.length}`);
181219

182-
//setRollingMbs(mbs);
183-
setRollingMbsEma((prev) => calculateEma(prev || mbs, mbs));
220+
const { tps, mbs, gas } = calculateRollingMetrics(blocks);
221+
// setRollingTps(tps);
222+
setRollingTpsEma(prev => calculateEma(prev || tps, tps));
223+
// setRollingMbs(mbs);
224+
setRollingMbsEma(prev => calculateEma(prev || mbs, mbs));
225+
// setRollingGas(gas);
226+
setRollingGasEma(prev => calculateEma(prev || gas, gas));
184227

185-
// setRollingGas(gas);
186-
setRollingGasEma((prev) => calculateEma(prev || gas, gas));
187-
}
188-
}, [consumptionData, chainNames, paraIdToChainName, selectedRelay]);
228+
// console.log('debug: set new rolling metrics ->', { tps, mbs, gas });
229+
}, [consumptionData, selectedRelay]);
189230

190231
return (
191232
<div className="app-container">
@@ -200,15 +241,9 @@ const App: React.FC = () => {
200241
<RelaySelector selectedRelay={selectedRelay} onRelayChange={setSelectedRelay} />
201242

202243
<MetricsTotal
203-
// the rolling 30s metrics
204-
// rollingTps={rollingTps.toFixed(2)}
205244
totalTps={rollingTpsEma.toFixed(2)}
206-
// rollingMbs={rollingMbs.toFixed(2)}
207245
totalMbs={rollingMbsEma.toFixed(2)}
208-
// rollingGas={rollingGas.toFixed(2)}
209246
totalGas={rollingGasEma.toFixed(2)}
210-
211-
// immediate relay chain-only stats (non-ema)
212247
tpsRelay={tpsRelay}
213248
weightRelay={weightRelay}
214249
gasRelay={gasRelay}
@@ -220,7 +255,6 @@ const App: React.FC = () => {
220255
chains={chainNames}
221256
selectedRelay={selectedRelay}
222257
paraIdToChainName={paraIdToChainName}
223-
// pass in weightData for chain usage
224258
weightData={weightData}
225259
/>
226260
</div>

0 commit comments

Comments
 (0)