chain: Better ReadState

This commit is contained in:
Łukasz Magiera 2019-08-16 04:33:59 +02:00
parent 6bee253e33
commit 3327781e60
2 changed files with 33 additions and 8 deletions

View File

@ -2,6 +2,7 @@ package vm
import ( import (
"fmt" "fmt"
"golang.org/x/xerrors"
"reflect" "reflect"
actors "github.com/filecoin-project/go-lotus/chain/actors" actors "github.com/filecoin-project/go-lotus/chain/actors"
@ -13,6 +14,7 @@ import (
type invoker struct { type invoker struct {
builtInCode map[cid.Cid]nativeCode builtInCode map[cid.Cid]nativeCode
builtInState map[cid.Cid]reflect.Type
} }
type invokeFunc func(act *types.Actor, vmctx types.VMContext, params []byte) ([]byte, aerrors.ActorError) type invokeFunc func(act *types.Actor, vmctx types.VMContext, params []byte) ([]byte, aerrors.ActorError)
@ -21,14 +23,15 @@ type nativeCode []invokeFunc
func newInvoker() *invoker { func newInvoker() *invoker {
inv := &invoker{ inv := &invoker{
builtInCode: make(map[cid.Cid]nativeCode), builtInCode: make(map[cid.Cid]nativeCode),
builtInState: make(map[cid.Cid]reflect.Type),
} }
// add builtInCode using: register(cid, singleton) // add builtInCode using: register(cid, singleton)
inv.register(actors.InitActorCodeCid, actors.InitActor{}) inv.register(actors.InitActorCodeCid, actors.InitActor{}, actors.InitActorState{})
inv.register(actors.StorageMarketActorCodeCid, actors.StorageMarketActor{}) inv.register(actors.StorageMarketActorCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}) inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
inv.register(actors.MultisigActorCodeCid, actors.MultiSigActor{}) inv.register(actors.MultisigActorCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
inv.register(actors.PaymentChannelActorCodeCid, actors.PaymentChannelActor{}) inv.register(actors.PaymentChannelActorCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
return inv return inv
} }
@ -46,12 +49,13 @@ func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint6
} }
func (inv *invoker) register(c cid.Cid, instance Invokee) { func (inv *invoker) register(c cid.Cid, instance Invokee, state interface{}) {
code, err := inv.transform(instance) code, err := inv.transform(instance)
if err != nil { if err != nil {
panic(err) panic(err)
} }
inv.builtInCode[c] = code inv.builtInCode[c] = code
inv.builtInState[c] = reflect.TypeOf(state)
} }
type Invokee interface { type Invokee interface {
@ -136,3 +140,19 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
} }
return code, nil return code, nil
} }
func DumpActorState(code cid.Cid, b []byte) (interface{}, error) {
i := newInvoker() // TODO: register builtins in init block
typ, ok := i.builtInState[code]
if !ok {
return nil, xerrors.New("state type for actor not found")
}
rv := reflect.New(typ)
if err := cbor.DecodeInto(b, rv.Interface()); err != nil {
return nil, err
}
return rv.Elem().Interface(), nil
}

View File

@ -244,8 +244,13 @@ func (a *FullNodeAPI) ChainReadState(ctx context.Context, act *types.Actor, ts *
return nil, err return nil, err
} }
var oif interface{} blk, err := state.Store.Blocks.GetBlock(ctx, act.Head)
if err := state.Store.Get(context.TODO(), act.Head, &oif); err != nil { if err != nil {
return nil, err
}
oif, err := vm.DumpActorState(act.Code, blk.RawData())
if err != nil {
return nil, err return nil, err
} }