diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 27d728efa..97b244690 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -40,9 +40,12 @@ type Runtime struct { sys runtime.Syscalls // address that started invoke chain - origin address.Address + origin address.Address + originNonce uint64 internalExecutions []*ExecutionResult + // the first internal call has a value of 1 for this field + internalCallCounter int64 } func (rs *Runtime) ResolveAddress(address address.Address) (ret address.Address, ok bool) { @@ -158,19 +161,14 @@ func (rs *Runtime) Store() vmr.Store { func (rt *Runtime) NewActorAddress() address.Address { var b bytes.Buffer - if err := rt.Message().Caller().MarshalCBOR(&b); err != nil { // todo: spec says cbor; why not just bytes? + if err := rt.origin.MarshalCBOR(&b); err != nil { // todo: spec says cbor; why not just bytes? rt.Abortf(exitcode.ErrSerialization, "writing caller address into a buffer: %v", err) } - act, err := rt.state.GetActor(rt.origin) - if err != nil { - rt.Abortf(exitcode.SysErrInternal, "getting top level actor: %v", err) - } - - if err := binary.Write(&b, binary.BigEndian, act.Nonce); err != nil { + if err := binary.Write(&b, binary.BigEndian, rt.originNonce); err != nil { rt.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 + if err := binary.Write(&b, binary.BigEndian, rt.internalCallCounter); err != nil { // TODO: expose on vm rt.Abortf(exitcode.ErrSerialization, "writing callSeqNum address into a buffer: %v", err) } addr, err := address.NewActorAddress(b.Bytes()) @@ -341,6 +339,9 @@ func (rt *Runtime) internalSend(to address.Address, method abi.MethodNum, value Subcalls: subrt.internalExecutions, } + if subrt != nil { + rt.internalCallCounter = subrt.internalCallCounter + } rt.internalExecutions = append(rt.internalExecutions, &er) return ret, err } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index fa890eac7..6b147e573 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -115,18 +115,20 @@ func (bs *gasChargingBlocks) Put(blk block.Block) error { return nil } -func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin address.Address, usedGas types.BigInt) *Runtime { +func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas types.BigInt, icc int64) *Runtime { rt := &Runtime{ - ctx: ctx, - vm: vm, - state: vm.cstate, - msg: msg, - origin: origin, - height: vm.blockHeight, - sys: vm.Syscalls, + ctx: ctx, + vm: vm, + state: vm.cstate, + msg: msg, + origin: origin, + originNonce: originNonce, + height: vm.blockHeight, + sys: vm.Syscalls, - gasUsed: usedGas, - gasAvailable: msg.GasLimit, + gasUsed: usedGas, + gasAvailable: msg.GasLimit, + internalCallCounter: icc, } rt.cst = &cbor.BasicIpldStore{ Blocks: &gasChargingBlocks{rt.ChargeGas, vm.cst.Blocks}, @@ -206,11 +208,15 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, gasUsed := types.NewInt(gasCharge) origin := msg.From + on := msg.Nonce + var icc int64 = 0 if parent != nil { gasUsed = types.BigAdd(parent.gasUsed, gasUsed) origin = parent.origin + on = parent.originNonce + icc = parent.internalCallCounter + 1 } - rt := vm.makeRuntime(ctx, msg, origin, gasUsed) + rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, icc) if parent != nil { defer func() { parent.gasUsed = rt.gasUsed