lotus/lotuspond/front/src/NodeList.js

154 lines
4.4 KiB
JavaScript
Raw Normal View History

2019-07-24 17:10:44 +00:00
import React from 'react';
import FullNode from "./FullNode";
2019-07-24 18:42:02 +00:00
import ConnMgr from "./ConnMgr";
2019-07-25 16:13:46 +00:00
import Consensus from "./Consensus";
2019-07-30 23:39:30 +00:00
import {Cristal} from "react-cristal";
import StorageNode from "./StorageNode";
2019-08-09 15:59:12 +00:00
import {Client} from "rpc-websockets";
import pushMessage from "./chain/send";
2019-07-24 17:10:44 +00:00
class NodeList extends React.Component {
constructor(props) {
2019-07-24 18:42:02 +00:00
super(props)
2019-07-24 17:10:44 +00:00
this.state = {
existingLoaded: false,
2019-07-24 20:00:11 +00:00
nodes: {},
2019-07-24 18:42:02 +00:00
showConnMgr: false,
2019-07-25 16:13:46 +00:00
showConsensus: false,
2019-07-24 18:42:02 +00:00
}
2019-07-24 17:10:44 +00:00
// This binding is necessary to make `this` work in the callback
2019-07-24 18:42:02 +00:00
this.spawnNode = this.spawnNode.bind(this)
this.connMgr = this.connMgr.bind(this)
2019-07-25 16:13:46 +00:00
this.consensus = this.consensus.bind(this)
2019-08-09 15:59:12 +00:00
this.transfer1kFrom1 = this.transfer1kFrom1.bind(this)
2019-07-24 17:10:44 +00:00
2019-07-24 20:00:11 +00:00
this.getNodes()
}
2019-08-09 15:59:12 +00:00
async mountNode(node) {
const token = await this.props.client.call('Pond.TokenFor', [node.ID])
const client = new Client(`ws://127.0.0.1:${node.ApiPort}/rpc/v0?token=${token}`)
client.on('open', async () => {
const id = await client.call("Filecoin.ID", [])
this.setState(prev => ({
nodes: {
...prev.nodes,
[node.ID]: {...node, conn: client, peerid: id}
}
}))
if (!node.Storage) {
this.props.mountWindow((onClose) =>
<FullNode key={node.ID}
node={{...node}}
client={client}
pondClient={this.props.client}
give1k={this.transfer1kFrom1}
mountWindow={this.props.mountWindow}/>)
} else {
this.props.mountWindow((onClose) =>
<StorageNode node={{...node}}
pondClient={this.props.client}
mountWindow={this.props.mountWindow}/>)
}
})
2019-07-30 23:39:30 +00:00
}
2019-07-24 20:00:11 +00:00
async getNodes() {
const nds = await this.props.client.call('Pond.Nodes')
const nodes = nds.reduce((o, i) => {o[i.ID] = i; return o}, {})
console.log('nds', nodes)
2019-07-30 23:39:30 +00:00
Object.keys(nodes).map(n => nodes[n]).forEach(n => this.mountNode(n))
2019-07-24 20:00:11 +00:00
this.setState({existingLoaded: true, nodes: nodes})
2019-07-24 17:10:44 +00:00
}
2019-08-09 15:59:12 +00:00
async transfer1kFrom1(to) {
const addrss = await this.state.nodes[1].conn.call('Filecoin.WalletList', [])
const [bestaddr, bal] = await addrss.map(async addr => {
let balance = 0
try {
balance = await this.state.nodes[1].conn.call('Filecoin.WalletBalance', [addr])
} catch {
balance = -1
}
return [addr, balance]
}).reduce(async (c, n) => (await c)[1] > (await n)[1] ? await c : await n, Promise.resolve(['', -2]))
pushMessage(this.state.nodes[1].conn, bestaddr, {
To: to,
From: bestaddr,
Value: "1000",
})
}
2019-07-24 17:10:44 +00:00
async spawnNode() {
const node = await this.props.client.call('Pond.Spawn')
console.log(node)
2019-08-09 15:59:12 +00:00
await this.mountNode(node)
2019-07-30 23:25:31 +00:00
2019-07-24 20:00:11 +00:00
this.setState(state => ({nodes: {...state.nodes, [node.ID]: node}}))
2019-07-24 17:10:44 +00:00
}
2019-07-24 18:42:02 +00:00
connMgr() {
this.setState({showConnMgr: true})
}
2019-07-25 16:13:46 +00:00
consensus() {
this.setState({showConsensus: true})
}
2019-07-24 17:10:44 +00:00
render() {
2019-07-24 18:42:02 +00:00
let connMgr
if (this.state.showConnMgr) {
connMgr = (<ConnMgr nodes={this.state.nodes}/>)
}
2019-07-25 16:13:46 +00:00
let consensus
if (this.state.showConsensus) {
consensus = (<Consensus nodes={this.state.nodes} mountWindow={this.props.mountWindow}/>)
2019-07-25 16:13:46 +00:00
}
2019-07-24 17:10:44 +00:00
return (
2019-07-30 23:39:30 +00:00
<Cristal title={"Node List"} initialPosition="bottom-left">
2019-07-30 23:53:24 +00:00
<div className={'NodeList'}>
<div>
<button onClick={this.spawnNode} disabled={!this.state.existingLoaded}>Spawn Node</button>
<button onClick={this.connMgr} disabled={!this.state.existingLoaded && !this.state.showConnMgr}>Connections</button>
<button onClick={this.consensus} disabled={!this.state.existingLoaded && !this.state.showConsensus}>Consensus</button>
</div>
<div>
{Object.keys(this.state.nodes).map(n => {
const nd = this.state.nodes[n]
let type = "FULL"
if (nd.Storage) {
type = "STOR"
}
let info = "[CONNECTING..]"
if (nd.conn) {
info = <span>{nd.peerid}</span>
}
return <div key={n}>
{n} {type} {info}
</div>
})}
</div>
2019-07-30 23:39:30 +00:00
</div>
2019-07-24 17:10:44 +00:00
<div>
2019-07-24 18:42:02 +00:00
{connMgr}
2019-07-25 16:13:46 +00:00
{consensus}
2019-07-24 17:10:44 +00:00
</div>
2019-07-30 23:39:30 +00:00
</Cristal>
2019-07-24 17:10:44 +00:00
);
}
}
export default NodeList