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}
+
+
+
+ Node | Height | TipSet |
+
+
+ {this.state.tipsets.map(([k, ts]) => {
+ return (
+
+ {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}
);