New Actor Addresses should be generated as per spec

- The pubkey address address of the sender should be used, not the ID address
- We should use the internal callSeqNum as input (was hard-coded to zero)
- The external message nonce should be used, not the actor's nonce in the post-increment state
This commit is contained in:
Aayush Rajasekaran 2020-03-17 01:58:00 -04:00
parent 8d0b2947d6
commit 51cf5d5f1b
2 changed files with 27 additions and 20 deletions

View File

@ -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
}

View File

@ -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