mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
core, consensus: update irregular state transition
This commit is contained in:
parent
5fecc3facb
commit
867efad997
2 changed files with 27 additions and 9 deletions
|
|
@ -17,10 +17,9 @@
|
|||
package misc
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
|
|
@ -29,12 +28,10 @@ import (
|
|||
// CREATE2 factory that, once present at the canonical address on every EVM chain,
|
||||
// allows contracts to be deployed at identical addresses across chains.
|
||||
func ApplyEIP7997(statedb vm.StateDB) {
|
||||
contractHash := statedb.GetCodeHash(params.DeterministicFactoryAddress)
|
||||
nonce := statedb.GetNonce(params.DeterministicFactoryAddress)
|
||||
|
||||
// Reject the irregular state transition if the destination doesn't
|
||||
// satisfy the deployment condition.
|
||||
if nonce != 0 || (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) {
|
||||
// The account must hold the canonical factory runtime code. If its code hash
|
||||
// already matches, the chain satisfies EIP-7997 and nothing needs to change.
|
||||
wantHash := crypto.Keccak256Hash(params.DeterministicFactoryCode)
|
||||
if statedb.GetCodeHash(params.DeterministicFactoryAddress) == wantHash {
|
||||
return
|
||||
}
|
||||
if !statedb.Exist(params.DeterministicFactoryAddress) {
|
||||
|
|
@ -42,5 +39,9 @@ func ApplyEIP7997(statedb vm.StateDB) {
|
|||
}
|
||||
statedb.CreateContract(params.DeterministicFactoryAddress)
|
||||
statedb.SetCode(params.DeterministicFactoryAddress, params.DeterministicFactoryCode, tracing.CodeChangeUnspecified)
|
||||
statedb.SetNonce(params.DeterministicFactoryAddress, 1, tracing.NonceChangeNewContract)
|
||||
|
||||
// Preserve a pre-existing nonce; only bump the default zero nonce to 1.
|
||||
if statedb.GetNonce(params.DeterministicFactoryAddress) == 0 {
|
||||
statedb.SetNonce(params.DeterministicFactoryAddress, 1, tracing.NonceChangeNewContract)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,23 @@ func TestApplyEIP7997Existing(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestApplyEIP7997WrongCode checks that an account occupying the factory address
|
||||
// with the wrong code is force-overwritten with the canonical runtime code, while
|
||||
// a pre-existing non-zero nonce is preserved.
|
||||
func TestApplyEIP7997WrongCode(t *testing.T) {
|
||||
sdb := mkState(types.GenesisAlloc{
|
||||
params.DeterministicFactoryAddress: {Code: []byte{0x60, 0x00}, Nonce: 7},
|
||||
})
|
||||
misc.ApplyEIP7997(sdb)
|
||||
|
||||
if got := sdb.GetCode(params.DeterministicFactoryAddress); !bytes.Equal(got, params.DeterministicFactoryCode) {
|
||||
t.Fatalf("factory code not overwritten:\n got %x\nwant %x", got, params.DeterministicFactoryCode)
|
||||
}
|
||||
if got := sdb.GetNonce(params.DeterministicFactoryAddress); got != 7 {
|
||||
t.Fatalf("factory nonce = %d, want %d (existing nonce must be preserved)", got, 7)
|
||||
}
|
||||
}
|
||||
|
||||
// TestEIP7997FactoryDeploys exercises the inserted factory bytecode: calling it
|
||||
// with a salt followed by init code must CREATE2-deploy the contract at the
|
||||
// canonical deterministic address and return that address (20 bytes, unpadded).
|
||||
|
|
|
|||
Loading…
Reference in a new issue