diff --git a/lotuspond/front/src/App.css b/lotuspond/front/src/App.css index abf335cd7..7bc75558a 100644 --- a/lotuspond/front/src/App.css +++ b/lotuspond/front/src/App.css @@ -16,4 +16,8 @@ min-width: 100%; height: 100%; overflow: auto; +} + +.Consensus { + font-family: monospace; } \ No newline at end of file diff --git a/lotuspond/front/src/Consensus.js b/lotuspond/front/src/Consensus.js new file mode 100644 index 000000000..08a935d2f --- /dev/null +++ b/lotuspond/front/src/Consensus.js @@ -0,0 +1,68 @@ +import React from 'react'; +import {Cristal} from "react-cristal"; + +function styleForHDiff(max, act) { + switch (max - act) { + case 0: + return {background: '#00aa00'} + case 1: + return {background: '#aaaa00'} + default: + return {background: '#aa0000'} + } +} + +class Consensus extends React.Component { + constructor(props) { + super(props) + + this.state = { + maxH: -1, + tipsets: [] + } + + this.updateNodes = this.updateNodes.bind(this) + + setInterval(this.updateNodes, 333) + } + + async updateNodes() { + const nodes = this.props.nodes + let keys = Object.keys(nodes) + + const tipsets = await keys.map(async k => { + const tipset = await nodes[k].conn.call("Filecoin.ChainHead", []) + return [k, tipset] + }).reduce(async(p, i) => ([...await p, await i]), Promise.resolve([])) + + const maxH = tipsets.reduce((p, [_, i]) => Math.max(p, i.Height), -1) + + this.setState({maxH, tipsets}) + } + + render() { + return ( +
+
Max Height: {this.state.maxH}
+
+ + + + + + {this.state.tipsets.map(([k, ts]) => { + return ( + + + + ) + })} + +
NodeHeightTipSet
{k}{ts.Height}{ts.Cids.map(c => {c['/'].substr(-8)})}
+
+
+
) + } +} + +export default Consensus \ No newline at end of file diff --git a/lotuspond/front/src/FullNode.js b/lotuspond/front/src/FullNode.js index 3ace226b3..37115669e 100644 --- a/lotuspond/front/src/FullNode.js +++ b/lotuspond/front/src/FullNode.js @@ -107,13 +107,17 @@ class FullNode extends React.Component { let chainInfo =
if (this.state.tipset !== undefined) { chainInfo = ( -
Head: {this.state.tipset.Cids.map(c => c['/'].substr(-8))} H:{this.state.tipset.Height}
+
+ Head: { + this.state.tipset.Cids.map(c => {c['/'].substr(-8)}) + } H:{this.state.tipset.Height} +
) } - let mine = Mine + let mine = [Mine] if (this.state.mining) { - mine = "Mining" + mine = "[Mining]" } let balances = this.state.balances.map(([addr, balance]) => { @@ -126,7 +130,7 @@ class FullNode extends React.Component { runtime = (
-
v{this.state.version.Version}, {this.state.id.substr(-8)}, {this.state.peers} peers
+
v{this.state.version.Version}, {this.state.id.substr(-8)}, {this.state.peers} peers
Repo: LOTUS_PATH={this.props.node.Repo}
{chainInfo} {mine} diff --git a/lotuspond/front/src/NodeList.js b/lotuspond/front/src/NodeList.js index 95d2a1606..c6066443e 100644 --- a/lotuspond/front/src/NodeList.js +++ b/lotuspond/front/src/NodeList.js @@ -1,6 +1,7 @@ import React from 'react'; import FullNode from "./FullNode"; import ConnMgr from "./ConnMgr"; +import Consensus from "./Consensus"; class NodeList extends React.Component { constructor(props) { @@ -10,11 +11,13 @@ class NodeList extends React.Component { nodes: {}, showConnMgr: false, + showConsensus: false, } // This binding is necessary to make `this` work in the callback this.spawnNode = this.spawnNode.bind(this) this.connMgr = this.connMgr.bind(this) + this.consensus = this.consensus.bind(this) this.getNodes() } @@ -36,17 +39,27 @@ class NodeList extends React.Component { this.setState({showConnMgr: true}) } + consensus() { + this.setState({showConsensus: true}) + } + render() { let connMgr if (this.state.showConnMgr) { connMgr = () } + let consensus + if (this.state.showConsensus) { + consensus = () + } + return (
+
{ @@ -60,6 +73,7 @@ class NodeList extends React.Component { }) } {connMgr} + {consensus}
);