pond: +1k button for addresses

This commit is contained in:
Łukasz Magiera 2019-08-09 17:59:12 +02:00
parent 5cda74fd15
commit f99c8e032d
11 changed files with 318 additions and 78 deletions

View File

@ -111,6 +111,7 @@ type FullNode interface {
WalletList(context.Context) ([]address.Address, error)
WalletBalance(context.Context, address.Address) (types.BigInt, error)
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
WalletDefaultAddress(context.Context) (address.Address, error)
// Other

View File

@ -55,13 +55,14 @@ type FullNodeStruct struct {
MinerStart func(context.Context, address.Address) error `perm:"admin"`
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error) `perm:"write"`
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
WalletSign func(context.Context, address.Address, []byte) (*types.Signature, error) `perm:"sign"`
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
WalletSign func(context.Context, address.Address, []byte) (*types.Signature, error) `perm:"sign"`
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
ClientImport func(ctx context.Context, path string) (cid.Cid, error) `perm:"write"`
ClientListImports func(ctx context.Context) ([]Import, error) `perm:"read"`
@ -190,6 +191,10 @@ func (c *FullNodeStruct) WalletSign(ctx context.Context, k address.Address, msg
return c.Internal.WalletSign(ctx, k, msg)
}
func (c *FullNodeStruct) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) {
return c.Internal.WalletSignMessage(ctx, k, msg)
}
func (c *FullNodeStruct) WalletDefaultAddress(ctx context.Context) (address.Address, error) {
return c.Internal.WalletDefaultAddress(ctx)
}

View File

@ -1,6 +1,7 @@
package chain
import (
"encoding/base64"
"sync"
"github.com/filecoin-project/go-lotus/chain/address"
@ -46,6 +47,8 @@ func NewMessagePool(cs *store.ChainStore) *MessagePool {
}
func (mp *MessagePool) Add(m *types.SignedMessage) error {
log.Info("MPOOLADD<<<<<<<<<<<<<<")
mp.lk.Lock()
defer mp.lk.Unlock()
@ -54,6 +57,8 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
return err
}
log.Info("mpooladd: %s", base64.StdEncoding.EncodeToString(data))
if err := m.Signature.Verify(m.Message.From, data); err != nil {
return err
}

View File

@ -15,7 +15,7 @@ import (
)
func main() {
logging.SetLogLevel("*", "INFO")
logging.SetLogLevel("*", "DEBUG")
local := []*cli.Command{
DaemonCmd,
}

View File

@ -2435,6 +2435,14 @@
}
}
},
"base-x": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz",
"integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"base64-js": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
@ -2458,11 +2466,21 @@
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
},
"bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
},
"binary-extensions": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw=="
},
"blakejs": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
"integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
},
"bluebird": {
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
@ -2533,6 +2551,18 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"borc": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/borc/-/borc-2.1.1.tgz",
"integrity": "sha512-vPLLC2/gS0QN4O3cnPh+8jLshkMMD4qIfs+B1TPGPh30WrtcfItaO6j4k9alsqu/hIgKi8dVdmMvTcbq4tIF7A==",
"requires": {
"bignumber.js": "^9.0.0",
"commander": "^2.15.0",
"ieee754": "^1.1.8",
"iso-url": "~0.4.4",
"json-text-sequence": "~0.1.0"
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -2669,6 +2699,14 @@
"node-releases": "^1.1.25"
}
},
"bs58": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
"requires": {
"base-x": "^3.0.2"
}
},
"bser": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz",
@ -3368,6 +3406,17 @@
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
},
"cids": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cids/-/cids-0.7.1.tgz",
"integrity": "sha512-qEM4j2GKE/BiT6WdUi6cfW8dairhSLTUE8tIdxJG6SvY33Mp/UPjw+xcO0n1zsllgo72BupzKF/44v+Bg8YPPg==",
"requires": {
"class-is": "^1.1.0",
"multibase": "~0.6.0",
"multicodec": "~0.5.1",
"multihashes": "~0.4.14"
}
},
"cipher-base": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
@ -3382,6 +3431,11 @@
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz",
"integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ=="
},
"class-is": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz",
"integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw=="
},
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@ -4223,6 +4277,11 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"delimit-stream": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz",
"integrity": "sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@ -4495,6 +4554,11 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
},
"err-code": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
},
"errno": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
@ -6265,6 +6329,18 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
},
"ipld-dag-cbor": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/ipld-dag-cbor/-/ipld-dag-cbor-0.15.0.tgz",
"integrity": "sha512-wc9nrDtV4Le76UUhG4LXX57NVi5d7JS2kLid2nOYZAcr0SFhiXZL2ZyV3bfmNohO50KvgPEessSaBBSm9bflGA==",
"requires": {
"borc": "^2.1.0",
"cids": "~0.7.0",
"is-circular": "^1.0.2",
"multicodec": "~0.5.0",
"multihashing-async": "~0.7.0"
}
},
"is-absolute-url": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
@ -6314,6 +6390,11 @@
"ci-info": "^2.0.0"
}
},
"is-circular": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-circular/-/is-circular-1.0.2.tgz",
"integrity": "sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA=="
},
"is-class": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/is-class/-/is-class-0.0.4.tgz",
@ -6511,6 +6592,11 @@
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"iso-url": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.6.tgz",
"integrity": "sha512-YQO7+aIe6l1aSJUKOx+Vrv08DlhZeLFIVfehG2L29KLSEb9RszqPXilxJRVpp57px36BddKR5ZsebacO5qG0tg=="
},
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@ -7642,6 +7728,11 @@
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
"integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g=="
},
"js-sha3": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -7780,6 +7871,14 @@
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"json-text-sequence": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz",
"integrity": "sha1-py8hfcSvxGKf/1/rME3BvVGi89I=",
"requires": {
"delimit-stream": "0.1.0"
}
},
"json3": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
@ -8397,6 +8496,14 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"multibase": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.0.tgz",
"integrity": "sha512-R9bNLQhbD7MsitPm1NeY7w9sDgu6d7cuj25snAWH7k5PSNPSwIQQBpcpj8jx1W96dLbdigZqmUWOdQRMnAmgjA==",
"requires": {
"base-x": "3.0.4"
}
},
"multicast-dns": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
@ -8411,6 +8518,52 @@
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
},
"multicodec": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.5.tgz",
"integrity": "sha512-1kOifvwAqp9IdiiTKmpK2tS+LY6GHZdKpk3S2EvW4T32vlwDyA3hJoZtGauzqdedUPVNGChnTksEotVOCVlC+Q==",
"requires": {
"varint": "^5.0.0"
}
},
"multihashes": {
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.15.tgz",
"integrity": "sha512-G/Smj1GWqw1RQP3dRuRRPe3oyLqvPqUaEDIaoi7JF7Loxl4WAWvhJNk84oyDEodSucv0MmSW/ZT0RKUrsIFD3g==",
"requires": {
"bs58": "^4.0.1",
"varint": "^5.0.0"
}
},
"multihashing-async": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-0.7.0.tgz",
"integrity": "sha512-SCbfl3f+DzJh+/5piukga9ofIOxwfT05t8R4jfzZIJ88YE9zU9+l3K2X+XB19MYyxqvyK9UJRNWbmQpZqQlbRA==",
"requires": {
"blakejs": "^1.1.0",
"buffer": "^5.2.1",
"err-code": "^1.1.2",
"js-sha3": "~0.8.0",
"multihashes": "~0.4.13",
"murmurhash3js-revisited": "^3.0.0"
},
"dependencies": {
"buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
"integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
}
}
},
"murmurhash3js-revisited": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz",
"integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g=="
},
"mute-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
@ -12325,6 +12478,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
"varint": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz",
"integrity": "sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",

View File

@ -3,6 +3,8 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"borc": "^2.1.1",
"ipld-dag-cbor": "^0.15.0",
"jsonrpc-websocket-client": "^0.5.0",
"react": "^16.8.6",
"react-cristal": "^0.0.12",

View File

@ -26,7 +26,7 @@ class ConnMgr extends React.Component {
let keys = Object.keys(nodes)
const newConns = await keys.filter((_, i) => i > 0).map(async (kfrom, i) => {
return await keys.filter((_, j) => i >= j).map(async kto => {
return keys.filter((_, j) => i >= j).map(async kto => {
const fromNd = this.props.nodes[kfrom]
const toNd = this.props.nodes[kto]

View File

@ -4,10 +4,6 @@ import Cristal from 'react-cristal'
import { BlockLinks } from "./BlockLink";
import StorageNodeInit from "./StorageNodeInit";
const stateConnected = 'connected'
const stateConnecting = 'connecting'
const stateGettingToken = 'getting-token'
async function awaitListReducer(prev, c) {
return [...await prev, await c]
}
@ -24,7 +20,6 @@ class FullNode extends React.Component {
super(props)
this.state = {
state: stateGettingToken,
id: "~",
mining: false,
@ -34,62 +29,35 @@ class FullNode extends React.Component {
this.startMining = this.startMining.bind(this)
this.newScepAddr = this.newScepAddr.bind(this)
this.startStorageMiner = this.startStorageMiner.bind(this)
this.add1k = this.add1k.bind(this)
this.connect()
}
async connect() {
const token = await this.props.pondClient.call('Pond.TokenFor', [this.props.node.ID])
this.setState(() => ({
state: stateConnecting,
token: token,
}))
const client = new Client(`ws://127.0.0.1:${this.props.node.ApiPort}/rpc/v0?token=${token}`)
client.on('open', async () => {
this.setState(() => ({
state: stateConnected,
client: client,
version: {Version: "~version~"},
id: "~peerid~",
peers: -1,
balances: []
}))
const id = await this.state.client.call("Filecoin.ID", [])
this.setState(() => ({id: id}))
this.props.onConnect(client, id)
this.loadInfo()
setInterval(this.loadInfo, 2050)
})
console.log(token) // todo: use
this.loadInfo()
setInterval(this.loadInfo, 2050)
}
async loadInfo() {
const version = await this.state.client.call("Filecoin.Version", [])
const id = await this.props.client.call("Filecoin.ID", [])
this.setState(() => ({id: id}))
const version = await this.props.client.call("Filecoin.Version", [])
this.setState(() => ({version: version}))
const peers = await this.state.client.call("Filecoin.NetPeers", [])
const peers = await this.props.client.call("Filecoin.NetPeers", [])
this.setState(() => ({peers: peers.length}))
const tipset = await this.state.client.call("Filecoin.ChainHead", [])
const tipset = await this.props.client.call("Filecoin.ChainHead", [])
this.setState(() => ({tipset: tipset}))
const addrss = await this.state.client.call('Filecoin.WalletList', [])
const addrss = await this.props.client.call('Filecoin.WalletList', [])
let defaultAddr = ""
if (addrss.length > 0) {
defaultAddr = await this.state.client.call('Filecoin.WalletDefaultAddress', [])
defaultAddr = await this.props.client.call('Filecoin.WalletDefaultAddress', [])
}
const balances = await addrss.map(async addr => {
let balance = 0
try {
balance = await this.state.client.call('Filecoin.WalletBalance', [addr])
balance = await this.props.client.call('Filecoin.WalletBalance', [addr])
} catch {
balance = -1
}
@ -109,22 +77,26 @@ class FullNode extends React.Component {
}
this.setState({mining: true})
await this.state.client.call("Filecoin.MinerStart", [addr])
await this.props.client.call("Filecoin.MinerStart", [addr])
}
async newScepAddr() {
const t = "secp256k1"
await this.state.client.call("Filecoin.WalletNew", [t])
await this.props.client.call("Filecoin.WalletNew", [t])
this.loadInfo()
}
async startStorageMiner() {
this.props.mountWindow((onClose) => <StorageNodeInit fullRepo={this.props.node.Repo} fullConn={this.props.conn} pondClient={this.props.pondClient} onClose={onClose} mountWindow={this.props.mountWindow}/>)
this.props.mountWindow((onClose) => <StorageNodeInit fullRepo={this.props.node.Repo} fullConn={this.props.client} pondClient={this.props.pondClient} onClose={onClose} mountWindow={this.props.mountWindow}/>)
}
async add1k(to) {
await this.props.give1k(to)
}
render() {
let runtime = <div></div>
if (this.state.state === stateConnected) {
if (this.state.defaultAddr) {
let chainInfo = <div></div>
if (this.state.tipset !== undefined) {
chainInfo = (
@ -144,7 +116,9 @@ class FullNode extends React.Component {
let storageMine = <a href="#" onClick={this.startStorageMiner}>[Spawn Storage Miner]</a>
let balances = this.state.balances.map(([addr, balance]) => {
let line = <span>{truncAddr(addr)}:&nbsp;{balance}&nbsp;(ActTyp)</span>
let add1k = <a href="#" onClick={() => this.add1k(addr)}>[+1k]</a>
let line = <span>{truncAddr(addr)}:&nbsp;{balance}&nbsp;(ActTyp) {add1k}</span>
if (this.state.defaultAddr === addr) {
line = <b>{line}</b>
}

View File

@ -4,6 +4,8 @@ import ConnMgr from "./ConnMgr";
import Consensus from "./Consensus";
import {Cristal} from "react-cristal";
import StorageNode from "./StorageNode";
import {Client} from "rpc-websockets";
import pushMessage from "./chain/send";
class NodeList extends React.Component {
constructor(props) {
@ -20,29 +22,40 @@ class NodeList extends React.Component {
this.spawnNode = this.spawnNode.bind(this)
this.connMgr = this.connMgr.bind(this)
this.consensus = this.consensus.bind(this)
this.transfer1kFrom1 = this.transfer1kFrom1.bind(this)
this.getNodes()
}
mountNode(node) {
if (!node.Storage) {
this.props.mountWindow((onClose) =>
<FullNode key={node.ID}
node={{...node}}
pondClient={this.props.client}
onConnect={(conn, id) => this.setState(prev => ({
nodes: {
...prev.nodes,
[node.ID]: {...node, conn: conn, peerid: id}
}
}))}
mountWindow={this.props.mountWindow}/>)
} else {
this.props.mountWindow((onClose) =>
<StorageNode node={{...node}}
pondClient={this.props.client}
mountWindow={this.props.mountWindow}/>)
}
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}/>)
}
})
}
async getNodes() {
@ -55,10 +68,29 @@ class NodeList extends React.Component {
this.setState({existingLoaded: true, nodes: nodes})
}
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",
})
}
async spawnNode() {
const node = await this.props.client.call('Pond.Spawn')
console.log(node)
this.mountNode(node)
await this.mountNode(node)
this.setState(state => ({nodes: {...state.nodes, [node.ID]: node}}))
}

View File

@ -0,0 +1,46 @@
import util from 'ipld-dag-cbor'
import { Buffer } from 'buffer'
import { Tagged } from 'borc'
async function pushMessage(client, from, inmsg) {
if(!inmsg.GasLimit) {
inmsg.GasLimit = "0"
}
if(!inmsg.GasPrice) {
inmsg.GasPrice = "0"
}
if(!inmsg.Params) {
inmsg.Params = "oA==" // 0b101_00000: empty cbor map: {}
}
if(!inmsg.Value) {
inmsg.Value = "0"
}
if(!inmsg.Method) {
inmsg.Method = 0
}
inmsg.Nonce = await client.call('Filecoin.MpoolGetNonce', [from])
/* const msg = [
inmsg.To,
inmsg.From,
inmsg.Nonce,
inmsg.Value,
inmsg.GasPrice,
inmsg.GasLimit,
inmsg.Method,
Buffer.from(inmsg.Params, 'base64'),
]*/
const signed = await client.call('Filecoin.WalletSignMessage', [from, inmsg])
console.log(signed)
await client.call('Filecoin.MpoolPush', [signed])
}
export default pushMessage

View File

@ -260,6 +260,23 @@ func (a *FullNodeAPI) WalletSign(ctx context.Context, k address.Address, msg []b
return a.Wallet.Sign(k, msg)
}
func (a *FullNodeAPI) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) {
msgbytes, err := msg.Serialize()
if err != nil {
return nil, err
}
sig, err := a.WalletSign(ctx, k, msgbytes)
if err != nil {
return nil, xerrors.Errorf("failed to sign message: %w", err)
}
return &types.SignedMessage{
Message: *msg,
Signature: *sig,
}, nil
}
func (a *FullNodeAPI) WalletDefaultAddress(ctx context.Context) (address.Address, error) {
addrs, err := a.Wallet.ListAddrs()
if err != nil {