Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/vm: start tracer before update callee's nonce #28445

Closed
wants to merge 2 commits into from

Conversation

jsvisa
Copy link
Contributor

@jsvisa jsvisa commented Nov 1, 2023

Fix #28439

I see what the question is :)

If the transaction is after EIP158(absolutely it is), we will set the created contract's nonce to 1

go-ethereum/core/vm/evm.go

Lines 445 to 461 in 233db64

if evm.chainRules.IsEIP158 {
evm.StateDB.SetNonce(address, 1)
}
evm.Context.Transfer(evm.StateDB, caller.Address(), address, value)
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(address), value, gas)
contract.SetCodeOptionalHash(&address, codeAndHash)
if evm.Config.Tracer != nil {
if evm.depth == 0 {
evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value)
} else {
evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
}
}

But in the inner created contracts, we fetch the nonce in front of entering this scope, so its nonce is 0

case op == vm.CREATE:
nonce := t.env.StateDB.GetNonce(caller)
addr := crypto.CreateAddress(caller, nonce)
t.lookupAccount(addr)
t.created[addr] = true
case stackLen >= 4 && op == vm.CREATE2:
offset := stackData[stackLen-2]
size := stackData[stackLen-3]
init, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(offset.Uint64()), int64(size.Uint64()))
if err != nil {
log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size)
return
}
inithash := crypto.Keccak256(init)
salt := stackData[stackLen-4]
addr := crypto.CreateAddress2(caller, salt.Bytes32(), inithash)
t.lookupAccount(addr)
t.created[addr] = true
}

So in general, the outer tx's created contract's nonce is always 1, and the inner created contracts' nonce is 0.

I found this issue does not happen in Erigon's node, dig into the code and found they will first start the tracer, and then launch the creating process. so the nonce is 0

https://github.com/ledgerwatch/erigon/blob/c90bff7e22337691ca4c41df41a782e805435f46/core/vm/evm.go#L335-L347

So I proposed to move the tracer a little forward, this will not affect the current implementation,

@jsvisa jsvisa requested a review from s1na as a code owner November 1, 2023 03:22
@@ -439,6 +439,15 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) {
return nil, common.Address{}, 0, ErrContractAddressCollision
}

Copy link
Contributor

@s1na s1na Nov 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're already changing where the hooks are called in #27629. Honestly I'd rather do it once and publish a semantic-change notice to users.

I appreciate you putting the work in figuring out and fixing this. I think we can at least use the testcase you generated in that PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this may affect the semantics of the current implementation, and that's fine to not merge this one.

@s1na
Copy link
Contributor

s1na commented Nov 3, 2023

I will close then.

@s1na s1na closed this Nov 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Prestate Tracer reported incorrect nonce for address being created
2 participants