initial vm conversion
We're probably going to want to change some of these design decisions down the road, but this is a good starting point. * We may want to use a more general test for "is actor valid at epoch". Maybe just a function? * I'd like to push some of the actor metadata down into the actor types themselves. Ideally, we'd be able to register actors with a simple `Register(validation, manyActors...)` call.
This commit is contained in:
parent
d9656f5220
commit
8b35f480c4
@ -106,7 +106,7 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
|
|
||||||
sm := NewStateManager(cg.ChainStore())
|
sm := NewStateManager(cg.ChainStore())
|
||||||
|
|
||||||
inv := vm.NewInvoker()
|
inv := vm.NewActorRegistry()
|
||||||
|
|
||||||
// predicting the address here... may break if other assumptions change
|
// predicting the address here... may break if other assumptions change
|
||||||
taddr, err := address.NewIDAddress(1002)
|
taddr, err := address.NewIDAddress(1002)
|
||||||
@ -143,7 +143,7 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
inv.Register(actors.Version0, builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{}, false)
|
||||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
||||||
nvm, err := vm.NewVM(ctx, vmopt)
|
nvm, err := vm.NewVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
addr "github.com/filecoin-project/go-address"
|
addr "github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
|
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
)
|
)
|
||||||
@ -210,7 +209,7 @@ func (ps pricedSyscalls) VerifyPoSt(vi proof.WindowPoStVerifyInfo) error {
|
|||||||
// the "parent grinding fault", in which case it must be the sibling of h1 (same parent tipset) and one of the
|
// the "parent grinding fault", in which case it must be the sibling of h1 (same parent tipset) and one of the
|
||||||
// blocks in the parent of h2 (i.e. h2's grandparent).
|
// blocks in the parent of h2 (i.e. h2's grandparent).
|
||||||
// Returns nil and an error if the headers don't prove a fault.
|
// Returns nil and an error if the headers don't prove a fault.
|
||||||
func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*runtime.ConsensusFault, error) {
|
func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*vmr.ConsensusFault, error) {
|
||||||
ps.chargeGas(ps.pl.OnVerifyConsensusFault())
|
ps.chargeGas(ps.pl.OnVerifyConsensusFault())
|
||||||
defer ps.chargeGas(gasOnActorExec)
|
defer ps.chargeGas(gasOnActorExec)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type scalingCost struct {
|
type scalingCost struct {
|
||||||
@ -112,14 +112,14 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M
|
|||||||
|
|
||||||
if big.Cmp(value, abi.NewTokenAmount(0)) != 0 {
|
if big.Cmp(value, abi.NewTokenAmount(0)) != 0 {
|
||||||
ret += pl.sendTransferFunds
|
ret += pl.sendTransferFunds
|
||||||
if methodNum == builtin.MethodSend {
|
if methodNum == builtin0.MethodSend {
|
||||||
// transfer only
|
// transfer only
|
||||||
ret += pl.sendTransferOnlyPremium
|
ret += pl.sendTransferOnlyPremium
|
||||||
}
|
}
|
||||||
extra += "t"
|
extra += "t"
|
||||||
}
|
}
|
||||||
|
|
||||||
if methodNum != builtin.MethodSend {
|
if methodNum != builtin0.MethodSend {
|
||||||
extra += "i"
|
extra += "i"
|
||||||
// running actors is cheaper becase we hand over to actors
|
// running actors is cheaper becase we hand over to actors
|
||||||
ret += pl.sendInvokeMethod
|
ret += pl.sendInvokeMethod
|
||||||
|
@ -40,79 +40,113 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Invoker struct {
|
type ActorRegistry struct {
|
||||||
builtInCode map[cid.Cid]nativeCode
|
actors map[cid.Cid]*actorInfo
|
||||||
builtInState map[cid.Cid]reflect.Type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError)
|
type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError)
|
||||||
type nativeCode []invokeFunc
|
type nativeCode []invokeFunc
|
||||||
|
|
||||||
func NewInvoker() *Invoker {
|
type actorInfo struct {
|
||||||
inv := &Invoker{
|
methods nativeCode
|
||||||
builtInCode: make(map[cid.Cid]nativeCode),
|
stateType reflect.Type
|
||||||
builtInState: make(map[cid.Cid]reflect.Type),
|
// TODO: consider making this a network version range?
|
||||||
}
|
version actors.Version
|
||||||
|
singleton bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewActorRegistry() *ActorRegistry {
|
||||||
|
inv := &ActorRegistry{actors: make(map[cid.Cid]*actorInfo)}
|
||||||
|
|
||||||
|
// TODO: define all these properties on the actors themselves, in specs-actors.
|
||||||
|
|
||||||
// add builtInCode using: register(cid, singleton)
|
// add builtInCode using: register(cid, singleton)
|
||||||
inv.Register(builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{})
|
inv.Register(actors.Version0, builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{}, true)
|
||||||
inv.Register(builtin0.InitActorCodeID, init0.Actor{}, init0.State{})
|
inv.Register(actors.Version0, builtin0.InitActorCodeID, init0.Actor{}, init0.State{}, true)
|
||||||
inv.Register(builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{})
|
inv.Register(actors.Version0, builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{}, true)
|
||||||
inv.Register(builtin0.CronActorCodeID, cron0.Actor{}, cron0.State{})
|
inv.Register(actors.Version0, builtin0.CronActorCodeID, cron0.Actor{}, cron0.State{}, true)
|
||||||
inv.Register(builtin0.StoragePowerActorCodeID, power0.Actor{}, power0.State{})
|
inv.Register(actors.Version0, builtin0.StoragePowerActorCodeID, power0.Actor{}, power0.State{}, true)
|
||||||
inv.Register(builtin0.StorageMarketActorCodeID, market0.Actor{}, market0.State{})
|
inv.Register(actors.Version0, builtin0.StorageMarketActorCodeID, market0.Actor{}, market0.State{}, true)
|
||||||
inv.Register(builtin0.StorageMinerActorCodeID, miner0.Actor{}, miner0.State{})
|
inv.Register(actors.Version0, builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{}, true)
|
||||||
inv.Register(builtin0.MultisigActorCodeID, msig0.Actor{}, msig0.State{})
|
inv.Register(actors.Version0, builtin0.StorageMinerActorCodeID, miner0.Actor{}, miner0.State{}, false)
|
||||||
inv.Register(builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{})
|
inv.Register(actors.Version0, builtin0.MultisigActorCodeID, msig0.Actor{}, msig0.State{}, false)
|
||||||
inv.Register(builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{})
|
inv.Register(actors.Version0, builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{}, false)
|
||||||
inv.Register(builtin0.AccountActorCodeID, account0.Actor{}, account0.State{})
|
inv.Register(actors.Version0, builtin0.AccountActorCodeID, account0.Actor{}, account0.State{}, false)
|
||||||
|
|
||||||
inv.Register(builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{})
|
inv.Register(actors.Version0, builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}, true)
|
||||||
inv.Register(builtin1.InitActorCodeID, init1.Actor{}, init1.State{})
|
inv.Register(actors.Version0, builtin1.InitActorCodeID, init1.Actor{}, init1.State{}, true)
|
||||||
inv.Register(builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{})
|
inv.Register(actors.Version0, builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}, true)
|
||||||
inv.Register(builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{})
|
inv.Register(actors.Version0, builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}, true)
|
||||||
inv.Register(builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{})
|
inv.Register(actors.Version0, builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}, true)
|
||||||
inv.Register(builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{})
|
inv.Register(actors.Version0, builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}, true)
|
||||||
inv.Register(builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{})
|
inv.Register(actors.Version0, builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}, true)
|
||||||
inv.Register(builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{})
|
inv.Register(actors.Version0, builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}, false)
|
||||||
inv.Register(builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{})
|
inv.Register(actors.Version0, builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}, false)
|
||||||
inv.Register(builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{})
|
inv.Register(actors.Version0, builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}, false)
|
||||||
inv.Register(builtin1.AccountActorCodeID, account1.Actor{}, account1.State{})
|
inv.Register(actors.Version0, builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}, false)
|
||||||
|
|
||||||
return inv
|
return inv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inv *Invoker) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
func (ar *ActorRegistry) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
||||||
|
act, ok := ar.actors[codeCid]
|
||||||
code, ok := inv.builtInCode[codeCid]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Errorf("no code for actor %s (Addr: %s)", codeCid, rt.Receiver())
|
log.Errorf("no code for actor %s (Addr: %s)", codeCid, rt.Receiver())
|
||||||
return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "no code for actor %s(%d)(%s)", codeCid, method, hex.EncodeToString(params))
|
return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "no code for actor %s(%d)(%s)", codeCid, method, hex.EncodeToString(params))
|
||||||
}
|
}
|
||||||
if method >= abi.MethodNum(len(code)) || code[method] == nil {
|
if method >= abi.MethodNum(len(act.methods)) || act.methods[method] == nil {
|
||||||
return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method)
|
return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method)
|
||||||
}
|
}
|
||||||
return code[method](rt, params)
|
if curVer := actors.VersionForNetwork(rt.NetworkVersion()); curVer != act.version {
|
||||||
|
return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "unsupported actors code version %d, expected %d", act.version, curVer)
|
||||||
|
}
|
||||||
|
return act.methods[method](rt, params)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inv *Invoker) Register(c cid.Cid, instance Invokee, state interface{}) {
|
func (ar *ActorRegistry) Register(version actors.Version, c cid.Cid, instance Invokee, state interface{}, singleton bool) {
|
||||||
code, err := inv.transform(instance)
|
code, err := ar.transform(instance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(xerrors.Errorf("%s: %w", string(c.Hash()), err))
|
panic(xerrors.Errorf("%s: %w", string(c.Hash()), err))
|
||||||
}
|
}
|
||||||
inv.builtInCode[c] = code
|
ar.actors[c] = &actorInfo{
|
||||||
inv.builtInState[c] = reflect.TypeOf(state)
|
methods: code,
|
||||||
|
version: version,
|
||||||
|
stateType: reflect.TypeOf(state),
|
||||||
|
singleton: singleton,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ar *ActorRegistry) Create(codeCid cid.Cid, rt vmr.Runtime) (*types.Actor, aerrors.ActorError) {
|
||||||
|
act, ok := ar.actors[codeCid]
|
||||||
|
if !ok {
|
||||||
|
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.")
|
||||||
|
}
|
||||||
|
if version := actors.VersionForNetwork(rt.NetworkVersion()); act.version != version {
|
||||||
|
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create version %d actors, attempted to create version %d actor", version, act.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
if act.singleton {
|
||||||
|
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.")
|
||||||
|
}
|
||||||
|
return &types.Actor{
|
||||||
|
Code: codeCid,
|
||||||
|
Head: EmptyObjectCid,
|
||||||
|
Nonce: 0,
|
||||||
|
Balance: abi.NewTokenAmount(0),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Invokee interface {
|
type Invokee interface {
|
||||||
Exports() []interface{}
|
Exports() []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Invoker) transform(instance Invokee) (nativeCode, error) {
|
func (*ActorRegistry) transform(instance Invokee) (nativeCode, error) {
|
||||||
itype := reflect.TypeOf(instance)
|
itype := reflect.TypeOf(instance)
|
||||||
exports := instance.Exports()
|
exports := instance.Exports()
|
||||||
runtimeType := reflect.TypeOf((*vmr.Runtime)(nil)).Elem()
|
runtimeType := reflect.TypeOf((*vmr.Runtime)(nil)).Elem()
|
||||||
@ -201,19 +235,19 @@ func DecodeParams(b []byte, out interface{}) error {
|
|||||||
return um.UnmarshalCBOR(bytes.NewReader(b))
|
return um.UnmarshalCBOR(bytes.NewReader(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DumpActorState(code cid.Cid, b []byte) (interface{}, error) {
|
func DumpActorState(act *types.Actor, b []byte) (interface{}, error) {
|
||||||
if code == builtin0.AccountActorCodeID { // Account code special case
|
if act.IsAccountActor() { // Account code special case
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
i := NewInvoker() // TODO: register builtins in init block
|
i := NewActorRegistry() // TODO: register builtins in init block
|
||||||
|
|
||||||
typ, ok := i.builtInState[code]
|
actInfo, ok := i.actors[act.Code]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, xerrors.Errorf("state type for actor %s not found", code)
|
return nil, xerrors.Errorf("state type for actor %s not found", act.Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
rv := reflect.New(typ)
|
rv := reflect.New(actInfo.stateType)
|
||||||
um, ok := rv.Interface().(cbg.CBORUnmarshaler)
|
um, ok := rv.Interface().(cbg.CBORUnmarshaler)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, xerrors.New("state type does not implement CBORUnmarshaler")
|
return nil, xerrors.New("state type does not implement CBORUnmarshaler")
|
||||||
|
@ -77,7 +77,7 @@ func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestInvokerBasic(t *testing.T) {
|
func TestInvokerBasic(t *testing.T) {
|
||||||
inv := Invoker{}
|
inv := ActorRegistry{}
|
||||||
code, err := inv.transform(basicContract{})
|
code, err := inv.transform(basicContract{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
@ -6,11 +6,13 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -39,7 +41,7 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aer
|
|||||||
return nil, aerrors.Escalate(err, "registering actor address")
|
return nil, aerrors.Escalate(err, "registering actor address")
|
||||||
}
|
}
|
||||||
|
|
||||||
act, aerr := makeActor(addr)
|
act, aerr := makeActor(actors.VersionForNetwork(rt.NetworkVersion()), addr)
|
||||||
if aerr != nil {
|
if aerr != nil {
|
||||||
return nil, aerr
|
return nil, aerr
|
||||||
}
|
}
|
||||||
@ -54,7 +56,7 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aer
|
|||||||
}
|
}
|
||||||
// call constructor on account
|
// call constructor on account
|
||||||
|
|
||||||
_, aerr = rt.internalSend(builtin.SystemActorAddr, addrID, builtin.MethodsAccount.Constructor, big.Zero(), p)
|
_, aerr = rt.internalSend(builtin0.SystemActorAddr, addrID, builtin0.MethodsAccount.Constructor, big.Zero(), p)
|
||||||
if aerr != nil {
|
if aerr != nil {
|
||||||
return nil, aerrors.Wrap(aerr, "failed to invoke account constructor")
|
return nil, aerrors.Wrap(aerr, "failed to invoke account constructor")
|
||||||
}
|
}
|
||||||
@ -66,12 +68,10 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aer
|
|||||||
return act, nil
|
return act, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeActor(addr address.Address) (*types.Actor, aerrors.ActorError) {
|
func makeActor(ver actors.Version, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||||
switch addr.Protocol() {
|
switch addr.Protocol() {
|
||||||
case address.BLS:
|
case address.BLS, address.SECP256K1:
|
||||||
return NewBLSAccountActor(), nil
|
return newAccountActor(ver), nil
|
||||||
case address.SECP256K1:
|
|
||||||
return NewSecp256k1AccountActor(), nil
|
|
||||||
case address.ID:
|
case address.ID:
|
||||||
return nil, aerrors.Newf(exitcode.SysErrInvalidReceiver, "no actor with given ID: %s", addr)
|
return nil, aerrors.Newf(exitcode.SysErrInvalidReceiver, "no actor with given ID: %s", addr)
|
||||||
case address.Actor:
|
case address.Actor:
|
||||||
@ -81,19 +81,19 @@ func makeActor(addr address.Address) (*types.Actor, aerrors.ActorError) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBLSAccountActor() *types.Actor {
|
func newAccountActor(ver actors.Version) *types.Actor {
|
||||||
|
// TODO: ActorsUpgrade use a global actor registry?
|
||||||
|
var code cid.Cid
|
||||||
|
switch ver {
|
||||||
|
case actors.Version0:
|
||||||
|
code = builtin0.AccountActorCodeID
|
||||||
|
case actors.Version1:
|
||||||
|
code = builtin1.AccountActorCodeID
|
||||||
|
default:
|
||||||
|
panic("unsupported actors version")
|
||||||
|
}
|
||||||
nact := &types.Actor{
|
nact := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: code,
|
||||||
Balance: types.NewInt(0),
|
|
||||||
Head: EmptyObjectCid,
|
|
||||||
}
|
|
||||||
|
|
||||||
return nact
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSecp256k1AccountActor() *types.Actor {
|
|
||||||
nact := &types.Actor{
|
|
||||||
Code: builtin.AccountActorCodeID,
|
|
||||||
Balance: types.NewInt(0),
|
Balance: types.NewInt(0),
|
||||||
Head: EmptyObjectCid,
|
Head: EmptyObjectCid,
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,11 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
rtt "github.com/filecoin-project/go-state-types/rt"
|
rtt "github.com/filecoin-project/go-state-types/rt"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
rt0 "github.com/filecoin-project/specs-actors/actors/runtime"
|
rt0 "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -216,12 +214,9 @@ func (rt *Runtime) NewActorAddress() address.Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
||||||
if !builtin.IsBuiltinActor(codeID) {
|
act, aerr := rt.vm.areg.Create(codeID, rt)
|
||||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.")
|
if aerr != nil {
|
||||||
}
|
rt.Abortf(aerr.RetCode(), aerr.Error())
|
||||||
|
|
||||||
if builtin.IsSingletonActor(codeID) {
|
|
||||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := rt.state.GetActor(address)
|
_, err := rt.state.GetActor(address)
|
||||||
@ -231,12 +226,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
|||||||
|
|
||||||
rt.chargeGas(rt.Pricelist().OnCreateActor())
|
rt.chargeGas(rt.Pricelist().OnCreateActor())
|
||||||
|
|
||||||
err = rt.state.SetActor(address, &types.Actor{
|
err = rt.state.SetActor(address, act)
|
||||||
Code: codeID,
|
|
||||||
Head: EmptyObjectCid,
|
|
||||||
Nonce: 0,
|
|
||||||
Balance: big.Zero(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(aerrors.Fatalf("creating actor entry: %v", err))
|
panic(aerrors.Fatalf("creating actor entry: %v", err))
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ type VM struct {
|
|||||||
cst *cbor.BasicIpldStore
|
cst *cbor.BasicIpldStore
|
||||||
buf *bufbstore.BufferedBS
|
buf *bufbstore.BufferedBS
|
||||||
blockHeight abi.ChainEpoch
|
blockHeight abi.ChainEpoch
|
||||||
inv *Invoker
|
areg *ActorRegistry
|
||||||
rand Rand
|
rand Rand
|
||||||
circSupplyCalc CircSupplyCalculator
|
circSupplyCalc CircSupplyCalculator
|
||||||
ntwkVersion NtwkVersionGetter
|
ntwkVersion NtwkVersionGetter
|
||||||
@ -186,7 +186,7 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
|
|||||||
cst: cst,
|
cst: cst,
|
||||||
buf: buf,
|
buf: buf,
|
||||||
blockHeight: opts.Epoch,
|
blockHeight: opts.Epoch,
|
||||||
inv: NewInvoker(),
|
areg: NewActorRegistry(),
|
||||||
rand: opts.Rand, // TODO: Probably should be a syscall
|
rand: opts.Rand, // TODO: Probably should be a syscall
|
||||||
circSupplyCalc: opts.CircSupplyCalc,
|
circSupplyCalc: opts.CircSupplyCalc,
|
||||||
ntwkVersion: opts.NtwkVersion,
|
ntwkVersion: opts.NtwkVersion,
|
||||||
@ -734,15 +734,15 @@ func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params
|
|||||||
defer func() {
|
defer func() {
|
||||||
rt.ctx = oldCtx
|
rt.ctx = oldCtx
|
||||||
}()
|
}()
|
||||||
ret, err := vm.inv.Invoke(act.Code, rt, method, params)
|
ret, err := vm.areg.Invoke(act.Code, rt, method, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) SetInvoker(i *Invoker) {
|
func (vm *VM) SetInvoker(i *ActorRegistry) {
|
||||||
vm.inv = i
|
vm.areg = i
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version {
|
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"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"
|
||||||
@ -140,11 +141,11 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, preroot cid.Cid, epoch
|
|||||||
return nil, cid.Undef, err
|
return nil, cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
invoker := vm.NewInvoker()
|
invoker := vm.NewActorRegistry()
|
||||||
|
|
||||||
// register the chaos actor if required by the vector.
|
// register the chaos actor if required by the vector.
|
||||||
if chaosOn, ok := d.selector["chaos_actor"]; ok && chaosOn == "true" {
|
if chaosOn, ok := d.selector["chaos_actor"]; ok && chaosOn == "true" {
|
||||||
invoker.Register(chaos.ChaosActorCodeCID, chaos.Actor{}, chaos.State{})
|
invoker.Register(actors.Version0, chaos.ChaosActorCodeCID, chaos.Actor{}, chaos.State{}, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
lvm.SetInvoker(invoker)
|
lvm.SetInvoker(invoker)
|
||||||
|
@ -422,7 +422,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
|
|||||||
return nil, nil, xerrors.Errorf("getting actor head for @state: %w", err)
|
return nil, nil, xerrors.Errorf("getting actor head for @state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := vm.DumpActorState(act.Code, head.RawData())
|
m, err := vm.DumpActorState(&act, head.RawData())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, ts
|
|||||||
return nil, xerrors.Errorf("getting actor head: %w", err)
|
return nil, xerrors.Errorf("getting actor head: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
oif, err := vm.DumpActorState(act.Code, blk.RawData())
|
oif, err := vm.DumpActorState(act, blk.RawData())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("dumping actor state (a:%s): %w", actor, err)
|
return nil, xerrors.Errorf("dumping actor state (a:%s): %w", actor, err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user