handle some runtime error edge cases

This commit is contained in:
Jeromy 2020-04-03 14:38:11 -07:00
parent 847bdb203a
commit 4c6fa1b2c0
3 changed files with 43 additions and 32 deletions

View File

@ -137,15 +137,13 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
param := reflect.New(paramT) param := reflect.New(paramT)
inBytes := in[1].Interface().([]byte) inBytes := in[1].Interface().([]byte)
if len(inBytes) > 0 { if err := DecodeParams(inBytes, param.Interface()); err != nil {
if err := DecodeParams(inBytes, param.Interface()); err != nil { aerr := aerrors.Absorb(err, 1, "failed to decode parameters")
aerr := aerrors.Absorb(err, 1, "failed to decode parameters") return []reflect.Value{
return []reflect.Value{ reflect.ValueOf([]byte{}),
reflect.ValueOf([]byte{}), // Below is a hack, fixed in Go 1.13
// Below is a hack, fixed in Go 1.13 // https://git.io/fjXU6
// https://git.io/fjXU6 reflect.ValueOf(&aerr).Elem(),
reflect.ValueOf(&aerr).Elem(),
}
} }
} }
rt := in[0].Interface().(*Runtime) rt := in[0].Interface().(*Runtime)

View File

@ -9,6 +9,7 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/abi/big"
sainit "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime" "github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime" vmr "github.com/filecoin-project/specs-actors/actors/runtime"
@ -19,6 +20,7 @@ import (
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
@ -31,6 +33,7 @@ type Runtime struct {
vm *VM vm *VM
state *state.StateTree state *state.StateTree
msg *types.Message msg *types.Message
vmsg vmr.Message
height abi.ChainEpoch height abi.ChainEpoch
cst cbor.IpldStore cst cbor.IpldStore
pricelist Pricelist pricelist Pricelist
@ -48,18 +51,29 @@ type Runtime struct {
numActorsCreated uint64 numActorsCreated uint64
} }
func (rt *Runtime) ResolveAddress(address address.Address) (ret address.Address, ok bool) { func (rt *Runtime) ResolveAddress(addr address.Address) (ret address.Address, ok bool) {
r, err := rt.state.LookupID(address) r, err := rt.state.LookupID(addr)
if err != nil { // TODO: check notfound if err != nil { // TODO: check notfound
rt.Abortf(exitcode.ErrPlaceholder, "resolve address: %v", err) if xerrors.Is(err, sainit.ErrAddressNotFound) {
return address.Undef, false
}
panic(aerrors.Fatalf("failed to resolve address %s: %s", addr, err))
} }
return r, true return r, true
} }
type notFoundErr interface {
IsNotFound() bool
}
func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool { func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
if err := rs.cst.Get(context.TODO(), c, o); err != nil { if err := rs.cst.Get(context.TODO(), c, o); err != nil {
// TODO: err not found? var nfe notFoundErr
rs.Abortf(exitcode.ErrPlaceholder, "storage get: %v", err) if xerrors.As(err, &nfe) && nfe.IsNotFound() {
return false
}
panic(aerrors.Fatalf("failed to get cbor object %s: %s", c, err))
} }
return true return true
} }
@ -67,7 +81,7 @@ func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid { func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
c, err := rs.cst.Put(context.TODO(), x) c, err := rs.cst.Put(context.TODO(), x)
if err != nil { if err != nil {
rs.Abortf(exitcode.ErrPlaceholder, "storage put: %v", err) // todo: spec code? panic(aerrors.Fatalf("failed to put cbor object: %s", err))
} }
return c return c
} }
@ -107,20 +121,7 @@ func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
} }
func (rs *Runtime) Message() vmr.Message { func (rs *Runtime) Message() vmr.Message {
var ok bool return rs.vmsg
rawm := *rs.msg
rawm.From, ok = rs.ResolveAddress(rawm.From)
if !ok {
rs.Abortf(exitcode.ErrPlaceholder, "resolve from address failed")
}
rawm.To, ok = rs.ResolveAddress(rawm.To)
if !ok {
rs.Abortf(exitcode.ErrPlaceholder, "resolve to address failed")
}
return &rawm
} }
func (rs *Runtime) ValidateImmediateCallerAcceptAny() { func (rs *Runtime) ValidateImmediateCallerAcceptAny() {
@ -138,8 +139,11 @@ func (rs *Runtime) CurrentBalance() abi.TokenAmount {
func (rs *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) { func (rs *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) {
act, err := rs.state.GetActor(addr) act, err := rs.state.GetActor(addr)
if err != nil { if err != nil {
// todo: notfound if xerrors.Is(err, types.ErrActorNotFound) {
rs.Abortf(exitcode.ErrPlaceholder, "%v", err) return cid.Undef, false
}
panic(aerrors.Fatalf("failed to get actor: %s", err))
} }
return act.Code, true return act.Code, true
@ -148,7 +152,7 @@ func (rs *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool)
func (rt *Runtime) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { func (rt *Runtime) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetRandomness(rt.ctx, personalization, int64(randEpoch), entropy) res, err := rt.vm.rand.GetRandomness(rt.ctx, personalization, int64(randEpoch), entropy)
if err != nil { if err != nil {
rt.Abortf(exitcode.SysErrInternal, "could not get randomness: %s", err) panic(aerrors.Fatalf("could not get randomness: %s", err))
} }
return res return res
} }

View File

@ -131,6 +131,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres
numActorsCreated: nac, numActorsCreated: nac,
pricelist: PricelistByEpoch(vm.blockHeight), pricelist: PricelistByEpoch(vm.blockHeight),
} }
rt.cst = &cbor.BasicIpldStore{ rt.cst = &cbor.BasicIpldStore{
Blocks: &gasChargingBlocks{rt.ChargeGas, rt.pricelist, vm.cst.Blocks}, Blocks: &gasChargingBlocks{rt.ChargeGas, rt.pricelist, vm.cst.Blocks},
Atlas: vm.cst.Atlas, Atlas: vm.cst.Atlas,
@ -141,6 +142,14 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres
pl: rt.pricelist, pl: rt.pricelist,
} }
vmm := *msg
resF, ok := rt.ResolveAddress(msg.From)
if !ok {
rt.Abortf(exitcode.SysErrInvalidReceiver, "resolve msg.From address failed")
}
vmm.From = resF
rt.vmsg = &vmm
return rt return rt
} }