Merge pull request #130 from filecoin-project/feat/pond-trasfers
More Pond inspections
This commit is contained in:
commit
2194f52852
10
api/api.go
10
api/api.go
@ -52,6 +52,11 @@ type SectorInfo struct {
|
||||
CommR []byte
|
||||
}
|
||||
|
||||
type ActorState struct {
|
||||
Balance types.BigInt
|
||||
State interface{}
|
||||
}
|
||||
|
||||
type Common interface {
|
||||
// Auth
|
||||
AuthVerify(ctx context.Context, token string) ([]string, error)
|
||||
@ -85,6 +90,8 @@ type FullNode interface {
|
||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
ChainGetBlockReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
||||
ChainGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
|
||||
ChainReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error)
|
||||
|
||||
// if tipset is nil, we'll use heaviest
|
||||
ChainCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error)
|
||||
@ -111,6 +118,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
|
||||
@ -135,6 +143,8 @@ type FullNode interface {
|
||||
type StorageMiner interface {
|
||||
Common
|
||||
|
||||
ActorAddresses(context.Context) ([]address.Address, error)
|
||||
|
||||
// Temp api for testing
|
||||
StoreGarbageData(context.Context) (uint64, error)
|
||||
|
||||
|
@ -48,6 +48,8 @@ type FullNodeStruct struct {
|
||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
||||
ChainGetBlockReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||
ChainCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
||||
ChainGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"`
|
||||
ChainReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"`
|
||||
|
||||
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
||||
@ -55,13 +57,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"`
|
||||
@ -76,6 +79,8 @@ type StorageMinerStruct struct {
|
||||
CommonStruct
|
||||
|
||||
Internal struct {
|
||||
ActorAddresses func(context.Context) ([]address.Address, error) `perm:"read"`
|
||||
|
||||
StoreGarbageData func(context.Context) (uint64, error) `perm:"write"`
|
||||
|
||||
SectorsStatus func(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) `perm:"read"`
|
||||
@ -170,6 +175,14 @@ func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message, ts *
|
||||
return c.Internal.ChainCall(ctx, msg, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
return c.Internal.ChainGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) {
|
||||
return c.Internal.ChainReadState(ctx, act, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
@ -190,6 +203,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)
|
||||
}
|
||||
@ -222,6 +239,10 @@ func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.
|
||||
return c.Internal.StateMinerProvingSet(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ActorAddresses(ctx context.Context) ([]address.Address, error) {
|
||||
return c.Internal.ActorAddresses(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StoreGarbageData(ctx context.Context) (uint64, error) {
|
||||
return c.Internal.StoreGarbageData(ctx)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
@ -54,6 +55,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
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
logging.SetLogLevel("*", "INFO")
|
||||
logging.SetLogLevel("*", "DEBUG")
|
||||
local := []*cli.Command{
|
||||
DaemonCmd,
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -62,7 +62,6 @@ require (
|
||||
github.com/polydawn/refmt v0.0.0-20190731040541-eff0b363297a
|
||||
github.com/smartystreets/assertions v1.0.1 // indirect
|
||||
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect
|
||||
github.com/stretchr/objx v0.1.1 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
|
||||
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
|
||||
|
@ -212,6 +212,7 @@ func (h handlers) handle(ctx context.Context, req request, w func(func(io.Writer
|
||||
if handler.errOut != -1 {
|
||||
err := callResult[handler.errOut].Interface()
|
||||
if err != nil {
|
||||
log.Warnf("error in RPC call: %s", err)
|
||||
resp.Error = &respError{
|
||||
Code: 1,
|
||||
Message: err.(error).Error(),
|
||||
@ -232,7 +233,7 @@ func (h handlers) handle(ctx context.Context, req request, w func(func(io.Writer
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
fmt.Println(err)
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
@ -73,6 +73,7 @@ func (s *RPCServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func rpcError(wf func(func(io.Writer)), req *request, code int, err error) {
|
||||
log.Errorf("RPC Error: %s", err)
|
||||
wf(func(w io.Writer) {
|
||||
if hw, ok := w.(http.ResponseWriter); ok {
|
||||
hw.WriteHeader(500)
|
||||
|
158
lotuspond/front/package-lock.json
generated
158
lotuspond/front/package-lock.json
generated
@ -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",
|
||||
|
@ -3,7 +3,11 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"borc": "^2.1.1",
|
||||
"cids": "^0.7.1",
|
||||
"ipld-dag-cbor": "^0.15.0",
|
||||
"jsonrpc-websocket-client": "^0.5.0",
|
||||
"multihashes": "^0.4.15",
|
||||
"react": "^16.8.6",
|
||||
"react-cristal": "^0.0.12",
|
||||
"react-dom": "^16.8.6",
|
||||
|
66
lotuspond/front/src/Address.js
Normal file
66
lotuspond/front/src/Address.js
Normal file
@ -0,0 +1,66 @@
|
||||
import React from 'react'
|
||||
import CID from 'cids'
|
||||
import * as multihash from "multihashes";
|
||||
import State from "./State";
|
||||
|
||||
function truncAddr(addr) {
|
||||
if (addr.length > 21) {
|
||||
return <abbr title={addr}>{addr.substr(0, 18) + '..'}</abbr>
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
class Address extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.openState = this.openState.bind(this)
|
||||
|
||||
this.state = {balance: -2}
|
||||
this.refresh = this.refresh.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refresh()
|
||||
if(!this.props.ts)
|
||||
setInterval(this.refresh, 2050)
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
let balance = 0
|
||||
let actor = {}
|
||||
|
||||
try {
|
||||
balance = await this.props.client.call('Filecoin.WalletBalance', [this.props.addr])
|
||||
actor = await this.props.client.call('Filecoin.ChainGetActor', [this.props.addr, this.props.ts || null])
|
||||
} catch (err) {
|
||||
balance = -1
|
||||
}
|
||||
this.setState({balance, actor})
|
||||
}
|
||||
|
||||
openState() {
|
||||
this.props.mountWindow((onClose) => <State addr={this.props.addr} actor={this.state.actor} client={this.props.client} onClose={onClose}/>)
|
||||
}
|
||||
|
||||
render() {
|
||||
let add1k = <span/>
|
||||
if(this.props.add1k) {
|
||||
add1k = <a href="#" onClick={() => this.props.add1k(this.props.addr)}>[+1k]</a>
|
||||
}
|
||||
let addr = truncAddr(this.props.addr)
|
||||
|
||||
let actInfo = <span>(?)</span>
|
||||
if(this.state.balance >= 0) {
|
||||
const c = new CID(this.state.actor.Code['/'])
|
||||
const mh = multihash.decode(c.multihash) // TODO: check identity
|
||||
|
||||
actInfo = <span>({mh.digest.toString()})</span>
|
||||
addr = <a href="#" onClick={this.openState}>{addr}</a>
|
||||
}
|
||||
|
||||
return <span>{addr}: {this.state.balance} {actInfo} {add1k}</span>
|
||||
}
|
||||
}
|
||||
|
||||
export default Address
|
@ -28,6 +28,22 @@
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.Block {
|
||||
background: #f9be77;
|
||||
user-select: text;
|
||||
font-family: monospace;
|
||||
min-width: 40em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.State {
|
||||
background: #f9be77;
|
||||
user-select: text;
|
||||
font-family: monospace;
|
||||
min-width: 40em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.CristalScroll {
|
||||
display: flex;
|
||||
min-width: 100%;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import {Cristal} from "react-cristal";
|
||||
import {BlockLinks} from "./BlockLink";
|
||||
import Address from "./Address";
|
||||
|
||||
class Block extends React.Component {
|
||||
constructor(props) {
|
||||
@ -13,7 +14,9 @@ class Block extends React.Component {
|
||||
|
||||
async loadHeader() {
|
||||
const header = await this.props.conn.call('Filecoin.ChainGetBlock', [this.props.cid])
|
||||
this.setState({header: header})
|
||||
const messages = await this.props.conn.call('Filecoin.ChainGetBlockMessages', [this.props.cid])
|
||||
console.log(messages)
|
||||
this.setState({header: header, messages: messages})
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -21,17 +24,30 @@ class Block extends React.Component {
|
||||
if (this.state.header) {
|
||||
let head = this.state.header
|
||||
|
||||
content = (
|
||||
|
||||
|
||||
let messages = [
|
||||
...(this.state.messages.BlsMessages.map(m => ({...m, type: 'BLS'}))),
|
||||
...(this.state.messages.SecpkMessages.map(m => ({...(m.Message), type: 'Secpk'})))
|
||||
].map(m => (
|
||||
<div>
|
||||
<Address client={this.props.conn} addr={m.From} mountWindow={this.props.mountWindow}/><b>=> </b>
|
||||
<Address client={this.props.conn} addr={m.To} mountWindow={this.props.mountWindow}/>
|
||||
{m.Value}FIL M{m.Method}
|
||||
</div>
|
||||
))
|
||||
|
||||
content = (
|
||||
<div className="Block">
|
||||
<div>Height: {head.Height}</div>
|
||||
<div>Parents: <BlockLinks cids={head.Parents} conn={this.props.conn} mountWindow={this.props.mountWindow}/></div>
|
||||
<div>Weight: {head.ParentWeight}</div>
|
||||
<div>Miner: {head.Miner}</div>
|
||||
<div>Miner: {<Address client={this.props.conn} addr={head.Miner} mountWindow={this.props.mountWindow}/>}</div>
|
||||
<div>Messages: {head.Messages['/']} {/*TODO: link to message explorer */}</div>
|
||||
<div>Receipts: {head.MessageReceipts['/']}</div>
|
||||
<div>State Root: {head.StateRoot['/']}</div>
|
||||
|
||||
|
||||
<div>State Root: {head.StateRoot['/']}</div>
|
||||
<div>----</div>
|
||||
<div>{messages}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import Block from "./Block";
|
||||
|
||||
export class BlockLinks extends React.Component {
|
||||
render() {
|
||||
return this.props.cids.map(c => <BlockLink conn={this.props.conn} cid={c} mountWindow={this.props.mountWindow}/>)
|
||||
return this.props.cids.map(c => <BlockLink key={c} conn={this.props.conn} cid={c} mountWindow={this.props.mountWindow}/>)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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]
|
||||
|
@ -3,30 +3,17 @@ import { Client } from 'rpc-websockets'
|
||||
import Cristal from 'react-cristal'
|
||||
import { BlockLinks } from "./BlockLink";
|
||||
import StorageNodeInit from "./StorageNodeInit";
|
||||
|
||||
const stateConnected = 'connected'
|
||||
const stateConnecting = 'connecting'
|
||||
const stateGettingToken = 'getting-token'
|
||||
import Address from "./Address";
|
||||
|
||||
async function awaitListReducer(prev, c) {
|
||||
return [...await prev, await c]
|
||||
}
|
||||
|
||||
function truncAddr(addr) {
|
||||
if (addr.length > 41) {
|
||||
return <abbr title={addr}>{addr.substr(0, 38) + '...'}</abbr>
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
class FullNode extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
state: stateGettingToken,
|
||||
id: "~",
|
||||
|
||||
mining: false,
|
||||
}
|
||||
|
||||
@ -34,69 +21,45 @@ 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", [])
|
||||
this.setState(() => ({version: version}))
|
||||
const id = await this.props.client.call("Filecoin.ID", [])
|
||||
|
||||
const peers = await this.state.client.call("Filecoin.NetPeers", [])
|
||||
this.setState(() => ({peers: peers.length}))
|
||||
const version = await this.props.client.call("Filecoin.Version", [])
|
||||
|
||||
const tipset = await this.state.client.call("Filecoin.ChainHead", [])
|
||||
this.setState(() => ({tipset: tipset}))
|
||||
const peers = await this.props.client.call("Filecoin.NetPeers", [])
|
||||
|
||||
const addrss = await this.state.client.call('Filecoin.WalletList', [])
|
||||
const tipset = await this.props.client.call("Filecoin.ChainHead", [])
|
||||
|
||||
const addrs = await this.props.client.call('Filecoin.WalletList', [])
|
||||
let defaultAddr = ""
|
||||
if (addrss.length > 0) {
|
||||
defaultAddr = await this.state.client.call('Filecoin.WalletDefaultAddress', [])
|
||||
if (addrs.length > 0) {
|
||||
defaultAddr = await this.props.client.call('Filecoin.WalletDefaultAddress', [])
|
||||
}
|
||||
|
||||
const balances = await addrss.map(async addr => {
|
||||
/* 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
|
||||
}
|
||||
return [addr, balance]
|
||||
}).reduce(awaitListReducer, Promise.resolve([]))
|
||||
}).reduce(awaitListReducer, Promise.resolve([]))*/
|
||||
|
||||
this.setState(() => ({balances: balances, defaultAddr: defaultAddr}))
|
||||
this.setState(() => ({
|
||||
id: id,
|
||||
version: version,
|
||||
peers: peers.length,
|
||||
tipset: tipset,
|
||||
|
||||
addrs: addrs,
|
||||
defaultAddr: defaultAddr}))
|
||||
}
|
||||
|
||||
async startMining() {
|
||||
@ -109,28 +72,33 @@ 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.id) {
|
||||
let chainInfo = <div></div>
|
||||
if (this.state.tipset !== undefined) {
|
||||
chainInfo = (
|
||||
<div>
|
||||
Head: {
|
||||
<BlockLinks cids={this.state.tipset.Cids} conn={this.state.client} mountWindow={this.props.mountWindow} />
|
||||
<BlockLinks cids={this.state.tipset.Cids} conn={this.props.client} mountWindow={this.props.mountWindow} />
|
||||
} H:{this.state.tipset.Height}
|
||||
</div>
|
||||
)
|
||||
@ -143,17 +111,17 @@ 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)}: {balance} (ActTyp)</span>
|
||||
let addresses = this.state.addrs.map((addr) => {
|
||||
let line = <Address client={this.props.client} add1k={this.add1k} addr={addr} mountWindow={this.props.mountWindow}/>
|
||||
if (this.state.defaultAddr === addr) {
|
||||
line = <b>{line}</b>
|
||||
}
|
||||
return <div>{line}</div>
|
||||
return <div key={addr}>{line}</div>
|
||||
})
|
||||
|
||||
runtime = (
|
||||
<div>
|
||||
<div>v{this.state.version.Version}, <abbr title={this.state.id}>{this.state.id.substr(-8)}</abbr>, {this.state.peers} peers</div>
|
||||
<div>{this.props.node.ID} - v{this.state.version.Version}, <abbr title={this.state.id}>{this.state.id.substr(-8)}</abbr>, {this.state.peers} peers</div>
|
||||
<div>Repo: LOTUS_PATH={this.props.node.Repo}</div>
|
||||
{chainInfo}
|
||||
<div>
|
||||
@ -161,7 +129,7 @@ class FullNode extends React.Component {
|
||||
</div>
|
||||
<div>
|
||||
<div>Balances: [New <a href="#" onClick={this.newScepAddr}>[Secp256k1]</a>]</div>
|
||||
<div>{balances}</div>
|
||||
<div>{addresses}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -174,7 +142,6 @@ class FullNode extends React.Component {
|
||||
initialPosition={{x: this.props.node.ID*30, y: this.props.node.ID * 30}} >
|
||||
<div className="CristalScroll">
|
||||
<div className="FullNode">
|
||||
<div>{this.props.node.ID} - {this.state.state}</div>
|
||||
{runtime}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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}}))
|
||||
}
|
||||
|
30
lotuspond/front/src/State.js
Normal file
30
lotuspond/front/src/State.js
Normal file
@ -0,0 +1,30 @@
|
||||
import React from 'react'
|
||||
import {Cristal} from "react-cristal";
|
||||
|
||||
class State extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {Balance: -2, State: {}}
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const tipset = await this.props.client.call("Filecoin.ChainHead", []) // TODO: from props
|
||||
const actstate = await this.props.client.call('Filecoin.ChainReadState', [this.props.actor, tipset])
|
||||
this.setState(actstate)
|
||||
}
|
||||
|
||||
render() {
|
||||
const content = <div className="State">
|
||||
<div>Balance: {this.state.Balance}</div>
|
||||
<div>---</div>
|
||||
<div>{Object.keys(this.state.State).map(k => <div key={k}>{k}: <span>{JSON.stringify(this.state.State[k])}</span></div>)}</div>
|
||||
</div>
|
||||
|
||||
return <Cristal onClose={this.props.onClose} title={`Actor ${this.props.addr} @{this.props.ts.Height}`}>
|
||||
{content}
|
||||
</Cristal>
|
||||
}
|
||||
}
|
||||
|
||||
export default State
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import {Cristal} from "react-cristal";
|
||||
import { Client } from 'rpc-websockets'
|
||||
import Address from "./Address";
|
||||
|
||||
const stateConnected = 'connected'
|
||||
const stateConnecting = 'connecting'
|
||||
@ -66,20 +67,10 @@ class StorageNode extends React.Component {
|
||||
|
||||
async loadInfo() {
|
||||
const version = await this.state.client.call("Filecoin.Version", [])
|
||||
this.setState(() => ({version: version}))
|
||||
|
||||
const peers = await this.state.client.call("Filecoin.NetPeers", [])
|
||||
this.setState(() => ({peers: peers.length}))
|
||||
|
||||
/*const addrss = await this.state.client.call('Filecoin.WalletList', [])
|
||||
let defaultAddr = ""
|
||||
if (addrss.length > 0) {
|
||||
defaultAddr = await this.state.client.call('Filecoin.WalletDefaultAddress', [])
|
||||
}
|
||||
|
||||
this.setState(() => ({defaultAddr: defaultAddr}))
|
||||
*/
|
||||
const [actor] = await this.state.client.call("Filecoin.ActorAddresses", [])
|
||||
|
||||
this.setState({version: version, peers: peers.length, actor: actor})
|
||||
await this.stagedList()
|
||||
}
|
||||
|
||||
@ -100,7 +91,7 @@ class StorageNode extends React.Component {
|
||||
|
||||
render() {
|
||||
let runtime = <div></div>
|
||||
if (this.state.state === stateConnected) {
|
||||
if (this.state.actor) {
|
||||
const sealGarbage = <a href="#" onClick={this.sealGarbage}>[Seal Garbage]</a>
|
||||
|
||||
runtime = (
|
||||
@ -110,6 +101,9 @@ class StorageNode extends React.Component {
|
||||
<div>
|
||||
{sealGarbage}
|
||||
</div>
|
||||
<div>
|
||||
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
|
||||
</div>
|
||||
<div>{this.state.statusCounts.map((c, i) => <span>{sealCodes[i]}: {c} | </span>)}</div>
|
||||
<div>
|
||||
{this.state.staged ? this.state.staged.map(s => (
|
||||
|
46
lotuspond/front/src/chain/send.js
Normal file
46
lotuspond/front/src/chain/send.js
Normal 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
|
@ -3,6 +3,7 @@ package impl
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filecoin-project/go-lotus/lib/bufbstore"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
@ -20,7 +21,7 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/node/client"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -191,6 +192,47 @@ func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message, ts *typ
|
||||
return &ret.MessageReceipt, err
|
||||
}
|
||||
|
||||
func (a *FullNodeAPI) stateForTs(ts *types.TipSet) (*state.StateTree, error) {
|
||||
if ts == nil {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
}
|
||||
|
||||
st, err := a.Chain.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(a.Chain.Blockstore())
|
||||
cst := hamt.CSTFromBstore(buf)
|
||||
return state.LoadStateTree(cst, st)
|
||||
}
|
||||
|
||||
func (a *FullNodeAPI) ChainGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
state, err := a.stateForTs(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state.GetActor(actor)
|
||||
}
|
||||
|
||||
func (a *FullNodeAPI) ChainReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) {
|
||||
state, err := a.stateForTs(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var oif interface{}
|
||||
if err := state.Store.Get(context.TODO(), act.Head, &oif); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.ActorState{
|
||||
Balance: act.Balance,
|
||||
State: oif,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *FullNodeAPI) MpoolPending(ctx context.Context, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||
// TODO: need to make sure we don't return messages that were already included in the referenced chain
|
||||
// also need to accept ts == nil just fine, assume nil == chain.Head()
|
||||
@ -260,6 +302,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 {
|
||||
|
@ -3,6 +3,7 @@ package impl
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
|
||||
@ -14,11 +15,16 @@ import (
|
||||
type StorageMinerAPI struct {
|
||||
CommonAPI
|
||||
|
||||
SectorBuilder *sectorbuilder.SectorBuilder
|
||||
SectorBuilderConfig *sectorbuilder.SectorBuilderConfig
|
||||
SectorBuilder *sectorbuilder.SectorBuilder
|
||||
|
||||
Miner *storage.Miner
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) ActorAddresses(context.Context) ([]address.Address, error) {
|
||||
return []address.Address{sm.SectorBuilderConfig.Miner}, nil
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) (uint64, error) {
|
||||
maxSize := uint64(1016) // this is the most data we can fit in a 1024 byte sector
|
||||
data := make([]byte, maxSize)
|
||||
|
Loading…
Reference in New Issue
Block a user