From b71b7434200c56f40ace3ce22314171f3e1a0f18 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Sun, 6 Sep 2020 03:48:45 -0400 Subject: [PATCH 1/3] Bugfix: Runtime's Receiver() should only return ID addresses --- chain/vm/mkactor.go | 18 +++++++++--------- chain/vm/vm.go | 12 +++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) 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/vm.go b/chain/vm/vm.go index 1361c6fbe..aec356fb4 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -131,6 +131,9 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres rt.Abortf(exitcode.SysErrInvalidReceiver, "resolve msg.From address failed") } vmm.From = resF + resT, _ := rt.ResolveAddress(msg.To) + // may be set to undef if recipient doesn't exist yet + vmm.To = resT rt.Message = vmm return rt @@ -257,11 +260,18 @@ 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 + nmsg := types.Message{ + To: aid, + From: rt.vmsg.Caller(), + Value: rt.vmsg.ValueReceived(), + } + + rt.vmsg = &nmsg } else { return nil, aerrors.Escalate(err, "getting actor") } From 757aa1039fe65202cfedd6c3c6819b41bc2d0473 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 23 Sep 2020 22:45:53 -0400 Subject: [PATCH 2/3] Panic if runtime's Message has non-ID caller or receiver --- chain/vm/runtime.go | 24 +++++++++++++++++++++++- chain/vm/vm.go | 14 ++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 472017a00..4c6bf1848 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 + Message rt0.Syscalls ctx context.Context diff --git a/chain/vm/vm.go b/chain/vm/vm.go index aec356fb4..a5072f8c5 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -134,7 +134,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres resT, _ := rt.ResolveAddress(msg.To) // may be set to undef if recipient doesn't exist yet vmm.To = resT - rt.Message = vmm + rt.Message = Message{msg: vmm} return rt } @@ -265,13 +265,15 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, return nil, aerrors.Wrapf(err, "could not create account") } toActor = a - nmsg := types.Message{ - To: aid, - From: rt.vmsg.Caller(), - Value: rt.vmsg.ValueReceived(), + nmsg := Message{ + msg: types.Message{ + To: aid, + From: rt.Message.Caller(), + Value: rt.Message.ValueReceived(), + }, } - rt.vmsg = &nmsg + rt.Message = nmsg } else { return nil, aerrors.Escalate(err, "getting actor") } From d9fad5fad09764504320e6aa82a7030b42b26a18 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 01:25:55 -0400 Subject: [PATCH 3/3] Move rt.Message fixes behind fork logic --- chain/vm/runtime.go | 2 +- chain/vm/vm.go | 33 +++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 4c6bf1848..530adfe95 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -50,7 +50,7 @@ func (m *Message) ValueReceived() abi.TokenAmount { } type Runtime struct { - Message + rt0.Message rt0.Syscalls ctx context.Context diff --git a/chain/vm/vm.go b/chain/vm/vm.go index a5072f8c5..bb20c14e9 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -131,10 +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 - resT, _ := rt.ResolveAddress(msg.To) - // may be set to undef if recipient doesn't exist yet - vmm.To = resT - rt.Message = Message{msg: 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 } @@ -265,15 +270,19 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, return nil, aerrors.Wrapf(err, "could not create account") } toActor = a - nmsg := Message{ - msg: types.Message{ - To: aid, - From: rt.Message.Caller(), - Value: rt.Message.ValueReceived(), - }, - } + 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 + rt.Message = &nmsg + } } else { return nil, aerrors.Escalate(err, "getting actor") }