mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 07:37:20 +00:00
parent
6f08b3a725
commit
328add2a5a
24 changed files with 186 additions and 59 deletions
|
|
@ -423,7 +423,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
|
|||
sdb := state.NewDatabase(tdb, nil)
|
||||
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
||||
for addr, a := range accounts {
|
||||
statedb.SetCode(addr, a.Code)
|
||||
statedb.SetCode(addr, a.Code, tracing.CodeChangeUnspecified)
|
||||
statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis)
|
||||
statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance)
|
||||
for k, v := range a.Storage {
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ func runCmd(ctx *cli.Context) error {
|
|||
}
|
||||
} else {
|
||||
if len(code) > 0 {
|
||||
prestate.SetCode(receiver, code)
|
||||
prestate.SetCode(receiver, code, tracing.CodeChangeUnspecified)
|
||||
}
|
||||
execFunc = func() ([]byte, uint64, error) {
|
||||
// don't mutate the state!
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
|||
if account.Balance != nil {
|
||||
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetCode(addr, account.Code, tracing.CodeChangeGenesis)
|
||||
statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis)
|
||||
for key, value := range account.Storage {
|
||||
statedb.SetState(addr, key, value)
|
||||
|
|
@ -179,7 +179,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e
|
|||
// already captures the allocations.
|
||||
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetCode(addr, account.Code, tracing.CodeChangeGenesis)
|
||||
statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis)
|
||||
for key, value := range account.Storage {
|
||||
statedb.SetState(addr, key, value)
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64, reason tracing.Non
|
|||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) SetCode(addr common.Address, code []byte) (prev []byte) {
|
||||
func (s *StateDB) SetCode(addr common.Address, code []byte, reason tracing.CodeChangeReason) (prev []byte) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction
|
|||
code := make([]byte, 16)
|
||||
binary.BigEndian.PutUint64(code, uint64(a.args[0]))
|
||||
binary.BigEndian.PutUint64(code[8:], uint64(a.args[1]))
|
||||
s.SetCode(addr, code)
|
||||
s.SetCode(addr, code, tracing.CodeChangeUnspecified)
|
||||
},
|
||||
args: make([]int64, 2),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -189,14 +189,20 @@ func (s *hookedStateDB) SetNonce(address common.Address, nonce uint64, reason tr
|
|||
}
|
||||
}
|
||||
|
||||
func (s *hookedStateDB) SetCode(address common.Address, code []byte) []byte {
|
||||
prev := s.inner.SetCode(address, code)
|
||||
if s.hooks.OnCodeChange != nil {
|
||||
func (s *hookedStateDB) SetCode(address common.Address, code []byte, reason tracing.CodeChangeReason) []byte {
|
||||
prev := s.inner.SetCode(address, code, reason)
|
||||
if s.hooks.OnCodeChangeV2 != nil || s.hooks.OnCodeChange != nil {
|
||||
prevHash := types.EmptyCodeHash
|
||||
if len(prev) != 0 {
|
||||
prevHash = crypto.Keccak256Hash(prev)
|
||||
}
|
||||
s.hooks.OnCodeChange(address, prevHash, prev, crypto.Keccak256Hash(code), code)
|
||||
codeHash := crypto.Keccak256Hash(code)
|
||||
|
||||
if s.hooks.OnCodeChangeV2 != nil {
|
||||
s.hooks.OnCodeChangeV2(address, prevHash, prev, codeHash, code, reason)
|
||||
} else if s.hooks.OnCodeChange != nil {
|
||||
s.hooks.OnCodeChange(address, prevHash, prev, codeHash, code)
|
||||
}
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
|
@ -224,8 +230,12 @@ func (s *hookedStateDB) SelfDestruct(address common.Address) uint256.Int {
|
|||
s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
|
||||
}
|
||||
|
||||
if s.hooks.OnCodeChange != nil && len(prevCode) > 0 {
|
||||
s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil)
|
||||
if len(prevCode) > 0 {
|
||||
if s.hooks.OnCodeChangeV2 != nil {
|
||||
s.hooks.OnCodeChangeV2(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil, tracing.CodeChangeSelfDestruct)
|
||||
} else if s.hooks.OnCodeChange != nil {
|
||||
s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil)
|
||||
}
|
||||
}
|
||||
|
||||
return prev
|
||||
|
|
@ -246,8 +256,12 @@ func (s *hookedStateDB) SelfDestruct6780(address common.Address) (uint256.Int, b
|
|||
s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
|
||||
}
|
||||
|
||||
if s.hooks.OnCodeChange != nil && changed && len(prevCode) > 0 {
|
||||
s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil)
|
||||
if changed && len(prevCode) > 0 {
|
||||
if s.hooks.OnCodeChangeV2 != nil {
|
||||
s.hooks.OnCodeChangeV2(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil, tracing.CodeChangeSelfDestruct)
|
||||
} else if s.hooks.OnCodeChange != nil {
|
||||
s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil)
|
||||
}
|
||||
}
|
||||
|
||||
return prev, changed
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func TestHooks(t *testing.T) {
|
|||
sdb.AddBalance(common.Address{0xaa}, uint256.NewInt(100), tracing.BalanceChangeUnspecified)
|
||||
sdb.SubBalance(common.Address{0xaa}, uint256.NewInt(50), tracing.BalanceChangeTransfer)
|
||||
sdb.SetNonce(common.Address{0xaa}, 1337, tracing.NonceChangeGenesis)
|
||||
sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37})
|
||||
sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37}, tracing.CodeChangeUnspecified)
|
||||
sdb.SetState(common.Address{0xaa}, common.HexToHash("0x01"), common.HexToHash("0x11"))
|
||||
sdb.SetState(common.Address{0xaa}, common.HexToHash("0x01"), common.HexToHash("0x22"))
|
||||
sdb.SetTransientState(common.Address{0xaa}, common.HexToHash("0x02"), common.HexToHash("0x01"))
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func TestUpdateLeaks(t *testing.T) {
|
|||
state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
|
||||
}
|
||||
if i%3 == 0 {
|
||||
state.SetCode(addr, []byte{i, i, i, i, i})
|
||||
state.SetCode(addr, []byte{i, i, i, i, i}, tracing.CodeChangeUnspecified)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||
state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak})
|
||||
}
|
||||
if i%3 == 0 {
|
||||
state.SetCode(addr, []byte{i, i, i, i, i, tweak})
|
||||
state.SetCode(addr, []byte{i, i, i, i, i, tweak}, tracing.CodeChangeUnspecified)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +374,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
|
|||
code := make([]byte, 16)
|
||||
binary.BigEndian.PutUint64(code, uint64(a.args[0]))
|
||||
binary.BigEndian.PutUint64(code[8:], uint64(a.args[1]))
|
||||
s.SetCode(addr, code)
|
||||
s.SetCode(addr, code, tracing.CodeChangeUnspecified)
|
||||
},
|
||||
args: make([]int64, 2),
|
||||
},
|
||||
|
|
@ -403,7 +403,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
|
|||
// which would cause a difference in state when unrolling
|
||||
// the journal. (CreateContact assumes created was false prior to
|
||||
// invocation, and the journal rollback sets it to false).
|
||||
s.SetCode(addr, []byte{1})
|
||||
s.SetCode(addr, []byte{1}, tracing.CodeChangeUnspecified)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -731,7 +731,7 @@ func TestCopyCommitCopy(t *testing.T) {
|
|||
sval := common.HexToHash("bbb")
|
||||
|
||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie
|
||||
state.SetCode(addr, []byte("hello")) // Change an external metadata
|
||||
state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata
|
||||
state.SetState(addr, skey, sval) // Change the storage trie
|
||||
|
||||
if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 {
|
||||
|
|
@ -804,7 +804,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
|
|||
sval := common.HexToHash("bbb")
|
||||
|
||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie
|
||||
state.SetCode(addr, []byte("hello")) // Change an external metadata
|
||||
state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata
|
||||
state.SetState(addr, skey, sval) // Change the storage trie
|
||||
|
||||
if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 {
|
||||
|
|
@ -874,7 +874,7 @@ func TestCommitCopy(t *testing.T) {
|
|||
sval1, sval2 := common.HexToHash("b1"), common.HexToHash("b2")
|
||||
|
||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie
|
||||
state.SetCode(addr, []byte("hello")) // Change an external metadata
|
||||
state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata
|
||||
state.SetState(addr, skey1, sval1) // Change the storage trie
|
||||
|
||||
if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 {
|
||||
|
|
@ -987,10 +987,10 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
|
|||
addr := common.BytesToAddress([]byte("so"))
|
||||
{
|
||||
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
||||
state.SetCode(addr, []byte{1, 2, 3})
|
||||
state.SetCode(addr, []byte{1, 2, 3}, tracing.CodeChangeUnspecified)
|
||||
a2 := common.BytesToAddress([]byte("another"))
|
||||
state.SetBalance(a2, uint256.NewInt(100), tracing.BalanceChangeUnspecified)
|
||||
state.SetCode(a2, []byte{1, 2, 4})
|
||||
state.SetCode(a2, []byte{1, 2, 4}, tracing.CodeChangeUnspecified)
|
||||
root, _ = state.Commit(0, false, false)
|
||||
t.Logf("root: %x", root)
|
||||
// force-flush
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func filledStateDB() *StateDB {
|
|||
sval := common.HexToHash("bbb")
|
||||
|
||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie
|
||||
state.SetCode(addr, []byte("hello")) // Change an external metadata
|
||||
state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata
|
||||
state.SetState(addr, skey, sval) // Change the storage trie
|
||||
for i := 0; i < 100; i++ {
|
||||
sk := common.BigToHash(big.NewInt(int64(i)))
|
||||
|
|
@ -81,7 +81,7 @@ func TestVerklePrefetcher(t *testing.T) {
|
|||
sval := testrand.Hash()
|
||||
|
||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie
|
||||
state.SetCode(addr, []byte("hello")) // Change an external metadata
|
||||
state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata
|
||||
state.SetState(addr, skey, sval) // Change the storage trie
|
||||
root, _ := state.Commit(0, true, false)
|
||||
|
||||
|
|
|
|||
|
|
@ -617,12 +617,12 @@ func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization)
|
|||
st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization)
|
||||
if auth.Address == (common.Address{}) {
|
||||
// Delegation to zero address means clear.
|
||||
st.state.SetCode(authority, nil)
|
||||
st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise install delegation to auth.Address.
|
||||
st.state.SetCode(authority, types.AddressToDelegation(auth.Address))
|
||||
st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
29
core/tracing/gen_code_change_reason_stringer.go
Normal file
29
core/tracing/gen_code_change_reason_stringer.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Code generated by "stringer -type=CodeChangeReason -trimprefix=CodeChange -output gen_code_change_reason_stringer.go"; DO NOT EDIT.
|
||||
|
||||
package tracing
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[CodeChangeUnspecified-0]
|
||||
_ = x[CodeChangeContractCreation-1]
|
||||
_ = x[CodeChangeGenesis-2]
|
||||
_ = x[CodeChangeAuthorization-3]
|
||||
_ = x[CodeChangeAuthorizationClear-4]
|
||||
_ = x[CodeChangeSelfDestruct-5]
|
||||
_ = x[CodeChangeRevert-6]
|
||||
}
|
||||
|
||||
const _CodeChangeReason_name = "UnspecifiedContractCreationGenesisAuthorizationAuthorizationClearSelfDestructRevert"
|
||||
|
||||
var _CodeChangeReason_index = [...]uint8{0, 11, 27, 34, 47, 65, 77, 83}
|
||||
|
||||
func (i CodeChangeReason) String() string {
|
||||
if i >= CodeChangeReason(len(_CodeChangeReason_index)-1) {
|
||||
return "CodeChangeReason(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _CodeChangeReason_name[_CodeChangeReason_index[i]:_CodeChangeReason_index[i+1]]
|
||||
}
|
||||
|
|
@ -177,6 +177,9 @@ type (
|
|||
// CodeChangeHook is called when the code of an account changes.
|
||||
CodeChangeHook = func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte)
|
||||
|
||||
// CodeChangeHookV2 is called when the code of an account changes.
|
||||
CodeChangeHookV2 = func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason)
|
||||
|
||||
// StorageChangeHook is called when the storage of an account changes.
|
||||
StorageChangeHook = func(addr common.Address, slot common.Hash, prev, new common.Hash)
|
||||
|
||||
|
|
@ -211,6 +214,7 @@ type Hooks struct {
|
|||
OnNonceChange NonceChangeHook
|
||||
OnNonceChangeV2 NonceChangeHookV2
|
||||
OnCodeChange CodeChangeHook
|
||||
OnCodeChangeV2 CodeChangeHookV2
|
||||
OnStorageChange StorageChangeHook
|
||||
OnLog LogHook
|
||||
// Block hash read
|
||||
|
|
@ -372,3 +376,31 @@ const (
|
|||
// It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal).
|
||||
NonceChangeRevert NonceChangeReason = 6
|
||||
)
|
||||
|
||||
// CodeChangeReason is used to indicate the reason for a code change.
|
||||
type CodeChangeReason byte
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer -type=CodeChangeReason -trimprefix=CodeChange -output gen_code_change_reason_stringer.go
|
||||
|
||||
const (
|
||||
CodeChangeUnspecified CodeChangeReason = 0
|
||||
|
||||
// CodeChangeContractCreation is when a new contract is deployed via CREATE/CREATE2 operations.
|
||||
CodeChangeContractCreation CodeChangeReason = 1
|
||||
|
||||
// CodeChangeGenesis is when contract code is set during blockchain genesis or initial setup.
|
||||
CodeChangeGenesis CodeChangeReason = 2
|
||||
|
||||
// CodeChangeAuthorization is when code is set via EIP-7702 Set Code Authorization.
|
||||
CodeChangeAuthorization CodeChangeReason = 3
|
||||
|
||||
// CodeChangeAuthorizationClear is when EIP-7702 delegation is cleared by setting to zero address.
|
||||
CodeChangeAuthorizationClear CodeChangeReason = 4
|
||||
|
||||
// CodeChangeSelfDestruct is when contract code is cleared due to self-destruct.
|
||||
CodeChangeSelfDestruct CodeChangeReason = 5
|
||||
|
||||
// CodeChangeRevert is emitted when the code is reverted back to a previous value due to call failure.
|
||||
// It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal).
|
||||
CodeChangeRevert CodeChangeReason = 6
|
||||
)
|
||||
|
|
|
|||
|
|
@ -42,12 +42,15 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) {
|
|||
return nil, errors.New("wrapping nil tracer")
|
||||
}
|
||||
// No state change to journal, return the wrapped hooks as is
|
||||
if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && hooks.OnCodeChange == nil && hooks.OnStorageChange == nil {
|
||||
if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && hooks.OnCodeChange == nil && hooks.OnCodeChangeV2 == nil && hooks.OnStorageChange == nil {
|
||||
return hooks, nil
|
||||
}
|
||||
if hooks.OnNonceChange != nil && hooks.OnNonceChangeV2 != nil {
|
||||
return nil, errors.New("cannot have both OnNonceChange and OnNonceChangeV2")
|
||||
}
|
||||
if hooks.OnCodeChange != nil && hooks.OnCodeChangeV2 != nil {
|
||||
return nil, errors.New("cannot have both OnCodeChange and OnCodeChangeV2")
|
||||
}
|
||||
|
||||
// Create a new Hooks instance and copy all hooks
|
||||
wrapped := *hooks
|
||||
|
|
@ -72,6 +75,9 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) {
|
|||
if hooks.OnCodeChange != nil {
|
||||
wrapped.OnCodeChange = j.OnCodeChange
|
||||
}
|
||||
if hooks.OnCodeChangeV2 != nil {
|
||||
wrapped.OnCodeChangeV2 = j.OnCodeChangeV2
|
||||
}
|
||||
if hooks.OnStorageChange != nil {
|
||||
wrapped.OnStorageChange = j.OnStorageChange
|
||||
}
|
||||
|
|
@ -174,6 +180,19 @@ func (j *journal) OnCodeChange(addr common.Address, prevCodeHash common.Hash, pr
|
|||
}
|
||||
}
|
||||
|
||||
func (j *journal) OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason) {
|
||||
j.entries = append(j.entries, codeChange{
|
||||
addr: addr,
|
||||
prevCodeHash: prevCodeHash,
|
||||
prevCode: prevCode,
|
||||
newCodeHash: codeHash,
|
||||
newCode: code,
|
||||
})
|
||||
if j.hooks.OnCodeChangeV2 != nil {
|
||||
j.hooks.OnCodeChangeV2(addr, prevCodeHash, prevCode, codeHash, code, reason)
|
||||
}
|
||||
}
|
||||
|
||||
func (j *journal) OnStorageChange(addr common.Address, slot common.Hash, prev, new common.Hash) {
|
||||
j.entries = append(j.entries, storageChange{addr: addr, slot: slot, prev: prev, new: new})
|
||||
if j.hooks.OnStorageChange != nil {
|
||||
|
|
@ -225,7 +244,9 @@ func (n nonceChange) revert(hooks *Hooks) {
|
|||
}
|
||||
|
||||
func (c codeChange) revert(hooks *Hooks) {
|
||||
if hooks.OnCodeChange != nil {
|
||||
if hooks.OnCodeChangeV2 != nil {
|
||||
hooks.OnCodeChangeV2(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode, CodeChangeRevert)
|
||||
} else if hooks.OnCodeChange != nil {
|
||||
hooks.OnCodeChange(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type testTracer struct {
|
||||
|
|
@ -56,6 +57,11 @@ func (t *testTracer) OnCodeChange(addr common.Address, prevCodeHash common.Hash,
|
|||
t.code = code
|
||||
}
|
||||
|
||||
func (t *testTracer) OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason) {
|
||||
t.t.Logf("OnCodeChangeV2(%v, %v -> %v, %v)", addr, prevCodeHash, codeHash, reason)
|
||||
t.code = code
|
||||
}
|
||||
|
||||
func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) {
|
||||
t.t.Logf("OnStorageCodeChange(%v, %v, %v -> %v)", addr, slot, prev, new)
|
||||
if t.storage == nil {
|
||||
|
|
@ -232,6 +238,27 @@ func TestOnNonceChangeV2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOnCodeChangeV2(t *testing.T) {
|
||||
tr := &testTracer{t: t}
|
||||
wr, err := WrapWithJournal(&Hooks{OnCodeChangeV2: tr.OnCodeChangeV2})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to wrap test tracer: %v", err)
|
||||
}
|
||||
|
||||
addr := common.HexToAddress("0x1234")
|
||||
code := []byte{1, 2, 3}
|
||||
{
|
||||
wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0))
|
||||
wr.OnCodeChangeV2(addr, common.Hash{}, nil, crypto.Keccak256Hash(code), code, CodeChangeContractCreation)
|
||||
wr.OnExit(2, nil, 100, nil, true)
|
||||
}
|
||||
|
||||
// After revert, code should be nil
|
||||
if tr.code != nil {
|
||||
t.Fatalf("unexpected code after revert: %v", tr.code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllHooksCalled(t *testing.T) {
|
||||
tracer := newTracerAllHooks()
|
||||
hooks := tracer.hooks()
|
||||
|
|
@ -298,6 +325,7 @@ func newTracerAllHooks() *tracerAllHooks {
|
|||
t.hooksCalled[hooksType.Field(i).Name] = false
|
||||
}
|
||||
delete(t.hooksCalled, "OnNonceChange")
|
||||
delete(t.hooksCalled, "OnCodeChange")
|
||||
return t
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +350,7 @@ func (t *tracerAllHooks) hooks() *Hooks {
|
|||
hooksValue := reflect.ValueOf(h).Elem()
|
||||
for i := 0; i < hooksValue.NumField(); i++ {
|
||||
field := hooksValue.Type().Field(i)
|
||||
if field.Name == "OnNonceChange" {
|
||||
if field.Name == "OnNonceChange" || field.Name == "OnCodeChange" {
|
||||
continue
|
||||
}
|
||||
hookMethod := reflect.MakeFunc(field.Type, func(args []reflect.Value) []reflect.Value {
|
||||
|
|
|
|||
|
|
@ -2292,8 +2292,8 @@ func TestSetCodeTransactions(t *testing.T) {
|
|||
pending: 1,
|
||||
run: func(name string) {
|
||||
aa := common.Address{0xaa, 0xaa}
|
||||
statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...))
|
||||
statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)})
|
||||
statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...), tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)}, tracing.CodeChangeUnspecified)
|
||||
|
||||
// Send gapped transaction, it should be rejected.
|
||||
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrOutOfOrderTxFromDelegated) {
|
||||
|
|
@ -2317,7 +2317,7 @@ func TestSetCodeTransactions(t *testing.T) {
|
|||
}
|
||||
|
||||
// Reset the delegation, avoid leaking state into the other tests
|
||||
statedb.SetCode(addrA, nil)
|
||||
statedb.SetCode(addrA, nil, tracing.CodeChangeUnspecified)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -2583,7 +2583,7 @@ func TestSetCodeTransactionsReorg(t *testing.T) {
|
|||
}
|
||||
// Simulate the chain moving
|
||||
blockchain.statedb.SetNonce(addrA, 1, tracing.NonceChangeAuthorization)
|
||||
blockchain.statedb.SetCode(addrA, types.AddressToDelegation(auth.Address))
|
||||
blockchain.statedb.SetCode(addrA, types.AddressToDelegation(auth.Address), tracing.CodeChangeUnspecified)
|
||||
<-pool.requestReset(nil, nil)
|
||||
// Set an authorization for 0x00
|
||||
auth, _ = types.SignSetCode(keyA, types.SetCodeAuthorization{
|
||||
|
|
@ -2601,7 +2601,7 @@ func TestSetCodeTransactionsReorg(t *testing.T) {
|
|||
}
|
||||
// Simulate the chain moving
|
||||
blockchain.statedb.SetNonce(addrA, 2, tracing.NonceChangeAuthorization)
|
||||
blockchain.statedb.SetCode(addrA, nil)
|
||||
blockchain.statedb.SetCode(addrA, nil, tracing.CodeChangeUnspecified)
|
||||
<-pool.requestReset(nil, nil)
|
||||
// Now send two transactions from addrA
|
||||
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); err != nil {
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
|||
// etc
|
||||
checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) {
|
||||
statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified)
|
||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
|
||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode, tracing.CodeChangeUnspecified)
|
||||
// Process n blocks, from 1 .. num
|
||||
var num = 2
|
||||
for i := 1; i <= num; i++ {
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
|
|||
}
|
||||
}
|
||||
|
||||
evm.StateDB.SetCode(address, ret)
|
||||
evm.StateDB.SetCode(address, ret, tracing.CodeChangeContractCreation)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
|
|
@ -87,7 +88,7 @@ func TestEIP2200(t *testing.T) {
|
|||
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.CreateAccount(address)
|
||||
statedb.SetCode(address, hexutil.MustDecode(tt.input))
|
||||
statedb.SetCode(address, hexutil.MustDecode(tt.input), tracing.CodeChangeUnspecified)
|
||||
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
||||
statedb.Finalise(true) // Push the state into the "original" slot
|
||||
|
||||
|
|
@ -139,7 +140,7 @@ func TestCreateGas(t *testing.T) {
|
|||
address := common.BytesToAddress([]byte("contract"))
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.CreateAccount(address)
|
||||
statedb.SetCode(address, hexutil.MustDecode(tt.code))
|
||||
statedb.SetCode(address, hexutil.MustDecode(tt.code), tracing.CodeChangeUnspecified)
|
||||
statedb.Finalise(true)
|
||||
vmctx := BlockContext{
|
||||
CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true },
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ type StateDB interface {
|
|||
GetCode(common.Address) []byte
|
||||
|
||||
// SetCode sets the new code for the address, and returns the previous code, if any.
|
||||
SetCode(common.Address, []byte) []byte
|
||||
SetCode(common.Address, []byte, tracing.CodeChangeReason) []byte
|
||||
GetCodeSize(common.Address) int
|
||||
|
||||
AddRefund(uint64)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
|
|
@ -45,7 +46,7 @@ func TestLoopInterrupt(t *testing.T) {
|
|||
for i, tt := range loopInterruptTests {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.CreateAccount(address)
|
||||
statedb.SetCode(address, common.Hex2Bytes(tt))
|
||||
statedb.SetCode(address, common.Hex2Bytes(tt), tracing.CodeChangeUnspecified)
|
||||
statedb.Finalise(true)
|
||||
|
||||
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{})
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"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"
|
||||
|
|
@ -139,7 +140,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil)
|
||||
cfg.State.CreateAccount(address)
|
||||
// set the receiver's (the executing contract) code for execution.
|
||||
cfg.State.SetCode(address, code)
|
||||
cfg.State.SetCode(address, code, tracing.CodeChangeUnspecified)
|
||||
// Call the code with the given configuration.
|
||||
ret, leftOverGas, err := vmenv.Call(
|
||||
cfg.Origin,
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func TestCall(t *testing.T) {
|
|||
byte(vm.PUSH1), 32,
|
||||
byte(vm.PUSH1), 0,
|
||||
byte(vm.RETURN),
|
||||
})
|
||||
}, tracing.CodeChangeUnspecified)
|
||||
|
||||
ret, _, err := Call(address, nil, &Config{State: state})
|
||||
if err != nil {
|
||||
|
|
@ -167,7 +167,7 @@ func benchmarkEVM_Create(bench *testing.B, code string) {
|
|||
)
|
||||
|
||||
statedb.CreateAccount(sender)
|
||||
statedb.SetCode(receiver, common.FromHex(code))
|
||||
statedb.SetCode(receiver, common.FromHex(code), tracing.CodeChangeUnspecified)
|
||||
runtimeConfig := Config{
|
||||
Origin: sender,
|
||||
State: statedb,
|
||||
|
|
@ -232,7 +232,7 @@ func BenchmarkEVM_SWAP1(b *testing.B) {
|
|||
|
||||
b.Run("10k", func(b *testing.B) {
|
||||
contractCode := swapContract(10_000)
|
||||
state.SetCode(contractAddr, contractCode)
|
||||
state.SetCode(contractAddr, contractCode, tracing.CodeChangeUnspecified)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _, err := Call(contractAddr, []byte{}, &Config{State: state})
|
||||
|
|
@ -263,7 +263,7 @@ func BenchmarkEVM_RETURN(b *testing.B) {
|
|||
b.ReportAllocs()
|
||||
|
||||
contractCode := returnContract(n)
|
||||
state.SetCode(contractAddr, contractCode)
|
||||
state.SetCode(contractAddr, contractCode, tracing.CodeChangeUnspecified)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
ret, _, err := Call(contractAddr, []byte{}, &Config{State: state})
|
||||
|
|
@ -422,12 +422,12 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode
|
|||
byte(vm.PUSH1), 0x00,
|
||||
byte(vm.PUSH1), 0x00,
|
||||
byte(vm.REVERT),
|
||||
})
|
||||
}, tracing.CodeChangeUnspecified)
|
||||
}
|
||||
|
||||
//cfg.State.CreateAccount(cfg.Origin)
|
||||
// set the receiver's (the executing contract) code for execution.
|
||||
cfg.State.SetCode(destination, code)
|
||||
cfg.State.SetCode(destination, code, tracing.CodeChangeUnspecified)
|
||||
Call(destination, nil, cfg)
|
||||
|
||||
b.Run(name, func(b *testing.B) {
|
||||
|
|
@ -772,12 +772,12 @@ func TestRuntimeJSTracer(t *testing.T) {
|
|||
for i, jsTracer := range jsTracers {
|
||||
for j, tc := range tests {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.SetCode(main, tc.code)
|
||||
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode)
|
||||
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode)
|
||||
statedb.SetCode(common.HexToAddress("0xdd"), calleeCode)
|
||||
statedb.SetCode(common.HexToAddress("0xee"), calleeCode)
|
||||
statedb.SetCode(common.HexToAddress("0xff"), suicideCode)
|
||||
statedb.SetCode(main, tc.code, tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode, tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode, tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(common.HexToAddress("0xdd"), calleeCode, tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(common.HexToAddress("0xee"), calleeCode, tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(common.HexToAddress("0xff"), suicideCode, tracing.CodeChangeUnspecified)
|
||||
|
||||
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil, params.MergedTestChainConfig)
|
||||
if err != nil {
|
||||
|
|
@ -862,8 +862,8 @@ func BenchmarkTracerStepVsCallFrame(b *testing.B) {
|
|||
// delegation designator incurs the correct amount of gas based on the tracer.
|
||||
func TestDelegatedAccountAccessCost(t *testing.T) {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.SetCode(common.HexToAddress("0xff"), types.AddressToDelegation(common.HexToAddress("0xaa")))
|
||||
statedb.SetCode(common.HexToAddress("0xaa"), program.New().Return(0, 0).Bytes())
|
||||
statedb.SetCode(common.HexToAddress("0xff"), types.AddressToDelegation(common.HexToAddress("0xaa")), tracing.CodeChangeUnspecified)
|
||||
statedb.SetCode(common.HexToAddress("0xaa"), program.New().Return(0, 0).Bytes(), tracing.CodeChangeUnspecified)
|
||||
|
||||
for i, tc := range []struct {
|
||||
code []byte
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.Precompi
|
|||
}
|
||||
// Override account(contract) code.
|
||||
if account.Code != nil {
|
||||
statedb.SetCode(addr, *account.Code)
|
||||
statedb.SetCode(addr, *account.Code, tracing.CodeChangeUnspecified)
|
||||
}
|
||||
// Override account balance.
|
||||
if account.Balance != nil {
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
|
|||
sdb := state.NewDatabase(triedb, nil)
|
||||
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
||||
for addr, a := range accounts {
|
||||
statedb.SetCode(addr, a.Code)
|
||||
statedb.SetCode(addr, a.Code, tracing.CodeChangeUnspecified)
|
||||
statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeUnspecified)
|
||||
statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceChangeUnspecified)
|
||||
for k, v := range a.Storage {
|
||||
|
|
|
|||
Loading…
Reference in a new issue