Skip to content

Commit

Permalink
chore: actors: Allow builtin-actors to return a map of methods (#9342)
Browse files Browse the repository at this point in the history
* Allow builtin-actors to return a map of methods

* go mod

* Fix tests

* Fix tests, check carefully please
  • Loading branch information
geoff-vball authored Sep 21, 2022
1 parent 99db94f commit 94add97
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 58 deletions.
28 changes: 22 additions & 6 deletions chain/actors/builtin/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,47 @@ import (
"github.com/filecoin-project/lotus/chain/actors"
)

var _ rtt.VMActor = (*RegistryEntry)(nil)

type RegistryEntry struct {
state cbor.Er
code cid.Cid
methods []interface{}
methods map[uint64]interface{}
}

func (r RegistryEntry) State() cbor.Er {
return r.state
}

func (r RegistryEntry) Exports() []interface{} {
func (r RegistryEntry) Exports() map[uint64]interface{} {
return r.methods
}

func (r RegistryEntry) Code() cid.Cid {
return r.code
}

func MakeRegistry(av actorstypes.Version) []rtt.VMActor {
func MakeRegistryLegacy(actors []rtt.VMActor) []RegistryEntry {
registry := make([]RegistryEntry, 0)

for _, actor := range actors {
methodMap := make(map[uint64]interface{})
for methodNum, method := range actor.Exports() {
methodMap[uint64(methodNum)] = method
}
registry = append(registry, RegistryEntry{
code: actor.Code(),
methods: methodMap,
state: actor.State(),
})
}

return registry
}

func MakeRegistry(av actorstypes.Version) []RegistryEntry {
if av < actorstypes.Version8 {
panic("expected version v8 and up only, use specs-actors for v0-7")
}
registry := make([]rtt.VMActor, 0)
registry := make([]RegistryEntry, 0)

codeIDs, err := actors.GetActorCodeIDs(av)
if err != nil {
Expand Down
28 changes: 22 additions & 6 deletions chain/actors/builtin/registry.go.template
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,47 @@ import (
"github.com/filecoin-project/lotus/chain/actors"
)

var _ rtt.VMActor = (*RegistryEntry)(nil)

type RegistryEntry struct {
state cbor.Er
code cid.Cid
methods []interface{}
methods map[uint64]interface{}
}

func (r RegistryEntry) State() cbor.Er {
return r.state
}

func (r RegistryEntry) Exports() []interface{} {
func (r RegistryEntry) Exports() map[uint64]interface{} {
return r.methods
}

func (r RegistryEntry) Code() cid.Cid {
return r.code
}

func MakeRegistry(av actorstypes.Version) []rtt.VMActor {
func MakeRegistryLegacy(actors []rtt.VMActor) []RegistryEntry {
registry := make([]RegistryEntry, 0)

for _, actor := range actors {
methodMap := make(map[uint64]interface{})
for methodNum, method := range actor.Exports() {
methodMap[uint64(methodNum)] = method
}
registry = append(registry, RegistryEntry{
code: actor.Code(),
methods: methodMap,
state: actor.State(),
})
}

return registry
}

func MakeRegistry(av actorstypes.Version) []RegistryEntry {
if av < actorstypes.Version8 {
panic("expected version v8 and up only, use specs-actors for v0-7")
}
registry := make([]rtt.VMActor, 0)
registry := make([]RegistryEntry, 0)

codeIDs, err := actors.GetActorCodeIDs(av)
if err != nil {
Expand Down
18 changes: 9 additions & 9 deletions chain/consensus/filcns/compute_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ import (
func NewActorRegistry() *vm.ActorRegistry {
inv := vm.NewActorRegistry()

inv.Register(actorstypes.Version0, vm.ActorsVersionPredicate(actorstypes.Version0), exported0.BuiltinActors()...)
inv.Register(actorstypes.Version2, vm.ActorsVersionPredicate(actorstypes.Version2), exported2.BuiltinActors()...)
inv.Register(actorstypes.Version3, vm.ActorsVersionPredicate(actorstypes.Version3), exported3.BuiltinActors()...)
inv.Register(actorstypes.Version4, vm.ActorsVersionPredicate(actorstypes.Version4), exported4.BuiltinActors()...)
inv.Register(actorstypes.Version5, vm.ActorsVersionPredicate(actorstypes.Version5), exported5.BuiltinActors()...)
inv.Register(actorstypes.Version6, vm.ActorsVersionPredicate(actorstypes.Version6), exported6.BuiltinActors()...)
inv.Register(actorstypes.Version7, vm.ActorsVersionPredicate(actorstypes.Version7), exported7.BuiltinActors()...)
inv.Register(actorstypes.Version8, vm.ActorsVersionPredicate(actorstypes.Version8), builtin.MakeRegistry(actorstypes.Version8)...)
inv.Register(actorstypes.Version9, vm.ActorsVersionPredicate(actorstypes.Version9), builtin.MakeRegistry(actorstypes.Version9)...)
inv.Register(actorstypes.Version0, vm.ActorsVersionPredicate(actorstypes.Version0), builtin.MakeRegistryLegacy(exported0.BuiltinActors()))
inv.Register(actorstypes.Version2, vm.ActorsVersionPredicate(actorstypes.Version2), builtin.MakeRegistryLegacy(exported2.BuiltinActors()))
inv.Register(actorstypes.Version3, vm.ActorsVersionPredicate(actorstypes.Version3), builtin.MakeRegistryLegacy(exported3.BuiltinActors()))
inv.Register(actorstypes.Version4, vm.ActorsVersionPredicate(actorstypes.Version4), builtin.MakeRegistryLegacy(exported4.BuiltinActors()))
inv.Register(actorstypes.Version5, vm.ActorsVersionPredicate(actorstypes.Version5), builtin.MakeRegistryLegacy(exported5.BuiltinActors()))
inv.Register(actorstypes.Version6, vm.ActorsVersionPredicate(actorstypes.Version6), builtin.MakeRegistryLegacy(exported6.BuiltinActors()))
inv.Register(actorstypes.Version7, vm.ActorsVersionPredicate(actorstypes.Version7), builtin.MakeRegistryLegacy(exported7.BuiltinActors()))
inv.Register(actorstypes.Version8, vm.ActorsVersionPredicate(actorstypes.Version8), builtin.MakeRegistry(actorstypes.Version8))
inv.Register(actorstypes.Version9, vm.ActorsVersionPredicate(actorstypes.Version9), builtin.MakeRegistry(actorstypes.Version9))

return inv
}
Expand Down
11 changes: 8 additions & 3 deletions chain/stmgr/forks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import (
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/go-state-types/network"
rtt "github.com/filecoin-project/go-state-types/rt"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
rt2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/actors/builtin"
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/consensus/filcns"
Expand Down Expand Up @@ -168,7 +170,8 @@ func TestForkHeightTriggers(t *testing.T) {
}

inv := filcns.NewActorRegistry()
inv.Register(actorstypes.Version0, nil, testActor{})
registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
inv.Register(actorstypes.Version0, nil, registry)

sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
nvm, err := vm.NewLegacyVM(ctx, vmopt)
Expand Down Expand Up @@ -285,7 +288,8 @@ func testForkRefuseCall(t *testing.T, nullsBefore, nullsAfter int) {
}

inv := filcns.NewActorRegistry()
inv.Register(actorstypes.Version0, nil, testActor{})
registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
inv.Register(actorstypes.Version0, nil, registry)

sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
nvm, err := vm.NewLegacyVM(ctx, vmopt)
Expand Down Expand Up @@ -506,7 +510,8 @@ func TestForkPreMigration(t *testing.T) {
}()

inv := filcns.NewActorRegistry()
inv.Register(actorstypes.Version0, nil, testActor{})
registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
inv.Register(actorstypes.Version0, nil, registry)

sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
nvm, err := vm.NewLegacyVM(ctx, vmopt)
Expand Down
30 changes: 13 additions & 17 deletions chain/vm/invoker.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/go-state-types/network"
rtt "github.com/filecoin-project/go-state-types/rt"
vmr "github.com/filecoin-project/specs-actors/v7/actors/runtime"

"github.com/filecoin-project/lotus/chain/actors"
Expand All @@ -38,27 +37,27 @@ type ActorRegistry struct {
}

// An ActorPredicate returns an error if the given actor is not valid for the given runtime environment (e.g., chain height, version, etc.).
type ActorPredicate func(vmr.Runtime, rtt.VMActor) error
type ActorPredicate func(vmr.Runtime, cid.Cid) error

func ActorsVersionPredicate(ver actorstypes.Version) ActorPredicate {
return func(rt vmr.Runtime, v rtt.VMActor) error {
return func(rt vmr.Runtime, codeCid cid.Cid) error {
aver, err := actorstypes.VersionForNetwork(rt.NetworkVersion())
if err != nil {
return xerrors.Errorf("unsupported network version: %w", err)
}
if aver != ver {
return xerrors.Errorf("actor %s is a version %d actor; chain only supports actor version %d at height %d and nver %d", v.Code(), ver, aver, rt.CurrEpoch(), rt.NetworkVersion())
return xerrors.Errorf("actor %s is a version %d actor; chain only supports actor version %d at height %d and nver %d", codeCid, ver, aver, rt.CurrEpoch(), rt.NetworkVersion())
}
return nil
}
}

type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError)
type nativeCode []invokeFunc
type nativeCode map[uint64]invokeFunc

type actorInfo struct {
methods nativeCode
vmActor rtt.VMActor
vmActor builtin.RegistryEntry
// TODO: consider making this a network version range?
predicate ActorPredicate
}
Expand All @@ -76,19 +75,19 @@ func (ar *ActorRegistry) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.Meth
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))
}
if err := act.predicate(rt, act.vmActor); err != nil {
if err := act.predicate(rt, codeCid); err != nil {
return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "unsupported actor: %s", err)
}
if method >= abi.MethodNum(len(act.methods)) || act.methods[method] == nil {
if act.methods[uint64(method)] == nil {
return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method)
}
return act.methods[method](rt, params)
return act.methods[uint64(method)](rt, params)

}

func (ar *ActorRegistry) Register(av actorstypes.Version, pred ActorPredicate, vmactors ...rtt.VMActor) {
func (ar *ActorRegistry) Register(av actorstypes.Version, pred ActorPredicate, vmactors []builtin.RegistryEntry) {
if pred == nil {
pred = func(vmr.Runtime, rtt.VMActor) error { return nil }
pred = func(vmr.Runtime, cid.Cid) error { return nil }
}
for _, a := range vmactors {
// register in the `actors` map (for the invoker)
Expand Down Expand Up @@ -140,7 +139,7 @@ func (ar *ActorRegistry) Register(av actorstypes.Version, pred ActorPredicate, v
et := ev.Type()

methods[abi.MethodNum(number)] = MethodMeta{
Num: strconv.Itoa(number),
Num: strconv.Itoa(int(number)),
Params: et.In(1),
Ret: et.Out(0),
}
Expand All @@ -159,13 +158,10 @@ func (ar *ActorRegistry) Create(codeCid cid.Cid, rt vmr.Runtime) (*types.Actor,
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.")
}

if err := act.predicate(rt, act.vmActor); err != nil {
if err := act.predicate(rt, codeCid); err != nil {
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Cannot create actor: %w", err)
}

if rtt.IsSingletonActor(act.vmActor) {
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.")
}
return &types.Actor{
Code: codeCid,
Head: EmptyObjectCid,
Expand All @@ -175,7 +171,7 @@ func (ar *ActorRegistry) Create(codeCid cid.Cid, rt vmr.Runtime) (*types.Actor,
}

type invokee interface {
Exports() []interface{}
Exports() map[uint64]interface{}
}

func (*ActorRegistry) transform(instance invokee) (nativeCode, error) {
Expand Down
26 changes: 13 additions & 13 deletions chain/vm/invoker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@ func init() {
cbor.RegisterCborType(basicParams{})
}

func (b basicContract) Exports() []interface{} {
return []interface{}{
b.InvokeSomething0,
b.BadParam,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
b.InvokeSomething10,
func (b basicContract) Exports() map[uint64]interface{} {
return map[uint64]interface{}{
0: b.InvokeSomething0,
1: b.BadParam,
2: nil,
3: nil,
4: nil,
5: nil,
6: nil,
7: nil,
8: nil,
9: nil,
10: b.InvokeSomething10,
}
}

Expand Down
5 changes: 4 additions & 1 deletion conformance/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
rtt "github.com/filecoin-project/go-state-types/rt"
"github.com/filecoin-project/test-vectors/schema"

"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/consensus/filcns"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr"
Expand Down Expand Up @@ -250,7 +252,8 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, params ExecuteMessageP
// register the chaos actor if required by the vector.
if chaosOn, ok := d.selector["chaos_actor"]; ok && chaosOn == "true" {
av, _ := actorstypes.VersionForNetwork(params.NetworkVersion)
invoker.Register(av, nil, chaos.Actor{})
registry := builtin.MakeRegistryLegacy([]rtt.VMActor{chaos.Actor{}})
invoker.Register(av, nil, registry)
}

lvm.SetInvoker(invoker)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ require (
github.com/filecoin-project/go-legs v0.4.4
github.com/filecoin-project/go-padreader v0.0.1
github.com/filecoin-project/go-paramfetch v0.0.4
github.com/filecoin-project/go-state-types v0.1.12-beta
github.com/filecoin-project/go-state-types v0.1.12-beta.0.20220920181425-d683559e386b
github.com/filecoin-project/go-statemachine v1.0.2
github.com/filecoin-project/go-statestore v0.2.0
github.com/filecoin-project/go-storedcounter v0.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS
github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
github.com/filecoin-project/go-state-types v0.1.8/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
github.com/filecoin-project/go-state-types v0.1.12-beta h1:QZE00g75shqwhPn0/bZL38sFxVAqnXC7zjmYltRdhxI=
github.com/filecoin-project/go-state-types v0.1.12-beta/go.mod h1:n/kujdC9JphvYTrmaD1+vJpvDPy/DwzckoMzP0nBKWI=
github.com/filecoin-project/go-state-types v0.1.12-beta.0.20220920181425-d683559e386b h1:s4F3e3EBo56j+4xmrzmoAIvtgvDwLn4nsIf5bqcU0Qg=
github.com/filecoin-project/go-state-types v0.1.12-beta.0.20220920181425-d683559e386b/go.mod h1:n/kujdC9JphvYTrmaD1+vJpvDPy/DwzckoMzP0nBKWI=
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc=
github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54=
Expand Down

0 comments on commit 94add97

Please sign in to comment.