on chain deals: Expose more chain state in pond
This commit is contained in:
parent
64bfb38834
commit
213ac77d08
@ -135,6 +135,8 @@ type FullNode interface {
|
|||||||
StateListMiners(context.Context, *types.TipSet) ([]address.Address, error)
|
StateListMiners(context.Context, *types.TipSet) ([]address.Address, error)
|
||||||
StateListActors(context.Context, *types.TipSet) ([]address.Address, error)
|
StateListActors(context.Context, *types.TipSet) ([]address.Address, error)
|
||||||
StateMarketBalance(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error)
|
StateMarketBalance(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error)
|
||||||
|
StateMarketParticipants(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error)
|
||||||
|
StateMarketDeals(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error)
|
||||||
|
|
||||||
PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error)
|
PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error)
|
||||||
PaychList(context.Context) ([]address.Address, error)
|
PaychList(context.Context) ([]address.Address, error)
|
||||||
|
@ -101,6 +101,8 @@ type FullNodeStruct struct {
|
|||||||
StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
|
StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
|
||||||
StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
|
StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
|
||||||
StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"`
|
StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"`
|
||||||
|
StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"`
|
||||||
|
StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"`
|
||||||
|
|
||||||
PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) `perm:"sign"`
|
PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) `perm:"sign"`
|
||||||
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
||||||
@ -394,6 +396,14 @@ func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Ad
|
|||||||
return c.Internal.StateMarketBalance(ctx, addr, ts)
|
return c.Internal.StateMarketBalance(ctx, addr, ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]actors.StorageParticipantBalance, error) {
|
||||||
|
return c.Internal.StateMarketParticipants(ctx, ts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]actors.OnChainDeal, error) {
|
||||||
|
return c.Internal.StateMarketDeals(ctx, ts)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) {
|
func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) {
|
||||||
return c.Internal.PaychGet(ctx, from, to, ensureFunds)
|
return c.Internal.PaychGet(ctx, from, to, ensureFunds)
|
||||||
}
|
}
|
||||||
|
@ -3476,3 +3476,61 @@ func (t *ProcessStorageDealsPaymentParams) UnmarshalCBOR(r io.Reader) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *OnChainDeal) MarshalCBOR(w io.Writer) error {
|
||||||
|
if t == nil {
|
||||||
|
_, err := w.Write(cbg.CborNull)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write([]byte{130}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.t.Deal (actors.StorageDeal)
|
||||||
|
if err := t.Deal.MarshalCBOR(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.t.ActivationEpoch (uint64)
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.ActivationEpoch)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *OnChainDeal) UnmarshalCBOR(r io.Reader) error {
|
||||||
|
br := cbg.GetPeeker(r)
|
||||||
|
|
||||||
|
maj, extra, err := cbg.CborReadHeader(br)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if maj != cbg.MajArray {
|
||||||
|
return fmt.Errorf("cbor input should be of type array")
|
||||||
|
}
|
||||||
|
|
||||||
|
if extra != 2 {
|
||||||
|
return fmt.Errorf("cbor input had wrong number of fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.t.Deal (actors.StorageDeal)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
if err := t.Deal.UnmarshalCBOR(br); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// t.t.ActivationEpoch (uint64)
|
||||||
|
|
||||||
|
maj, extra, err = cbg.CborReadHeader(br)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if maj != cbg.MajUnsignedInt {
|
||||||
|
return fmt.Errorf("wrong type for uint64 field")
|
||||||
|
}
|
||||||
|
t.ActivationEpoch = extra
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -2,12 +2,10 @@ package deals
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
"github.com/ipfs/go-datastore/namespace"
|
"github.com/ipfs/go-datastore/namespace"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
inet "github.com/libp2p/go-libp2p-core/network"
|
inet "github.com/libp2p/go-libp2p-core/network"
|
||||||
@ -185,7 +183,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro
|
|||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proposalNd, err := cbor.WrapObject(proposal, math.MaxUint64, -1)
|
proposalNd, err := cborrpc.AsIpld(proposal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,11 @@ package deals
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
datastore "github.com/ipfs/go-datastore"
|
datastore "github.com/ipfs/go-datastore"
|
||||||
"github.com/ipfs/go-datastore/namespace"
|
"github.com/ipfs/go-datastore/namespace"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
|
||||||
inet "github.com/libp2p/go-libp2p-core/network"
|
inet "github.com/libp2p/go-libp2p-core/network"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -17,6 +15,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/address"
|
"github.com/filecoin-project/lotus/chain/address"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/cborrpc"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/storage/commitment"
|
"github.com/filecoin-project/lotus/storage/commitment"
|
||||||
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
||||||
@ -192,7 +191,7 @@ func (p *Provider) onUpdated(ctx context.Context, update minerDealUpdate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) newDeal(s inet.Stream, proposal actors.StorageDealProposal) (MinerDeal, error) {
|
func (p *Provider) newDeal(s inet.Stream, proposal actors.StorageDealProposal) (MinerDeal, error) {
|
||||||
proposalNd, err := cbor.WrapObject(proposal, math.MaxUint64, -1)
|
proposalNd, err := cborrpc.AsIpld(proposal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MinerDeal{}, err
|
return MinerDeal{}, err
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
amt "github.com/filecoin-project/go-amt-ipld"
|
amt "github.com/filecoin-project/go-amt-ipld"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/ipfs/go-datastore"
|
||||||
|
hamt "github.com/ipfs/go-hamt-ipld"
|
||||||
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
|
peer "github.com/libp2p/go-libp2p-peer"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
actors "github.com/filecoin-project/lotus/chain/actors"
|
actors "github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/address"
|
"github.com/filecoin-project/lotus/chain/address"
|
||||||
@ -12,14 +20,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"github.com/ipfs/go-datastore"
|
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
|
||||||
peer "github.com/libp2p/go-libp2p-peer"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type GenesisBootstrap struct {
|
type GenesisBootstrap struct {
|
||||||
|
@ -86,6 +86,7 @@ func main() {
|
|||||||
actors.PublishStorageDealResponse{},
|
actors.PublishStorageDealResponse{},
|
||||||
actors.ActivateStorageDealsParams{},
|
actors.ActivateStorageDealsParams{},
|
||||||
actors.ProcessStorageDealsPaymentParams{},
|
actors.ProcessStorageDealsPaymentParams{},
|
||||||
|
actors.OnChainDeal{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
@ -4,8 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
ipld "github.com/ipfs/go-ipld-format"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
)
|
)
|
||||||
@ -52,3 +54,15 @@ func Dump(obj interface{}) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return out.Bytes(), nil
|
return out.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is a bit ugly, and this package is not exactly the best place
|
||||||
|
func AsIpld(obj interface{}) (ipld.Node, error) {
|
||||||
|
if m, ok := obj.(cbg.CBORMarshaler); ok {
|
||||||
|
b, err := Dump(m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cbor.Decode(b, math.MaxUint64, -1)
|
||||||
|
}
|
||||||
|
return cbor.WrapObject(obj, math.MaxUint64, -1)
|
||||||
|
}
|
||||||
|
14
lotuspond/front/package-lock.json
generated
14
lotuspond/front/package-lock.json
generated
@ -3457,6 +3457,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"classnames": {
|
||||||
|
"version": "2.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||||
|
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||||
|
},
|
||||||
"clean-css": {
|
"clean-css": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
||||||
@ -10663,6 +10668,15 @@
|
|||||||
"workbox-webpack-plugin": "4.2.0"
|
"workbox-webpack-plugin": "4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-tooltip": {
|
||||||
|
"version": "3.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-3.11.1.tgz",
|
||||||
|
"integrity": "sha512-YCMVlEC2KuHIzOQhPplTK5jmBBwoL+PYJJdJKXj7M/h7oevupd/QSVq6z5U7/ehIGXyHsAqvwpdxexDfyQ0o3A==",
|
||||||
|
"requires": {
|
||||||
|
"classnames": "^2.2.5",
|
||||||
|
"prop-types": "^15.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"react-dom": "^16.8.6",
|
"react-dom": "^16.8.6",
|
||||||
"react-router-dom": "^5.0.1",
|
"react-router-dom": "^5.0.1",
|
||||||
"react-scripts": "3.0.1",
|
"react-scripts": "3.0.1",
|
||||||
|
"react-tooltip": "^3.11.1",
|
||||||
"rpc-websockets": "^4.5.1",
|
"rpc-websockets": "^4.5.1",
|
||||||
"styled-components": "^3.3.3",
|
"styled-components": "^3.3.3",
|
||||||
"xterm": "^3.14.5",
|
"xterm": "^3.14.5",
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CID from 'cids'
|
import CID from 'cids'
|
||||||
import * as multihash from "multihashes";
|
import ReactTooltip from 'react-tooltip'
|
||||||
import State from "./State";
|
import * as multihash from "multihashes"
|
||||||
import methods from "./chain/methods";
|
import State from "./State"
|
||||||
|
import methods from "./chain/methods"
|
||||||
|
|
||||||
function truncAddr(addr, len) {
|
function truncAddr(addr, len) {
|
||||||
if (addr.length > len) {
|
if (addr.length > len) {
|
||||||
@ -11,6 +12,17 @@ function truncAddr(addr, len) {
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filStr(raw) {
|
||||||
|
if(typeof raw !== 'string') {
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
if(raw.length < 18) {
|
||||||
|
raw = '0'.repeat(18 - raw.length)
|
||||||
|
}
|
||||||
|
let out = (raw.substring(0, raw.length - 18) + '.' + raw.substring(raw.length - 18, raw.length)).replace(/\.0+|0+$/g, '');
|
||||||
|
return out ? out : '0'
|
||||||
|
}
|
||||||
|
|
||||||
let sheet = document.createElement('style')
|
let sheet = document.createElement('style')
|
||||||
document.body.appendChild(sheet);
|
document.body.appendChild(sheet);
|
||||||
|
|
||||||
@ -62,7 +74,7 @@ class Address extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openState() {
|
openState() {
|
||||||
this.props.mountWindow((onClose) => <State addr={this.props.addr} actor={this.state.actor} client={this.props.client} onClose={onClose}/>)
|
this.props.mountWindow((onClose) => <State addr={this.props.addr} actor={this.state.actor} client={this.props.client} onClose={onClose} mountWindow={this.props.mountWindow}/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
async actorInfo(actor) {
|
async actorInfo(actor) {
|
||||||
@ -117,12 +129,12 @@ class Address extends React.Component {
|
|||||||
nonce = <span> <abbr title={"Next nonce"}>Nc:{this.state.nonce}</abbr>{nonce}</span>
|
nonce = <span> <abbr title={"Next nonce"}>Nc:{this.state.nonce}</abbr>{nonce}</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
let balance = <span>: {this.state.balance} </span>
|
let balance = <span>: {filStr(this.state.balance)} </span>
|
||||||
if(this.props.nobalance) {
|
if(this.props.nobalance) {
|
||||||
balance = <span/>
|
balance = <span/>
|
||||||
}
|
}
|
||||||
if(this.props.short) {
|
if(this.props.short) {
|
||||||
actInfo = <span/>
|
actInfo = <ReactTooltip id={this.props.addr} place="top" type="dark" effect="solid">{actInfo}: {filStr(this.state.balance)}</ReactTooltip>
|
||||||
balance = <span/>
|
balance = <span/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +148,7 @@ class Address extends React.Component {
|
|||||||
minerInfo = <span> Power: {this.state.minerInfo.MinerPower} ({this.state.minerInfo.MinerPower/this.state.minerInfo.TotalPower*100}%)</span>
|
minerInfo = <span> Power: {this.state.minerInfo.MinerPower} ({this.state.minerInfo.MinerPower/this.state.minerInfo.TotalPower*100}%)</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
return <span>{addr}{balance}{actInfo}{nonce}{add20k}{transfer}{minerInfo}</span>
|
return <span data-tip data-for={this.props.addr}>{addr}{balance}{actInfo}{nonce}{add20k}{transfer}{minerInfo}</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,14 @@ class Block extends React.Component {
|
|||||||
<div>Miner: {<Address client={this.props.conn} addr={head.Miner} mountWindow={this.props.mountWindow}/>}</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>Messages: {head.Messages['/']} {/*TODO: link to message explorer */}</div>
|
||||||
<div>Parent Receipts: {head.ParentMessageReceipts['/']}</div>
|
<div>Parent Receipts: {head.ParentMessageReceipts['/']}</div>
|
||||||
<div>Parent State Root: {head.ParentStateRoot['/']}</div>
|
<div>
|
||||||
|
<span>Parent State Root: {head.ParentStateRoot['/']}</span>
|
||||||
|
<span> <Address client={this.props.conn} short={true} addr="t00" mountWindow={this.props.mountWindow}/></span>
|
||||||
|
<span> <Address client={this.props.conn} short={true} addr="t01" mountWindow={this.props.mountWindow}/></span>
|
||||||
|
<span> <Address client={this.props.conn} short={true} addr="t02" mountWindow={this.props.mountWindow}/></span>
|
||||||
|
<span> <Address client={this.props.conn} short={true} addr="t03" mountWindow={this.props.mountWindow}/></span>
|
||||||
|
<span> <Address client={this.props.conn} short={true} addr="t099" mountWindow={this.props.mountWindow}/></span>
|
||||||
|
</div>
|
||||||
<div>----</div>
|
<div>----</div>
|
||||||
<div>{messages}</div>
|
<div>{messages}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Window from "./Window";
|
import Window from "./Window";
|
||||||
|
import CID from "cids";
|
||||||
|
import * as multihash from "multihashes";
|
||||||
|
import code from "./chain/code";
|
||||||
|
import Address from "./Address";
|
||||||
|
|
||||||
class State extends React.Component {
|
class State extends React.Component {
|
||||||
|
byCode = {
|
||||||
|
[code.init]: InitState,
|
||||||
|
[code.power]: PowerState,
|
||||||
|
[code.market]: MarketState,
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
@ -9,22 +19,99 @@ class State extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const tipset = await this.props.client.call("Filecoin.ChainHead", []) // TODO: from props
|
const tipset = this.props.tipset || await this.props.client.call("Filecoin.ChainHead", [])
|
||||||
const actstate = await this.props.client.call('Filecoin.StateReadState', [this.props.actor, tipset])
|
const actstate = await this.props.client.call('Filecoin.StateReadState', [this.props.actor, tipset])
|
||||||
this.setState(actstate)
|
|
||||||
|
const c = new CID(this.props.actor.Code['/'])
|
||||||
|
const mh = multihash.decode(c.multihash)
|
||||||
|
let code = mh.digest.toString()
|
||||||
|
|
||||||
|
this.setState({...actstate, code: code})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let state
|
||||||
|
if(this.byCode[this.state.code]) {
|
||||||
|
const Stelem = this.byCode[this.state.code]
|
||||||
|
state = <Stelem client={this.props.client} mountWindow={this.props.mountWindow} tipset={this.props.tipset}/>
|
||||||
|
} else {
|
||||||
|
state = <div>{Object.keys(this.state.State).map(k => <div key={k}>{k}: <span>{JSON.stringify(this.state.State[k])}</span></div>)}</div>
|
||||||
|
}
|
||||||
|
|
||||||
const content = <div className="State">
|
const content = <div className="State">
|
||||||
<div>Balance: {this.state.Balance}</div>
|
<div>Balance: {this.state.Balance}</div>
|
||||||
<div>---</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>
|
{state}
|
||||||
</div>
|
</div>
|
||||||
|
return <Window initialSize={{width: 700, height: 400}} onClose={this.props.onClose} title={`Actor ${this.props.addr} ${this.props.tipset && this.props.tipset.Height || ''} ${this.state.code}`}>
|
||||||
return <Window onClose={this.props.onClose} title={`Actor ${this.props.addr} @{this.props.ts.Height}`}>
|
|
||||||
{content}
|
{content}
|
||||||
</Window>
|
</Window>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InitState extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {actors: []}
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
const tipset = await this.props.client.call("Filecoin.ChainHead", []) // TODO: from props
|
||||||
|
const actors = await this.props.client.call("Filecoin.StateListActors", [tipset])
|
||||||
|
this.setState({actors: actors})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return this.state.actors.sort((a, b) => (Number(a.substr(1)) > Number(b.substr(1))))
|
||||||
|
.map(addr => <div key={addr}><Address addr={addr} client={this.props.client} mountWindow={this.props.mountWindow}/></div>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PowerState extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {actors: []}
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
const tipset = await this.props.client.call("Filecoin.ChainHead", []) // TODO: from props
|
||||||
|
const actors = await this.props.client.call("Filecoin.StateListMiners", [tipset])
|
||||||
|
this.setState({actors: actors})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return this.state.actors.sort((a, b) => (Number(a.substr(1)) > Number(b.substr(1))))
|
||||||
|
.map(addr => <div key={addr}><Address miner={true} addr={addr} client={this.props.client} mountWindow={this.props.mountWindow}/></div>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MarketState extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.state = {participants: {}, deals: []}
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
const tipset = await this.props.client.call("Filecoin.ChainHead", []) // TODO: from props
|
||||||
|
const participants = await this.props.client.call("Filecoin.StateMarketParticipants", [tipset])
|
||||||
|
const deals = await this.props.client.call("Filecoin.StateMarketDeals", [tipset])
|
||||||
|
this.setState({participants, deals})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div>
|
||||||
|
<div>
|
||||||
|
<div>Participants:</div>
|
||||||
|
{Object.keys(this.state.participants).map(p => <span>{p}</span>)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>Deals:</div>
|
||||||
|
{this.state.deals.map(d => <span>{d}</span>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default State
|
export default State
|
5
lotuspond/front/src/chain/code.js
Normal file
5
lotuspond/front/src/chain/code.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export default {
|
||||||
|
init: 'filecoin/1.0/InitActor',
|
||||||
|
power: 'filecoin/1.0/StoragePowerActor',
|
||||||
|
market: 'filecoin/1.0/StorageMarketActor'
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package full
|
package full
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filecoin-project/go-amt-ipld"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
"github.com/ipfs/go-hamt-ipld"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -240,3 +244,62 @@ func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address,
|
|||||||
|
|
||||||
return b[0], nil
|
return b[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]actors.StorageParticipantBalance, error) {
|
||||||
|
out := map[string]actors.StorageParticipantBalance{}
|
||||||
|
|
||||||
|
var state actors.StorageMarketState
|
||||||
|
if _, err := a.StateManager.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cst := hamt.CSTFromBstore(a.StateManager.ChainStore().Blockstore())
|
||||||
|
nd, err := hamt.LoadNode(ctx, cst, state.Balances)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nd.ForEach(ctx, func(k string, val interface{}) error {
|
||||||
|
cv := val.(*cbg.Deferred)
|
||||||
|
a, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var b actors.StorageParticipantBalance
|
||||||
|
if err := b.UnmarshalCBOR(bytes.NewReader(cv.Raw)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out[a.String()] = b
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]actors.OnChainDeal, error) {
|
||||||
|
out := map[string]actors.OnChainDeal{}
|
||||||
|
|
||||||
|
var state actors.StorageMarketState
|
||||||
|
if _, err := a.StateManager.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
blks := amt.WrapBlockstore(a.StateManager.ChainStore().Blockstore())
|
||||||
|
da, err := amt.LoadAMT(blks, state.Deals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := da.ForEach(func(i uint64, v *cbg.Deferred) error {
|
||||||
|
var d actors.OnChainDeal
|
||||||
|
if err := d.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out[strconv.FormatInt(int64(i), 10)] = d
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user