bd10bdf99a
* build: Bump version to v1.17.3-dev * build: set version to v1.18.0-dev * 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 * Delete lotus-pond (#9352) * feat: add StateNetworkVersion to mpool API * chore: refactor: rename NewestNetworkVersion * feat: actors: Integrate datacap actor into lotus (#9348) * Integrate datacap actor * Implement datacap actor in chain/builtin * feat: support typed errors over RPC * chore: deps: update to go-jsonrpc 0.1.8 * remove duplicate import * fix: itest: check for closed connection * chore: refactor: move retry test to API * address magik supernit * Add ability to only have single partition per msg for partitions with recovery sectors * doc gen * Address comments * Return beneficiary info from miner state Info() * Update builtin-actors to dev/20220922-v9 which includes FIP-0045 changes in progress * Integrate verifreg changes to lotus * Setup datacap actor * Update builtin-actors to dev/20220922-v9-1 * Update datacap actor to query datacap instead of verifreg * update gst * update markets * update actors with hamt fix * update gst * Update datacap to parse tokens * Update bundles * datacap and verifreg actors use ID addresses without protocol byte * update builtin-actors to rc1 * update go-fil-markets * Update bundles to rc2 * Integrate the v9 migration * Add api for getting allocation * Add upgrade epoch for butterfly * Tweak PreSeal struct to be infra-friendly * docsgen * More tweaking of PreSeal for genesis * review fixes * Use fake cid for test * add butterfly artifacts for oct 5 upgrade * check datacaps for v8 verifreg match v9 datacap actor * Remove print statements * Update to go-state-types master * Update to go-state-types v0.9.0-rc1 * review fixes * use go-fil-markets v1.24.0-v17 * Add accessors for allocations and claims maps * fix: missing permissions tag * butterfly * update butterfly artifacts * sealing pipeline: Prepare deal assigning logic for FIP-45 * sealing pipeline: Get allocationId with StateApi * use NoAllocationID instead of nil AllocationId * address review * Add datacap actor to registry.go * Add cli for listing allocations and removing expired allocations * Update to go-state-types master * deps: upgrade go-merkledag to 0.8.0 * shark params * Update cli/filplus.go Co-authored-by: Aayush Rajasekaran <arajasek94@gmail.com> * revert change to verifreg util * docsgen-cli * miss the stuff * Update FFI * Update go-state-types to v0.9.0 * Update builtin-actors to v9.0.0 * add calib upgrade epcoh * update the upgrade envvar * kill shark * Remove fvm splash banner from nv17 upgrade * check invariance for pending deals and allocations * check pending verified deal proposal migrated to allocation * Add check for unsealed CID in precommit sectors * Fix counting of allocations in nv17 migration test * make gen * pass state trees as pointers * Add assertion that migrations with & without cache are the same * compare allocation to verified deal proposal * Fix miner state precommit info * fix migration test tool * add changelog * Update to go-state-types v0.9.1 * Integrate builtin-actors v9.0.1 * chore: ver: bump version for rc3 (#9512) * Bump version to 1.18.0-rc3 * Update CHANGELOG.md * Update CHANGELOG.md Co-authored-by: Aayush Rajasekaran <arajasek94@gmail.com> * Update CHANGELOG.md Co-authored-by: Aayush Rajasekaran <arajasek94@gmail.com> Co-authored-by: Jiaying Wang <42981373+jennijuju@users.noreply.github.com> Co-authored-by: Aayush Rajasekaran <arajasek94@gmail.com> * Migration: Use autobatch bs * Fix autobatch Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai> * Invoker: Use MethodMeta from go-state-types * Add a second premigration for nv17 * Add more shed tools for migration checking * address review * Lotus release v1.18.0-rc4 * fix: ci: fix app-image build on ci (#9527) * Remove old go version first * Add GO_VERSION file * Use GO_VERSION to set / verify go version * mv GO_VERSION GO_VERSION_MIN * Use GO_VERSION_MIN in Makefile check Co-authored-by: Ian Davis <jungziege@gmail.com> * Update to latest go-state-types for migration fixes * go mod tidy * fix: use api.ErrActorNotFound instead of types.ErrActorNotFound * fix: add fields to ForkUpgradeParams * docs: update actors_version_checklist.md * chore: fix lint * update to go state type v0.9.6 with market migration fix (#9545) * update go-state-types to v-0.9.7 * Add invariant checks to migration * fix invariant check: number of entries in datacap actor should include verifreg * Invariant checks: Only include not-activated deals * test: nv17 migration * Address review * add lotus-shed invariance method * Migration cli takes a stateroot cid and a height * make gen * Update to builtin-actors v9.0.2 * Failing test that shows that notaries can remove datacap from the verifreg actor * Test that should pass when the problem is solved * make gen * Review fixes * statemanager call function will return call information even if call errors * update go-state-types * update builtin-actors * bubble up errors properly from ApplyImplicitMessage * bump to rc5 * set new upgrade heights for calibnet * set new upgrade height for butterfly * tweak calibnet upgrade schedule * clarify changelog note about calibnet * butterfly * update calibnet artifacts * Allow setting local bundles for Debug FVM for av 9+ * fix: autobatch: remove potential deadlock when a block is missing Check the _underlying_ blockstore instead of recursing. Also, drop the lock before we do that. * fix imports * build: set shark mainnet epoch (#9640) * chore: build: Lotus release v1.18.0 (#9641) * Lotus release v1.18.0 * add changelog * address review * changelog improvement Co-authored-by: Jennifer Wang <jiayingw703@gmail.com> Co-authored-by: Jiaying Wang <42981373+jennijuju@users.noreply.github.com> Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai> Co-authored-by: Łukasz Magiera <magik6k@gmail.com> Co-authored-by: Łukasz Magiera <magik6k@users.noreply.github.com> Co-authored-by: Aayush <arajasek94@gmail.com> Co-authored-by: Geoff Stuart <geoff.vball@gmail.com> Co-authored-by: Shrenuj Bansal <shrenuj.bansal@protocol.ai> Co-authored-by: simlecode <69969590+simlecode@users.noreply.github.com> Co-authored-by: Rod Vagg <rod@vagg.org> Co-authored-by: Jakub Sztandera <kubuxu@protocol.ai> Co-authored-by: Ian Davis <jungziege@gmail.com> Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com> Co-authored-by: Steven Allen <steven@stebalien.com>
303 lines
8.2 KiB
Go
303 lines
8.2 KiB
Go
package vm
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"github.com/ipfs/go-cid"
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
|
builtinst "github.com/filecoin-project/go-state-types/builtin"
|
|
"github.com/filecoin-project/go-state-types/exitcode"
|
|
"github.com/filecoin-project/go-state-types/network"
|
|
vmr "github.com/filecoin-project/specs-actors/v7/actors/runtime"
|
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
)
|
|
|
|
type MethodMeta struct {
|
|
Name string
|
|
|
|
Params reflect.Type
|
|
Ret reflect.Type
|
|
}
|
|
|
|
type ActorRegistry struct {
|
|
actors map[cid.Cid]*actorInfo
|
|
|
|
Methods map[cid.Cid]map[abi.MethodNum]MethodMeta
|
|
}
|
|
|
|
// 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, cid.Cid) error
|
|
|
|
func ActorsVersionPredicate(ver actorstypes.Version) ActorPredicate {
|
|
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", codeCid, ver, aver, rt.CurrEpoch(), rt.NetworkVersion())
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError)
|
|
type nativeCode map[uint64]invokeFunc
|
|
|
|
type actorInfo struct {
|
|
methods nativeCode
|
|
vmActor builtin.RegistryEntry
|
|
// TODO: consider making this a network version range?
|
|
predicate ActorPredicate
|
|
}
|
|
|
|
func NewActorRegistry() *ActorRegistry {
|
|
return &ActorRegistry{
|
|
actors: make(map[cid.Cid]*actorInfo),
|
|
Methods: map[cid.Cid]map[abi.MethodNum]MethodMeta{},
|
|
}
|
|
}
|
|
|
|
func (ar *ActorRegistry) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
|
act, ok := ar.actors[codeCid]
|
|
if !ok {
|
|
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, codeCid); err != nil {
|
|
return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "unsupported actor: %s", err)
|
|
}
|
|
if act.methods[uint64(method)] == nil {
|
|
return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method)
|
|
}
|
|
return act.methods[uint64(method)](rt, params)
|
|
|
|
}
|
|
|
|
func (ar *ActorRegistry) Register(av actorstypes.Version, pred ActorPredicate, vmactors []builtin.RegistryEntry) {
|
|
if pred == nil {
|
|
pred = func(vmr.Runtime, cid.Cid) error { return nil }
|
|
}
|
|
for _, a := range vmactors {
|
|
|
|
var code nativeCode
|
|
var err error
|
|
if av <= actorstypes.Version7 {
|
|
// register in the `actors` map (for the invoker)
|
|
code, err = ar.transform(a)
|
|
if err != nil {
|
|
panic(xerrors.Errorf("%s: %w", string(a.Code().Hash()), err))
|
|
}
|
|
}
|
|
|
|
ai := &actorInfo{
|
|
methods: code,
|
|
vmActor: a,
|
|
predicate: pred,
|
|
}
|
|
|
|
ac := a.Code()
|
|
ar.actors[ac] = ai
|
|
|
|
// necessary to make stuff work
|
|
var realCode cid.Cid
|
|
if av >= actorstypes.Version8 {
|
|
name := actors.CanonicalName(builtin.ActorNameByCode(ac))
|
|
|
|
var ok bool
|
|
realCode, ok = actors.GetActorCodeID(av, name)
|
|
if ok {
|
|
ar.actors[realCode] = ai
|
|
}
|
|
}
|
|
|
|
// register in the `Methods` map (used by statemanager utils)
|
|
exports := a.Exports()
|
|
methods := make(map[abi.MethodNum]MethodMeta, len(exports))
|
|
|
|
// Explicitly add send, it's special.
|
|
methods[builtin.MethodSend] = MethodMeta{
|
|
Name: "Send",
|
|
Params: reflect.TypeOf(new(abi.EmptyValue)),
|
|
Ret: reflect.TypeOf(new(abi.EmptyValue)),
|
|
}
|
|
|
|
// Iterate over exported methods. Some of these _may_ be nil and
|
|
// must be skipped.
|
|
for number, export := range exports {
|
|
if export.Method == nil {
|
|
continue
|
|
}
|
|
|
|
ev := reflect.ValueOf(export.Method)
|
|
et := ev.Type()
|
|
|
|
mm := MethodMeta{
|
|
Name: export.Name,
|
|
Ret: et.Out(0),
|
|
}
|
|
|
|
if av <= actorstypes.Version7 {
|
|
// methods exported from specs-actors have the runtime as the first param, so we want et.In(1)
|
|
mm.Params = et.In(1)
|
|
} else {
|
|
// methods exported from go-state-types do not, so we want et.In(0)
|
|
mm.Params = et.In(0)
|
|
}
|
|
|
|
methods[abi.MethodNum(number)] = mm
|
|
}
|
|
if realCode.Defined() {
|
|
ar.Methods[realCode] = methods
|
|
} else {
|
|
ar.Methods[a.Code()] = methods
|
|
}
|
|
}
|
|
}
|
|
|
|
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 err := act.predicate(rt, codeCid); err != nil {
|
|
return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Cannot create actor: %w", err)
|
|
}
|
|
|
|
return &types.Actor{
|
|
Code: codeCid,
|
|
Head: EmptyObjectCid,
|
|
Nonce: 0,
|
|
Balance: abi.NewTokenAmount(0),
|
|
}, nil
|
|
}
|
|
|
|
type invokee interface {
|
|
Exports() map[uint64]builtinst.MethodMeta
|
|
}
|
|
|
|
func (*ActorRegistry) transform(instance invokee) (nativeCode, error) {
|
|
itype := reflect.TypeOf(instance)
|
|
exports := instance.Exports()
|
|
runtimeType := reflect.TypeOf((*vmr.Runtime)(nil)).Elem()
|
|
for i, e := range exports {
|
|
i := i
|
|
m := e.Method
|
|
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 !runtimeType.Implements(t.In(0)) {
|
|
return nil, newErr("first argument should be vmr.Runtime")
|
|
}
|
|
if t.In(1).Kind() != reflect.Ptr {
|
|
return nil, newErr("second argument should be of kind reflect.Ptr")
|
|
}
|
|
|
|
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, e := range exports {
|
|
m := e.Method
|
|
if m == nil {
|
|
continue
|
|
}
|
|
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)
|
|
|
|
rt := in[0].Interface().(*Runtime)
|
|
inBytes := in[1].Interface().([]byte)
|
|
if err := DecodeParams(inBytes, param.Interface()); err != nil {
|
|
ec := exitcode.ErrSerialization
|
|
if rt.NetworkVersion() < network.Version7 {
|
|
ec = 1
|
|
}
|
|
aerr := aerrors.Absorb(err, ec, "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(),
|
|
}
|
|
}
|
|
rval, aerror := rt.shimCall(func() interface{} {
|
|
ret := meth.Call([]reflect.Value{
|
|
reflect.ValueOf(rt),
|
|
param,
|
|
})
|
|
return ret[0].Interface()
|
|
})
|
|
|
|
return []reflect.Value{
|
|
reflect.ValueOf(&rval).Elem(),
|
|
reflect.ValueOf(&aerror).Elem(),
|
|
}
|
|
}).Interface().(invokeFunc)
|
|
|
|
}
|
|
return code, nil
|
|
}
|
|
|
|
func DecodeParams(b []byte, out interface{}) error {
|
|
um, ok := out.(cbg.CBORUnmarshaler)
|
|
if !ok {
|
|
return fmt.Errorf("type %T does not implement UnmarshalCBOR", out)
|
|
}
|
|
|
|
return um.UnmarshalCBOR(bytes.NewReader(b))
|
|
}
|
|
|
|
func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{}, error) {
|
|
if builtin.IsAccountActor(act.Code) { // Account code special case
|
|
return nil, nil
|
|
}
|
|
|
|
actInfo, ok := i.actors[act.Code]
|
|
if !ok {
|
|
return nil, xerrors.Errorf("state type for actor %s not found", act.Code)
|
|
}
|
|
|
|
um := actInfo.vmActor.State()
|
|
if err := um.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
|
return nil, xerrors.Errorf("unmarshaling actor state: %w", err)
|
|
}
|
|
|
|
return um, nil
|
|
}
|