diff --git a/chain/actors/aerrors/wrap.go b/chain/actors/aerrors/wrap.go index 928d3fb70..324eeb4e1 100644 --- a/chain/actors/aerrors/wrap.go +++ b/chain/actors/aerrors/wrap.go @@ -48,6 +48,26 @@ func Newf(retCode uint8, format string, args ...interface{}) ActorError { } } +// todo: bit hacky +func NewfSkip(skip int, retCode uint8, format string, args ...interface{}) ActorError { + if retCode == 0 { + return &actorError{ + fatal: true, + retCode: 0, + + msg: "tried creating an error and setting RetCode to 0", + frame: xerrors.Caller(skip), + err: fmt.Errorf(format, args...), + } + } + return &actorError{ + retCode: retCode, + + msg: fmt.Sprintf(format, args...), + frame: xerrors.Caller(skip), + } +} + func Fatal(message string, args ...interface{}) ActorError { return &actorError{ fatal: true, diff --git a/chain/gen/genesis/util.go b/chain/gen/genesis/util.go index 258e6597c..22cb7c33d 100644 --- a/chain/gen/genesis/util.go +++ b/chain/gen/genesis/util.go @@ -2,7 +2,6 @@ package genesis import ( "context" - "fmt" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" @@ -47,7 +46,7 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value } if ret.ExitCode != 0 { - return nil, fmt.Errorf("failed to call method: %s", ret.ActorErr) + return nil, xerrors.Errorf("failed to call method: %w", ret.ActorErr) } return ret.Return, nil diff --git a/chain/vm/spec_shim.go b/chain/vm/spec_shim.go index 760ec95b2..b75b944ac 100644 --- a/chain/vm/spec_shim.go +++ b/chain/vm/spec_shim.go @@ -3,6 +3,7 @@ package vm import ( "bytes" "context" + "encoding/binary" "fmt" "runtime/debug" @@ -110,7 +111,33 @@ func (rs *runtimeShim) Store() vmr.Store { } func (rs *runtimeShim) NewActorAddress() address.Address { - panic("implement me") + var b bytes.Buffer + if err := rs.ImmediateCaller().MarshalCBOR(&b); err != nil { // todo: spec says cbor; why not just bytes? + rs.Abortf(exitcode.ErrSerialization, "writing caller address into a buffer: %v", err) + } + + var err error + st, err := rs.vmctx.StateTree() + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "getting statetree: %v", err) + } + act, err := st.GetActor(rs.vmctx.Origin()) + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "getting top level actor: %v", err) + } + + if err := binary.Write(&b, binary.BigEndian, act.Nonce); err != nil { + rs.Abortf(exitcode.ErrSerialization, "writing nonce address into a buffer: %v", err) + } + if err := binary.Write(&b, binary.BigEndian, uint64(0)); err != nil { // TODO: expose on vm + rs.Abortf(exitcode.ErrSerialization, "writing callSeqNum address into a buffer: %v", err) + } + addr, err := address.NewActorAddress(b.Bytes()) + if err != nil { + rs.Abortf(exitcode.ErrSerialization, "create actor address: %v", err) + } + + return addr } func (rs *runtimeShim) CreateActor(codeId cid.Cid, address address.Address) { @@ -148,11 +175,11 @@ func (rs *runtimeShim) Context() context.Context { } func (rs *runtimeShim) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { - panic(aerrors.Newf(uint8(code), msg, args...)) + panic(aerrors.NewfSkip(2, uint8(code), msg, args...)) } func (rs *runtimeShim) AbortStateMsg(msg string) { - rs.Abortf(101, msg) + panic(aerrors.NewfSkip(3, 101, msg)) } func (rs *runtimeShim) ValidateImmediateCallerType(...cid.Cid) {