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)
|
||||
StateListActors(context.Context, *types.TipSet) ([]address.Address, 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)
|
||||
PaychList(context.Context) ([]address.Address, error)
|
||||
|
@ -101,6 +101,8 @@ type FullNodeStruct struct {
|
||||
StateListMiners 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"`
|
||||
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"`
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
return c.Internal.PaychGet(ctx, from, to, ensureFunds)
|
||||
}
|
||||
|
@ -3476,3 +3476,61 @@ func (t *ProcessStorageDealsPaymentParams) UnmarshalCBOR(r io.Reader) error {
|
||||
|
||||
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 (
|
||||
"context"
|
||||
"math"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
"github.com/ipfs/go-datastore/namespace"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
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
|
||||
}
|
||||
|
||||
proposalNd, err := cbor.WrapObject(proposal, math.MaxUint64, -1)
|
||||
proposalNd, err := cborrpc.AsIpld(proposal)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
@ -2,13 +2,11 @@ package deals
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
datastore "github.com/ipfs/go-datastore"
|
||||
"github.com/ipfs/go-datastore/namespace"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"golang.org/x/xerrors"
|
||||
@ -17,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"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/storage/commitment"
|
||||
"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) {
|
||||
proposalNd, err := cbor.WrapObject(proposal, math.MaxUint64, -1)
|
||||
proposalNd, err := cborrpc.AsIpld(proposal)
|
||||
if err != nil {
|
||||
return MinerDeal{}, err
|
||||
}
|
||||
|
@ -5,6 +5,14 @@ import (
|
||||
"fmt"
|
||||
|
||||
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"
|
||||
actors "github.com/filecoin-project/lotus/chain/actors"
|
||||
"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/types"
|
||||
"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 {
|
||||
|
@ -86,6 +86,7 @@ func main() {
|
||||
actors.PublishStorageDealResponse{},
|
||||
actors.ActivateStorageDealsParams{},
|
||||
actors.ProcessStorageDealsPaymentParams{},
|
||||
actors.OnChainDeal{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"math"
|
||||
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
logging "github.com/ipfs/go-log"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
@ -52,3 +54,15 @@ func Dump(obj interface{}) ([]byte, error) {
|
||||
}
|
||||
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": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
||||
@ -10663,6 +10668,15 @@
|
||||
"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": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
|
||||
|
@ -13,6 +13,7 @@
|
||||
"react-dom": "^16.8.6",
|
||||
"react-router-dom": "^5.0.1",
|
||||
"react-scripts": "3.0.1",
|
||||
"react-tooltip": "^3.11.1",
|
||||
"rpc-websockets": "^4.5.1",
|
||||
"styled-components": "^3.3.3",
|
||||
"xterm": "^3.14.5",
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react'
|
||||
import CID from 'cids'
|
||||
import * as multihash from "multihashes";
|
||||
import State from "./State";
|
||||
import methods from "./chain/methods";
|
||||
import ReactTooltip from 'react-tooltip'
|
||||
import * as multihash from "multihashes"
|
||||
import State from "./State"
|
||||
import methods from "./chain/methods"
|
||||
|
||||
function truncAddr(addr, len) {
|
||||
if (addr.length > len) {
|
||||
@ -11,6 +12,17 @@ function truncAddr(addr, len) {
|
||||
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')
|
||||
document.body.appendChild(sheet);
|
||||
|
||||
@ -62,7 +74,7 @@ class Address extends React.Component {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -117,12 +129,12 @@ class Address extends React.Component {
|
||||
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) {
|
||||
balance = <span/>
|
||||
}
|
||||
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/>
|
||||
}
|
||||
|
||||
@ -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>
|
||||
}
|
||||
|
||||
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>Messages: {head.Messages['/']} {/*TODO: link to message explorer */}</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>{messages}</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,17 @@
|
||||
import React from 'react'
|
||||
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 {
|
||||
byCode = {
|
||||
[code.init]: InitState,
|
||||
[code.power]: PowerState,
|
||||
[code.market]: MarketState,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
@ -9,22 +19,99 @@ class State extends React.Component {
|
||||
}
|
||||
|
||||
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])
|
||||
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() {
|
||||
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">
|
||||
<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>
|
||||
{state}
|
||||
</div>
|
||||
|
||||
return <Window onClose={this.props.onClose} title={`Actor ${this.props.addr} @{this.props.ts.Height}`}>
|
||||
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}`}>
|
||||
{content}
|
||||
</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
|
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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"strconv"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -240,3 +244,62 @@ func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address,
|
||||
|
||||
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