chore: actors: Allow builtin-actors to return a map of methods (#9342)
* Allow builtin-actors to return a map of methods * go mod * Fix tests * Fix tests, check carefully please
This commit is contained in:
parent
99db94f476
commit
94add978b0
@ -32,19 +32,17 @@ 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
|
||||
}
|
||||
|
||||
@ -52,11 +50,29 @@ 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 {
|
||||
|
@ -23,19 +23,17 @@ 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
|
||||
}
|
||||
|
||||
@ -43,11 +41,29 @@ 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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ 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"
|
||||
@ -27,6 +28,7 @@ import (
|
||||
"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"
|
||||
@ -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)
|
||||
@ -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)
|
||||
@ -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)
|
||||
|
@ -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"
|
||||
@ -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
|
||||
}
|
||||
@ -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)
|
||||
@ -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),
|
||||
}
|
||||
@ -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,
|
||||
@ -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) {
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
@ -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)
|
||||
|
2
go.mod
2
go.mod
@ -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
|
||||
|
4
go.sum
4
go.sum
@ -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=
|
||||
|
Loading…
Reference in New Issue
Block a user