Merge pull request #1211 from filecoin-project/feat/auto-shim
Invoker autoshim
This commit is contained in:
commit
8d1ef188b1
@ -1,8 +1,6 @@
|
|||||||
package actors
|
package actors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,6 +23,15 @@ type musigMethods struct {
|
|||||||
|
|
||||||
var MultiSigMethods = musigMethods{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
var MultiSigMethods = musigMethods{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
|
||||||
|
type MultiSigConstructorParams = samsig.ConstructorParams
|
||||||
|
type MultiSigProposeParams = samsig.ProposeParams
|
||||||
|
type MultiSigTxID = samsig.TxnIDParams
|
||||||
|
type MultiSigAddSignerParam = samsig.AddSigner
|
||||||
|
type MultiSigRemoveSignerParam = samsig.RemoveSigner
|
||||||
|
type MultiSigSwapSignerParams = samsig.SwapSignerParams
|
||||||
|
type MultiSigChangeReqParams = samsig.ChangeNumApprovalsThresholdParams
|
||||||
|
|
||||||
|
/*
|
||||||
func (msa MultiSigActor) Exports() []interface{} {
|
func (msa MultiSigActor) Exports() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
1: msa.MultiSigConstructor,
|
1: msa.MultiSigConstructor,
|
||||||
@ -39,7 +46,7 @@ func (msa MultiSigActor) Exports() []interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigConstructorParams = samsig.ConstructorParams
|
|
||||||
|
|
||||||
func (MultiSigActor) MultiSigConstructor(act *types.Actor, vmctx types.VMContext,
|
func (MultiSigActor) MultiSigConstructor(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigConstructorParams) ([]byte, ActorError) {
|
params *MultiSigConstructorParams) ([]byte, ActorError) {
|
||||||
@ -50,7 +57,6 @@ func (MultiSigActor) MultiSigConstructor(act *types.Actor, vmctx types.VMContext
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigProposeParams = samsig.ProposeParams
|
|
||||||
|
|
||||||
func (msa MultiSigActor) Propose(act *types.Actor, vmctx types.VMContext,
|
func (msa MultiSigActor) Propose(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigProposeParams) ([]byte, ActorError) {
|
params *MultiSigProposeParams) ([]byte, ActorError) {
|
||||||
@ -61,7 +67,6 @@ func (msa MultiSigActor) Propose(act *types.Actor, vmctx types.VMContext,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigTxID = samsig.TxnIDParams
|
|
||||||
|
|
||||||
func (msa MultiSigActor) Approve(act *types.Actor, vmctx types.VMContext,
|
func (msa MultiSigActor) Approve(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigTxID) ([]byte, ActorError) {
|
params *MultiSigTxID) ([]byte, ActorError) {
|
||||||
@ -81,7 +86,6 @@ func (msa MultiSigActor) Cancel(act *types.Actor, vmctx types.VMContext,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigAddSignerParam = samsig.AddSigner
|
|
||||||
|
|
||||||
func (msa MultiSigActor) AddSigner(act *types.Actor, vmctx types.VMContext,
|
func (msa MultiSigActor) AddSigner(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigAddSignerParam) ([]byte, ActorError) {
|
params *MultiSigAddSignerParam) ([]byte, ActorError) {
|
||||||
@ -92,7 +96,6 @@ func (msa MultiSigActor) AddSigner(act *types.Actor, vmctx types.VMContext,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigRemoveSignerParam = samsig.RemoveSigner
|
|
||||||
|
|
||||||
func (msa MultiSigActor) RemoveSigner(act *types.Actor, vmctx types.VMContext,
|
func (msa MultiSigActor) RemoveSigner(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigRemoveSignerParam) ([]byte, ActorError) {
|
params *MultiSigRemoveSignerParam) ([]byte, ActorError) {
|
||||||
@ -103,7 +106,6 @@ func (msa MultiSigActor) RemoveSigner(act *types.Actor, vmctx types.VMContext,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigSwapSignerParams = samsig.SwapSignerParams
|
|
||||||
|
|
||||||
func (msa MultiSigActor) SwapSigner(act *types.Actor, vmctx types.VMContext,
|
func (msa MultiSigActor) SwapSigner(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigSwapSignerParams) ([]byte, ActorError) {
|
params *MultiSigSwapSignerParams) ([]byte, ActorError) {
|
||||||
@ -114,7 +116,6 @@ func (msa MultiSigActor) SwapSigner(act *types.Actor, vmctx types.VMContext,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiSigChangeReqParams = samsig.ChangeNumApprovalsThresholdParams
|
|
||||||
|
|
||||||
func (msa MultiSigActor) ChangeRequirement(act *types.Actor, vmctx types.VMContext,
|
func (msa MultiSigActor) ChangeRequirement(act *types.Actor, vmctx types.VMContext,
|
||||||
params *MultiSigChangeReqParams) ([]byte, ActorError) {
|
params *MultiSigChangeReqParams) ([]byte, ActorError) {
|
||||||
@ -124,3 +125,4 @@ func (msa MultiSigActor) ChangeRequirement(act *types.Actor, vmctx types.VMConte
|
|||||||
return (&samsig.MultiSigActor{}).ChangeNumApprovalsThreshold(shim, params)
|
return (&samsig.MultiSigActor{}).ChangeNumApprovalsThreshold(shim, params)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -13,6 +14,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"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"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type invoker struct {
|
type invoker struct {
|
||||||
@ -36,7 +39,7 @@ func NewInvoker() *invoker {
|
|||||||
inv.Register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
inv.Register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
||||||
inv.Register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
inv.Register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
||||||
inv.Register(actors.StorageMiner2CodeCid, actors.StorageMinerActor2{}, actors.StorageMinerActorState{})
|
inv.Register(actors.StorageMiner2CodeCid, actors.StorageMinerActor2{}, actors.StorageMinerActorState{})
|
||||||
inv.Register(actors.MultisigCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
|
inv.Register(actors.MultisigCodeCid, multisig.MultiSigActor{}, multisig.MultiSigActorState{})
|
||||||
inv.Register(actors.PaymentChannelCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
|
inv.Register(actors.PaymentChannelCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
|
||||||
|
|
||||||
return inv
|
return inv
|
||||||
@ -76,7 +79,96 @@ type Invokee interface {
|
|||||||
var tVMContext = reflect.TypeOf((*types.VMContext)(nil)).Elem()
|
var tVMContext = reflect.TypeOf((*types.VMContext)(nil)).Elem()
|
||||||
var tAError = reflect.TypeOf((*aerrors.ActorError)(nil)).Elem()
|
var tAError = reflect.TypeOf((*aerrors.ActorError)(nil)).Elem()
|
||||||
|
|
||||||
func (*invoker) transform(instance Invokee) (nativeCode, error) {
|
func (i *invoker) transform(instance Invokee) (nativeCode, error) {
|
||||||
|
itype := reflect.TypeOf(instance)
|
||||||
|
if strings.Contains(itype.PkgPath(), "github.com/filecoin-project/specs-actors/") {
|
||||||
|
return i.transformSpec(instance)
|
||||||
|
} else {
|
||||||
|
return i.transformLotus(instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*invoker) transformSpec(instance Invokee) (nativeCode, error) {
|
||||||
|
itype := reflect.TypeOf(instance)
|
||||||
|
exports := instance.Exports()
|
||||||
|
for i, m := range exports {
|
||||||
|
i := i
|
||||||
|
newErr := func(format string, args ...interface{}) error {
|
||||||
|
str := fmt.Sprintf(format, args...)
|
||||||
|
return fmt.Errorf("transform(%s) export(%d): %s", itype.Name(), i, str)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
meth := reflect.ValueOf(m)
|
||||||
|
t := meth.Type()
|
||||||
|
if t.Kind() != reflect.Func {
|
||||||
|
return nil, newErr("is not a function")
|
||||||
|
}
|
||||||
|
if t.NumIn() != 2 {
|
||||||
|
return nil, newErr("wrong number of inputs should be: " +
|
||||||
|
"vmr.Runtime, <parameter>")
|
||||||
|
}
|
||||||
|
if t.In(0) != reflect.TypeOf((*vmr.Runtime)(nil)).Elem() {
|
||||||
|
return nil, newErr("first arguemnt should be vmr.Runtime")
|
||||||
|
}
|
||||||
|
if t.In(1).Kind() != reflect.Ptr {
|
||||||
|
return nil, newErr("second argument should be types.VMContext")
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.NumOut() != 1 {
|
||||||
|
return nil, newErr("wrong number of outputs should be: " +
|
||||||
|
"cbg.CBORMarshaler")
|
||||||
|
}
|
||||||
|
o0 := t.Out(0)
|
||||||
|
if !o0.Implements(reflect.TypeOf((*cbg.CBORMarshaler)(nil)).Elem()) {
|
||||||
|
return nil, newErr("output needs to implement cgb.CBORMarshaler")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code := make(nativeCode, len(exports))
|
||||||
|
for id, m := range exports {
|
||||||
|
meth := reflect.ValueOf(m)
|
||||||
|
code[id] = reflect.MakeFunc(reflect.TypeOf((invokeFunc)(nil)),
|
||||||
|
func(in []reflect.Value) []reflect.Value {
|
||||||
|
paramT := meth.Type().In(1).Elem()
|
||||||
|
param := reflect.New(paramT)
|
||||||
|
|
||||||
|
inBytes := in[2].Interface().([]byte)
|
||||||
|
if len(inBytes) > 0 {
|
||||||
|
if err := DecodeParams(inBytes, param.Interface()); err != nil {
|
||||||
|
aerr := aerrors.Absorb(err, 1, "failed to decode parameters")
|
||||||
|
return []reflect.Value{
|
||||||
|
reflect.ValueOf([]byte{}),
|
||||||
|
// Below is a hack, fixed in Go 1.13
|
||||||
|
// https://git.io/fjXU6
|
||||||
|
reflect.ValueOf(&aerr).Elem(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shim := &runtimeShim{vmctx: in[1].Interface().(*VMContext)}
|
||||||
|
rval, aerror := shim.shimCall(func() interface{} {
|
||||||
|
ret := meth.Call([]reflect.Value{
|
||||||
|
reflect.ValueOf(shim),
|
||||||
|
param,
|
||||||
|
})
|
||||||
|
return ret[0].Interface()
|
||||||
|
})
|
||||||
|
|
||||||
|
return []reflect.Value{
|
||||||
|
reflect.ValueOf(&rval).Elem(),
|
||||||
|
reflect.ValueOf(&aerror).Elem(),
|
||||||
|
}
|
||||||
|
}).Interface().(invokeFunc)
|
||||||
|
|
||||||
|
}
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*invoker) transformLotus(instance Invokee) (nativeCode, error) {
|
||||||
itype := reflect.TypeOf(instance)
|
itype := reflect.TypeOf(instance)
|
||||||
exports := instance.Exports()
|
exports := instance.Exports()
|
||||||
for i, m := range exports {
|
for i, m := range exports {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package actors
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"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"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
@ -21,10 +22,10 @@ type runtimeShim struct {
|
|||||||
vmr.Runtime
|
vmr.Runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *runtimeShim) shimCall(f func() interface{}) (rval []byte, aerr ActorError) {
|
func (rs *runtimeShim) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
if ar, ok := r.(ActorError); ok {
|
if ar, ok := r.(aerrors.ActorError); ok {
|
||||||
aerr = ar
|
aerr = ar
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -169,7 +170,7 @@ func (ssh *shimStateHandle) Construct(f func() vmr.CBORMarshaler) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := ssh.rs.vmctx.Storage().Commit(EmptyCBOR, c); err != nil {
|
if err := ssh.rs.vmctx.Storage().Commit(actors.EmptyCBOR, c); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user