Merge pull request #1932 from filecoin-project/feat/chainget-state

chain get: @state selector to prettify actor state
This commit is contained in:
Łukasz Magiera 2020-06-05 22:42:36 +02:00 committed by GitHub
commit a5d81c6cc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 1 deletions

View File

@ -442,7 +442,8 @@ var chainGetCmd = &cli.Command{
- /ipfs/[cid]/@Hi:123 - get varint elem 123 from hamt
- /ipfs/[cid]/@Hu:123 - get uvarint elem 123 from hamt
- /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes
- /ipfs/[cid]/@A:10 - get 10th amt element
- /ipfs/[cid]/@A:10 - get 10th amt element
- .../@Ha:t01/@state - get pretty map-based actor state
List of --as-type types:
- raw

View File

@ -1,7 +1,9 @@
package full
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"strconv"
@ -33,6 +35,7 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
)
var log = logging.Logger("fullnode")
@ -377,6 +380,54 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
return resolveOnce(bs)(ctx, ds, n, names[1:])
}
if names[0] == "@state" {
var act types.Actor
if err := act.UnmarshalCBOR(bytes.NewReader(nd.RawData())); err != nil {
return nil, nil, xerrors.Errorf("unmarshaling actor struct for @state: %w", err)
}
head, err := ds.Get(ctx, act.Head)
if err != nil {
return nil, nil, xerrors.Errorf("getting actor head for @state: %w", err)
}
m, err := vm.DumpActorState(act.Code, head.RawData())
if err != nil {
return nil, nil, err
}
// a hack to workaround struct aliasing in refmt
ms := map[string]interface{}{}
{
mstr, err := json.Marshal(m)
if err != nil {
return nil, nil, err
}
if err := json.Unmarshal(mstr, &ms); err != nil {
return nil, nil, err
}
}
n, err := cbor.WrapObject(ms, mh.SHA2_256, 32)
if err != nil {
return nil, nil, err
}
if err := bs.Put(n); err != nil {
return nil, nil, xerrors.Errorf("put amt val: %w", err)
}
if len(names) == 1 {
return &ipld.Link{
Name: "state",
Size: 0,
Cid: n.Cid(),
}, nil, nil
}
return resolveOnce(bs)(ctx, ds, n, names[1:])
}
return nd.ResolveLink(names)
}
}