diff --git a/src/v2/components/TourDeSol/Table/index.jsx b/src/v2/components/TourDeSol/Table/index.jsx index acecf8aa..5fc0ba10 100644 --- a/src/v2/components/TourDeSol/Table/index.jsx +++ b/src/v2/components/TourDeSol/Table/index.jsx @@ -17,19 +17,19 @@ import {observer} from 'mobx-react-lite'; import {Link} from 'react-router-dom'; import {map} from 'lodash/fp'; import NodesStore from 'v2/stores/nodes'; -import HelpLink from '../../HelpLink'; +import getUptime from 'v2/utils/getUptime'; +import HelpLink from '../../HelpLink'; import useStyles from './styles'; const ValidatorsTable = ({separate}: {separate: boolean}) => { const classes = useStyles(); const theme = useTheme(); const showTable = useMediaQuery(theme.breakpoints.up('md')); - const { - cluster: {voting = []}, - } = NodesStore; + const {validators} = NodesStore; const renderRow = row => { + const uptime = getUptime(row); return ( 1 @@ -43,11 +43,12 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { {row.stake} - TODO + {uptime}% ); }; const renderCard = card => { + const uptime = getUptime(card); return (
{
Uptime
-
TODO
+
{uptime}%
@@ -77,7 +78,7 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { Active Validators - {voting.length} + {validators.length} {!separate && ( See all > @@ -99,12 +100,12 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { root: classes.body, }} > - {map(renderRow)(voting)} + {map(renderRow)(validators)} ) : (
- {map(renderCard)(voting)} + {map(renderCard)(validators)}
)} diff --git a/src/v2/components/Validators/Table/index.jsx b/src/v2/components/Validators/Table/index.jsx index 408a49b6..1cba06d0 100644 --- a/src/v2/components/Validators/Table/index.jsx +++ b/src/v2/components/Validators/Table/index.jsx @@ -17,6 +17,7 @@ import {observer} from 'mobx-react-lite'; import {Link} from 'react-router-dom'; import {map} from 'lodash/fp'; import NodesStore from 'v2/stores/nodes'; +import getUptime from 'v2/utils/getUptime'; import useStyles from './styles'; @@ -24,10 +25,9 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { const classes = useStyles(); const theme = useTheme(); const showTable = useMediaQuery(theme.breakpoints.up('md')); - const { - cluster: {voting = []}, - } = NodesStore; + const {validators} = NodesStore; const renderRow = row => { + const uptime = getUptime(row); return ( @@ -41,10 +41,12 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { {row.stake} Lamports {row.commission} + {uptime}% ); }; const renderCard = card => { + const uptime = getUptime(card); return (
{
{card.nodePubkey}
- +
Stake
{card.stake} Lamports
@@ -63,6 +65,10 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => {
Commission
{card.commission}
+ +
Uptime
+
{uptime}%
+
); @@ -71,7 +77,7 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => {
Validators - {voting.length} + {validators.length} {!separate && ( See all > @@ -85,6 +91,7 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { Name/Moniker Stake Commission + Uptime { root: classes.body, }} > - {map(renderRow)(voting)} + {map(renderRow)(validators)} ) : (
- {map(renderCard)(voting)} + {map(renderCard)(validators)}
)}
diff --git a/src/v2/components/Validators/index.jsx b/src/v2/components/Validators/index.jsx index daa3c18c..8aa96bd5 100644 --- a/src/v2/components/Validators/index.jsx +++ b/src/v2/components/Validators/index.jsx @@ -14,7 +14,7 @@ import useStyles from './styles'; const Validators = () => { const classes = useStyles(); - const {cluster, fetchClusterInfo, totalBondedTokens} = NodesStore; + const {cluster, validators, fetchClusterInfo, totalBondedTokens} = NodesStore; useEffect(() => { fetchClusterInfo(); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -34,7 +34,7 @@ const Validators = () => { }, { title: '# Active Validators', - value: cluster.nodes.length, + value: validators.length, changes: '', period: 'since yesterday', }, diff --git a/src/v2/stores/nodes.js b/src/v2/stores/nodes.js index a92039fb..b188fa96 100644 --- a/src/v2/stores/nodes.js +++ b/src/v2/stores/nodes.js @@ -8,6 +8,7 @@ import { mapValues, pick, merge, + find, } from 'lodash/fp'; import {action, computed, decorate, observable, observe, flow} from 'mobx'; import {parseClusterInfo} from 'v2/utils/parseMessage'; @@ -17,6 +18,7 @@ import calcChanges from 'v2/utils/calcChanges'; class Store { cluster = { nodes: [], + voting: [], }; clusterChanges = {}; @@ -54,6 +56,13 @@ class Store { }))(this.cluster.nodes); } + get validators() { + return map(vote => ({ + ...vote, + uptime: find({votePubkey: vote.votePubkey})(this.cluster.uptime), + }))(this.cluster.voting); + } + get totalBondedTokens() { return compose( sumBy('stake'), diff --git a/src/v2/utils/getUptime.js b/src/v2/utils/getUptime.js new file mode 100644 index 00000000..b7aa51a4 --- /dev/null +++ b/src/v2/utils/getUptime.js @@ -0,0 +1,7 @@ +import {compose, getOr, multiply} from 'lodash/fp'; + +export default compose( + time => time.toFixed(time ? 4 : 2), + multiply(100), + getOr(0, 'uptime.uptime.[0].percentage'), +);