-
Notifications
You must be signed in to change notification settings - Fork 121
fix: add miner stats pagination by block range #232
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { Table, TableBody, TableCell, TableHead, TableRow, Typography, LinearProgress } from "@material-ui/core"; | ||
import { Table, TableBody, TableCell, TableHead, TableRow, Typography, LinearProgress, Tooltip } from "@material-ui/core"; | ||
import * as React from "react"; | ||
import Link from "@material-ui/core/Link"; | ||
import { hexToDate, hexToNumber, hexToString } from "@etclabscore/eserialize"; | ||
|
@@ -60,29 +60,41 @@ function BlockList({ blocks }: any) { | |
} | ||
|
||
// Calculate difference of block timestamp from that of parent. | ||
const timeDifferenceFromParent = (index === sortedBlocks.length-1) ? 0 : hexToNumber(b.timestamp) - hexToNumber(sortedBlocks[index+1].timestamp); | ||
const timeDifferenceFromParent = (index === sortedBlocks.length - 1) ? 0 : hexToNumber(b.timestamp) - hexToNumber(sortedBlocks[index + 1].timestamp); | ||
|
||
return ( | ||
<TableRow key={b.number} style={authorHashStyle}> | ||
<TableCell style={rightPaddingFix}> | ||
<Typography> | ||
<Link | ||
<Typography> | ||
<Link | ||
component={({ className, children }: { children: any, className: string }) => ( | ||
<RouterLink className={className} to={`/address/${b.miner}`} > | ||
{children} | ||
</RouterLink> | ||
)}> | ||
{authorHashShort} | ||
</Link> | ||
<sup>{hexToString(b.extraData).substring(0, 20)}</sup> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eventually we might want to refactor this address/+extradata format out to a configurable/standard, eg. substring length, abbreviations, sanitization, ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed. lets make a ticket for that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
</Typography> | ||
</TableCell> | ||
<TableCell component="th" scope="row"> | ||
<Link | ||
component={({ className, children }: { children: any, className: string }) => ( | ||
<RouterLink className={className} to={`/address/${b.miner}`} > | ||
<RouterLink className={className} to={`/block/${b.hash}`} > | ||
{children} | ||
</RouterLink> | ||
)}> | ||
{authorHashShort} | ||
{parseInt(b.number, 16)} | ||
</Link> | ||
<sup>{hexToString(b.extraData).substring(0,20)}</sup> | ||
</Typography> | ||
</TableCell> | ||
<TableCell component="th" scope="row"><Typography>{parseInt(b.number, 16)}</Typography></TableCell> | ||
<TableCell style={rightPaddingFix}> | ||
<Typography>{t("Timestamp Date", { date: hexToDate(b.timestamp) })} <sub>({+timeDifferenceFromParent > 0 ? `+${timeDifferenceFromParent}` : `-${timeDifferenceFromParent}`}s)</sub></Typography> | ||
<Typography>{t("Timestamp Date", { date: hexToDate(b.timestamp) })} <sub>({timeDifferenceFromParent > 0 ? `+${timeDifferenceFromParent}` : `-${timeDifferenceFromParent}`}s)</sub></Typography> | ||
</TableCell> | ||
<TableCell style={rightPaddingFix}> | ||
<Typography><sub>{txTypes.transact}</sub><sup>{txTypes.create === 0 ? "" : txTypes.create}</sup></Typography> | ||
<Tooltip title={t("Create Transactions", {count: txTypes.create})} placement="top"> | ||
<Typography variant="caption" color="textSecondary">{txTypes.create === 0 ? "" : txTypes.create}</Typography> | ||
</Tooltip> | ||
<Typography>{txTypes.transact}</Typography> | ||
</TableCell> | ||
<TableCell style={rightPaddingFix}> | ||
<LinearProgress value={filledPercent} variant="determinate" /> | ||
|
@@ -91,7 +103,7 @@ function BlockList({ blocks }: any) { | |
<Typography>{hexToNumber(b.gasLimit)}</Typography> | ||
</TableCell> | ||
<TableCell> | ||
<Typography>{b.uncles.length === 0 ? '' : b.uncles.length}</Typography> | ||
<Typography>{b.uncles.length === 0 ? "" : b.uncles.length}</Typography> | ||
</TableCell> | ||
<TableCell style={rightPaddingFix}> | ||
<Link | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
import React from "react"; | ||
import { Grid, IconButton, Typography } from "@material-ui/core"; | ||
import { ArrowForwardIos, ArrowBackIos } from "@material-ui/icons"; | ||
|
||
interface IProps { | ||
from: number; | ||
to: number; | ||
disableNext?: boolean; | ||
disablePrev?: boolean; | ||
onNext?: () => void; | ||
onPrev?: () => void; | ||
style?: any; | ||
} | ||
|
||
const BlockPagination: React.FC<IProps> = (props) => { | ||
|
||
return ( | ||
<Grid container> | ||
<Grid container justify="flex-end"> | ||
<IconButton onClick={props.onPrev} disabled={props.disablePrev}> | ||
<ArrowBackIos /> | ||
</IconButton> | ||
<IconButton onClick={props.onNext} disabled={props.disableNext}> | ||
<ArrowForwardIos /> | ||
</IconButton> | ||
</Grid> | ||
<Grid container justify="flex-end"> | ||
<Typography>Showing {(props.to - props.from) + 1} Block Range: <b>{props.to}</b> - {props.from}</Typography> | ||
</Grid> | ||
</Grid> | ||
); | ||
}; | ||
|
||
export default BlockPagination; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import BlockPagination from "./BlockPagination"; | ||
export default BlockPagination; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import React from "react"; | ||
import BigNumber from "bignumber.js"; | ||
import { hashesToGH } from "../formatters"; | ||
import { hexToNumber } from "@etclabscore/eserialize"; | ||
import { Grid } from "@material-ui/core"; | ||
import ChartCard from "../ChartCard"; | ||
import { VictoryLine, VictoryBar, VictoryChart } from "victory"; | ||
import { useTranslation } from "react-i18next"; | ||
|
||
const config = { | ||
blockTime: 15, // seconds | ||
blockHistoryLength: 100, | ||
chartHeight: 200, | ||
chartWidth: 400, | ||
}; | ||
|
||
const blockMapGasUsed = (block: any) => { | ||
return { | ||
x: hexToNumber(block.number), | ||
y: new BigNumber(block.gasUsed).dividedBy(1000000), | ||
}; | ||
}; | ||
|
||
const blockMapUncles = (block: any) => { | ||
return { | ||
x: hexToNumber(block.number), | ||
y: block.uncles.length, | ||
}; | ||
}; | ||
|
||
const blockMapHashRate = (block: any) => { | ||
return { | ||
x: hexToNumber(block.number), | ||
y: hashesToGH(new BigNumber(block.difficulty, 16).dividedBy(config.blockTime)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmmm.. Using a hardcoded block time is a liiiitleee stretchy? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea would be nice to calculate the block time for the list of blocks you are looking at. maybe a helper |
||
}; | ||
}; | ||
|
||
const blockMapTransactionCount = (block: any) => { | ||
return { | ||
x: hexToNumber(block.number), | ||
y: block.transactions.length, | ||
}; | ||
}; | ||
|
||
interface IProps { | ||
blocks: any[]; | ||
victoryTheme?: any; | ||
} | ||
|
||
const StatCharts: React.FC<IProps> = ({ blocks, victoryTheme }) => { | ||
const { t } = useTranslation(); | ||
return ( | ||
<Grid item container> | ||
<Grid key="hashChart" item xs={12} md={6} lg={3}> | ||
<ChartCard title={t("Hash Rate")}> | ||
<VictoryChart height={config.chartHeight} width={config.chartWidth} theme={victoryTheme as any}> | ||
<VictoryLine data={blocks.map(blockMapHashRate)} /> | ||
</VictoryChart> | ||
</ChartCard> | ||
</Grid> | ||
<Grid key="txChart" item xs={12} md={6} lg={3}> | ||
<ChartCard title={t("Transaction count")}> | ||
<VictoryChart height={config.chartHeight} width={config.chartWidth} theme={victoryTheme as any}> | ||
<VictoryBar data={blocks.map(blockMapTransactionCount)} /> | ||
</VictoryChart> | ||
</ChartCard> | ||
</Grid> | ||
<Grid key="gasUsed" item xs={12} md={6} lg={3}> | ||
<ChartCard title={t("Gas Used")}> | ||
<VictoryChart height={config.chartHeight} width={config.chartWidth} theme={victoryTheme as any}> | ||
<VictoryBar data={blocks.map(blockMapGasUsed)} /> | ||
</VictoryChart> | ||
</ChartCard> | ||
</Grid> | ||
<Grid key="uncles" item xs={12} md={6} lg={3}> | ||
<ChartCard title={t("Uncles")}> | ||
<VictoryChart height={config.chartHeight} width={config.chartWidth} theme={victoryTheme as any}> | ||
<VictoryBar data={blocks.map(blockMapUncles)} /> | ||
</VictoryChart> | ||
</ChartCard> | ||
</Grid> | ||
</Grid> | ||
); | ||
}; | ||
|
||
export default StatCharts; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import StatCharts from "./StatCharts"; | ||
export default StatCharts; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this work if there are other parameters in the search pattern of the URI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it does for certain keys, see here: https://github.com/etclabscore/expedition/blob/master/src/App.tsx#L38
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha, thanks. Maybe the supported params should be parts of a config object and standardized/globalized then too, toward fewer magic strings.
Would suggest new ticket for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... Or modify the handrolled
History
logic to use either a library (there must be one...?) and/or/thereby support arbitrary URI path/parameter/hash updates. So that this feature itself becomes some background "just works" magic.