Fix vm build

This commit is contained in:
Łukasz Magiera 2020-09-14 13:45:20 +02:00
parent 38f87981c1
commit 68097132fe
6 changed files with 99 additions and 122 deletions

View File

@ -6,8 +6,6 @@ import (
"encoding/json"
"fmt"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
cbor "github.com/ipfs/go-ipld-cbor"
@ -19,6 +17,7 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/account"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
@ -406,8 +405,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
var sum abi.PaddedPieceSize
nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion {
return runtime.NetworkVersion1
nwv := func(context.Context, abi.ChainEpoch) network.Version {
return network.Version1
}
vmopt := vm.VMOpts{

View File

@ -61,8 +61,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
return big.Zero(), nil
}
nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion {
return runtime.NetworkVersion1
nwv := func(context.Context, abi.ChainEpoch) network.Version {
return network.Version1
}
vmopt := &vm.VMOpts{

View File

@ -5,11 +5,22 @@ import (
"fmt"
"sync"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
@ -19,20 +30,6 @@ import (
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"golang.org/x/xerrors"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/trace"
)
var log = logging.Logger("statemgr")
@ -1126,14 +1123,14 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
return csi.FilCirculating, nil
}
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) runtime.NetworkVersion {
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
if build.UpgradeBreezeHeight == 0 {
return runtime.NetworkVersion1
return network.Version1
}
if height <= build.UpgradeBreezeHeight {
return runtime.NetworkVersion0
return network.Version0
}
return runtime.NetworkVersion1
return network.Version1
}

View File

@ -15,6 +15,7 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
@ -27,9 +28,6 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin/system"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
)
type Invoker struct {
@ -48,7 +46,7 @@ func NewInvoker() *Invoker {
// add builtInCode using: register(cid, singleton)
// NETUPGRADE: register code IDs for v2, etc.
inv.Register(builtin.SystemActorCodeID, system.Actor{}, adt.EmptyValue{})
inv.Register(builtin.SystemActorCodeID, system.Actor{}, abi.EmptyValue{})
inv.Register(builtin.InitActorCodeID, init_.Actor{}, init_.State{})
inv.Register(builtin.RewardActorCodeID, reward.Actor{}, reward.State{})
inv.Register(builtin.CronActorCodeID, cron.Actor{}, cron.State{})
@ -67,7 +65,7 @@ func (inv *Invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.Metho
code, ok := inv.builtInCode[codeCid]
if !ok {
log.Errorf("no code for actor %s (Addr: %s)", codeCid, rt.Message().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))
}
if method >= abi.MethodNum(len(code)) || code[method] == nil {

View File

@ -8,21 +8,24 @@ import (
gruntime "runtime"
"time"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
statecbor "github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/go-state-types/crypto"
"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"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/state"
@ -34,15 +37,15 @@ type Runtime struct {
vm *VM
state *state.StateTree
vmsg vmr.Message
height abi.ChainEpoch
cst cbor.IpldStore
pricelist Pricelist
vmr.Message
gasAvailable int64
gasUsed int64
sys runtime.Syscalls
runtime.Syscalls
// address that started invoke chain
origin address.Address
@ -56,7 +59,7 @@ type Runtime struct {
lastGasCharge *types.GasTrace
}
func (rt *Runtime) NetworkVersion() vmr.NetworkVersion {
func (rt *Runtime) NetworkVersion() network.Version {
return rt.vm.GetNtwkVersion(rt.ctx, rt.CurrEpoch())
}
@ -84,7 +87,7 @@ type notFoundErr interface {
IsNotFound() bool
}
func (rt *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
func (rt *Runtime) StoreGet(c cid.Cid, o statecbor.Unmarshaler) bool {
if err := rt.cst.Get(context.TODO(), c, o); err != nil {
var nfe notFoundErr
if xerrors.As(err, &nfe) && nfe.IsNotFound() {
@ -99,7 +102,7 @@ func (rt *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
return true
}
func (rt *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
func (rt *Runtime) StorePut(x statecbor.Marshaler) cid.Cid {
c, err := rt.cst.Put(context.TODO(), x)
if err != nil {
if xerrors.As(err, new(cbor.SerializationError)) {
@ -136,7 +139,7 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
switch ret := ret.(type) {
case []byte:
return ret, nil
case *adt.EmptyValue:
case *abi.EmptyValue:
return nil, nil
case cbg.CBORMarshaler:
buf := new(bytes.Buffer)
@ -151,17 +154,13 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
}
}
func (rt *Runtime) Message() vmr.Message {
return rt.vmsg
}
func (rt *Runtime) ValidateImmediateCallerAcceptAny() {
rt.abortIfAlreadyValidated()
return
}
func (rt *Runtime) CurrentBalance() abi.TokenAmount {
b, err := rt.GetBalance(rt.Message().Receiver())
b, err := rt.GetBalance(rt.Receiver())
if err != nil {
rt.Abortf(err.RetCode(), "get current balance: %v", err)
}
@ -257,7 +256,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
// May only be called by the actor itself.
func (rt *Runtime) DeleteActor(beneficiary address.Address) {
rt.chargeGas(rt.Pricelist().OnDeleteActor())
act, err := rt.state.GetActor(rt.Message().Receiver())
act, err := rt.state.GetActor(rt.Receiver())
if err != nil {
if xerrors.Is(err, types.ErrActorNotFound) {
rt.Abortf(exitcode.SysErrorIllegalActor, "failed to load actor in delete actor: %s", err)
@ -266,36 +265,32 @@ func (rt *Runtime) DeleteActor(beneficiary address.Address) {
}
if !act.Balance.IsZero() {
// Transfer the executing actor's balance to the beneficiary
if err := rt.vm.transfer(rt.Message().Receiver(), beneficiary, act.Balance); err != nil {
if err := rt.vm.transfer(rt.Receiver(), beneficiary, act.Balance); err != nil {
panic(aerrors.Fatalf("failed to transfer balance to beneficiary actor: %s", err))
}
}
// Delete the executing actor
if err := rt.state.DeleteActor(rt.Message().Receiver()); err != nil {
if err := rt.state.DeleteActor(rt.Receiver()); err != nil {
panic(aerrors.Fatalf("failed to delete actor: %s", err))
}
_ = rt.chargeGasSafe(gasOnActorExec)
}
func (rt *Runtime) Syscalls() vmr.Syscalls {
return rt.sys
}
func (rt *Runtime) StartSpan(name string) vmr.TraceSpan {
func (rt *Runtime) StartSpan(name string) func() {
panic("implement me")
}
func (rt *Runtime) ValidateImmediateCallerIs(as ...address.Address) {
rt.abortIfAlreadyValidated()
imm := rt.Message().Caller()
imm := rt.Caller()
for _, a := range as {
if imm == a {
return
}
}
rt.Abortf(exitcode.SysErrForbidden, "caller %s is not one of %s", rt.Message().Caller(), as)
rt.Abortf(exitcode.SysErrForbidden, "caller %s is not one of %s", rt.Caller(), as)
}
func (rt *Runtime) Context() context.Context {
@ -313,7 +308,7 @@ func (rt *Runtime) AbortStateMsg(msg string) {
func (rt *Runtime) ValidateImmediateCallerType(ts ...cid.Cid) {
rt.abortIfAlreadyValidated()
callerCid, ok := rt.GetActorCodeCID(rt.Message().Caller())
callerCid, ok := rt.GetActorCodeCID(rt.Caller())
if !ok {
panic(aerrors.Fatalf("failed to lookup code cid for caller"))
}
@ -329,15 +324,7 @@ func (rt *Runtime) CurrEpoch() abi.ChainEpoch {
return rt.height
}
type dumbWrapperType struct {
val []byte
}
func (dwt *dumbWrapperType) Into(um vmr.CBORUnmarshaler) error {
return um.UnmarshalCBOR(bytes.NewReader(dwt.val))
}
func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) {
func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m statecbor.Marshaler, value abi.TokenAmount, out statecbor.Er) exitcode.ExitCode {
if !rt.allowInternal {
rt.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed")
}
@ -350,16 +337,22 @@ func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars
params = buf.Bytes()
}
ret, err := rt.internalSend(rt.Message().Receiver(), to, method, value, params)
ret, err := rt.internalSend(rt.Receiver(), to, method, value, params)
if err != nil {
if err.IsFatal() {
panic(err)
}
log.Warnf("vmctx send failed: to: %s, method: %d: ret: %d, err: %s", to, method, ret, err)
return &dumbWrapperType{nil}, err.RetCode()
return err.RetCode()
}
_ = rt.chargeGasSafe(gasOnActorExec)
return &dumbWrapperType{ret}, 0
if err := out.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
// REVIEW: always fatal?
panic(err)
}
return 0
}
func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) {
@ -398,54 +391,46 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum,
if subrt != nil {
rt.numActorsCreated = subrt.numActorsCreated
rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace)
}
rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace)
return ret, errSend
}
func (rt *Runtime) State() vmr.StateHandle {
return &shimStateHandle{rt: rt}
}
type shimStateHandle struct {
rt *Runtime
}
func (ssh *shimStateHandle) Create(obj vmr.CBORMarshaler) {
c := ssh.rt.Put(obj)
err := ssh.rt.stateCommit(EmptyObjectCid, c)
func (rt *Runtime) StateCreate(obj statecbor.Marshaler) {
c := rt.StorePut(obj)
err := rt.stateCommit(EmptyObjectCid, c)
if err != nil {
panic(fmt.Errorf("failed to commit state after creating object: %w", err))
}
}
func (ssh *shimStateHandle) Readonly(obj vmr.CBORUnmarshaler) {
act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver())
func (rt *Runtime) StateReadonly(obj statecbor.Unmarshaler) {
act, err := rt.state.GetActor(rt.Receiver())
if err != nil {
ssh.rt.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err)
rt.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err)
}
ssh.rt.Get(act.Head, obj)
rt.StoreGet(act.Head, obj)
}
func (ssh *shimStateHandle) Transaction(obj vmr.CBORer, f func()) {
func (rt *Runtime) StateTransaction(obj statecbor.Er, f func()) {
if obj == nil {
ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()")
rt.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()")
}
act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver())
act, err := rt.state.GetActor(rt.Receiver())
if err != nil {
ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err)
rt.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err)
}
baseState := act.Head
ssh.rt.Get(baseState, obj)
rt.StoreGet(baseState, obj)
ssh.rt.allowInternal = false
rt.allowInternal = false
f()
ssh.rt.allowInternal = true
rt.allowInternal = true
c := ssh.rt.Put(obj)
c := rt.StorePut(obj)
err = ssh.rt.stateCommit(baseState, c)
err = rt.stateCommit(baseState, c)
if err != nil {
panic(fmt.Errorf("failed to commit state after transaction: %w", err))
}
@ -465,7 +450,7 @@ func (rt *Runtime) GetBalance(a address.Address) (types.BigInt, aerrors.ActorErr
func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError {
// TODO: we can make this more efficient in the future...
act, err := rt.state.GetActor(rt.Message().Receiver())
act, err := rt.state.GetActor(rt.Receiver())
if err != nil {
return aerrors.Escalate(err, "failed to get actor to commit state")
}
@ -476,7 +461,7 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError {
act.Head = newh
if err := rt.state.SetActor(rt.Message().Receiver(), act); err != nil {
if err := rt.state.SetActor(rt.Receiver(), act); err != nil {
return aerrors.Fatalf("failed to set actor in commit state: %s", err)
}
@ -571,15 +556,15 @@ func (rt *Runtime) abortIfAlreadyValidated() {
rt.callerValidated = true
}
func (rt *Runtime) Log(level vmr.LogLevel, msg string, args ...interface{}) {
func (rt *Runtime) Log(level rtt.LogLevel, msg string, args ...interface{}) {
switch level {
case vmr.DEBUG:
case rtt.DEBUG:
actorLog.Debugf(msg, args...)
case vmr.INFO:
case rtt.INFO:
actorLog.Infof(msg, args...)
case vmr.WARN:
case rtt.WARN:
actorLog.Warnf(msg, args...)
case vmr.ERROR:
case rtt.ERROR:
actorLog.Errorf(msg, args...)
}
}

View File

@ -7,13 +7,6 @@ import (
"reflect"
"time"
"github.com/filecoin-project/specs-actors/actors/runtime"
bstore "github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
block "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
@ -25,8 +18,11 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/account"
"github.com/filecoin-project/lotus/build"
@ -34,6 +30,7 @@ import (
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore"
bstore "github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/lotus/lib/bufbstore"
)
@ -116,7 +113,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres
Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks},
Atlas: vm.cst.Atlas,
}
rt.sys = pricedSyscalls{
rt.Syscalls = pricedSyscalls{
under: vm.Syscalls(ctx, vm.cstate, rt.cst),
chargeGas: rt.chargeGasFunc(1),
pl: rt.pricelist,
@ -128,7 +125,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres
rt.Abortf(exitcode.SysErrInvalidReceiver, "resolve msg.From address failed")
}
vmm.From = resF
rt.vmsg = &vmm
rt.Message = &vmm
return rt
}
@ -142,7 +139,7 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin
}
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
type NtwkVersionGetter func(context.Context, abi.ChainEpoch) runtime.NetworkVersion
type NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
type VM struct {
cstate *state.StateTree
@ -170,10 +167,11 @@ type VMOpts struct {
BaseFee abi.TokenAmount
}
func NewVM(opts *VMOpts) (*VM, error) {
func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
buf := bufbstore.NewBufferedBstore(opts.Bstore)
cst := cbor.NewCborStore(buf)
state, err := state.LoadStateTree(cst, opts.StateBase)
nwv := opts.NtwkVersion(ctx, opts.Epoch) // TODO: why do we need a context for this?
state, err := state.LoadStateTree(cst, opts.StateBase, nwv)
if err != nil {
return nil, err
}
@ -700,9 +698,9 @@ func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params
defer span.End()
if span.IsRecordingEvents() {
span.AddAttributes(
trace.StringAttribute("to", rt.Message().Receiver().String()),
trace.StringAttribute("to", rt.Receiver().String()),
trace.Int64Attribute("method", int64(method)),
trace.StringAttribute("value", rt.Message().ValueReceived().String()),
trace.StringAttribute("value", rt.ValueReceived().String()),
)
}
@ -722,7 +720,7 @@ func (vm *VM) SetInvoker(i *Invoker) {
vm.inv = i
}
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) runtime.NetworkVersion {
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version {
return vm.ntwkVersion(ctx, ce)
}