diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 33884368f..22a2acb8b 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -31,41 +31,41 @@ func init() { var EmptyObjectCid cid.Cid // TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses. -func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aerrors.ActorError) { +func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, address.Address, aerrors.ActorError) { if err := rt.chargeGasSafe(PricelistByEpoch(rt.height).OnCreateActor()); err != nil { - return nil, err + return nil, address.Undef, err } addrID, err := rt.state.RegisterNewAddress(addr) if err != nil { - return nil, aerrors.Escalate(err, "registering actor address") + return nil, address.Undef, aerrors.Escalate(err, "registering actor address") } act, aerr := makeActor(actors.VersionForNetwork(rt.NetworkVersion()), addr) if aerr != nil { - return nil, aerr + return nil, address.Undef, aerr } if err := rt.state.SetActor(addrID, act); err != nil { - return nil, aerrors.Escalate(err, "creating new actor failed") + return nil, address.Undef, aerrors.Escalate(err, "creating new actor failed") } p, err := actors.SerializeParams(&addr) if err != nil { - return nil, aerrors.Escalate(err, "couldn't serialize params for actor construction") + return nil, address.Undef, aerrors.Escalate(err, "couldn't serialize params for actor construction") } // call constructor on account _, aerr = rt.internalSend(builtin0.SystemActorAddr, addrID, builtin0.MethodsAccount.Constructor, big.Zero(), p) if aerr != nil { - return nil, aerrors.Wrap(aerr, "failed to invoke account constructor") + return nil, address.Undef, aerrors.Wrap(aerr, "failed to invoke account constructor") } act, err = rt.state.GetActor(addrID) if err != nil { - return nil, aerrors.Escalate(err, "loading newly created actor failed") + return nil, address.Undef, aerrors.Escalate(err, "loading newly created actor failed") } - return act, nil + return act, addrID, nil } func makeActor(ver actors.Version, addr address.Address) (*types.Actor, aerrors.ActorError) { diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 472017a00..530adfe95 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -27,8 +27,30 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +type Message struct { + msg types.Message +} + +func (m *Message) Caller() address.Address { + if m.msg.From.Protocol() != address.ID { + panic("runtime message has a non-ID caller") + } + return m.msg.From +} + +func (m *Message) Receiver() address.Address { + if m.msg.To != address.Undef && m.msg.To.Protocol() != address.ID { + panic("runtime message has a non-ID receiver") + } + return m.msg.To +} + +func (m *Message) ValueReceived() abi.TokenAmount { + return m.msg.Value +} + type Runtime struct { - types.Message + rt0.Message rt0.Syscalls ctx context.Context diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 1361c6fbe..bb20c14e9 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -131,7 +131,15 @@ 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.Message = vmm + + if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version3 { + rt.Message = &vmm + } else { + resT, _ := rt.ResolveAddress(msg.To) + // may be set to undef if recipient doesn't exist yet + vmm.To = resT + rt.Message = &Message{msg: vmm} + } return rt } @@ -257,11 +265,24 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, toActor, err := st.GetActor(msg.To) if err != nil { if xerrors.Is(err, types.ErrActorNotFound) { - a, err := TryCreateAccountActor(rt, msg.To) + a, aid, err := TryCreateAccountActor(rt, msg.To) if err != nil { return nil, aerrors.Wrapf(err, "could not create account") } toActor = a + if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version3 { + // Leave the rt.Message as is + } else { + nmsg := Message{ + msg: types.Message{ + To: aid, + From: rt.Message.Caller(), + Value: rt.Message.ValueReceived(), + }, + } + + rt.Message = &nmsg + } } else { return nil, aerrors.Escalate(err, "getting actor") }