github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/core/state/statedb_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package state
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"fmt"
    23  	"math"
    24  	"math/big"
    25  	"math/rand"
    26  	"reflect"
    27  	"strings"
    28  	"sync"
    29  	"testing"
    30  	"testing/quick"
    31  
    32  	"github.com/stretchr/testify/assert"
    33  
    34  	"github.com/ethereum/go-ethereum/common"
    35  	"github.com/ethereum/go-ethereum/core/blockstm"
    36  	"github.com/ethereum/go-ethereum/core/rawdb"
    37  	"github.com/ethereum/go-ethereum/core/types"
    38  )
    39  
    40  // Tests that updating a state trie does not leak any database writes prior to
    41  // actually committing the state.
    42  func TestUpdateLeaks(t *testing.T) {
    43  	// Create an empty state database
    44  	db := rawdb.NewMemoryDatabase()
    45  	state, _ := New(common.Hash{}, NewDatabase(db), nil)
    46  
    47  	// Update it with some accounts
    48  	for i := byte(0); i < 255; i++ {
    49  		addr := common.BytesToAddress([]byte{i})
    50  		state.AddBalance(addr, big.NewInt(int64(11*i)))
    51  		state.SetNonce(addr, uint64(42*i))
    52  		if i%2 == 0 {
    53  			state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
    54  		}
    55  		if i%3 == 0 {
    56  			state.SetCode(addr, []byte{i, i, i, i, i})
    57  		}
    58  	}
    59  
    60  	root := state.IntermediateRoot(false)
    61  	if err := state.Database().TrieDB().Commit(root, false, nil); err != nil {
    62  		t.Errorf("can not commit trie %v to persistent database", root.Hex())
    63  	}
    64  
    65  	// Ensure that no data was leaked into the database
    66  	it := db.NewIterator(nil, nil)
    67  	for it.Next() {
    68  		t.Errorf("State leaked into database: %x -> %x", it.Key(), it.Value())
    69  	}
    70  	it.Release()
    71  }
    72  
    73  // Tests that no intermediate state of an object is stored into the database,
    74  // only the one right before the commit.
    75  func TestIntermediateLeaks(t *testing.T) {
    76  	// Create two state databases, one transitioning to the final state, the other final from the beginning
    77  	transDb := rawdb.NewMemoryDatabase()
    78  	finalDb := rawdb.NewMemoryDatabase()
    79  	transState, _ := New(common.Hash{}, NewDatabase(transDb), nil)
    80  	finalState, _ := New(common.Hash{}, NewDatabase(finalDb), nil)
    81  
    82  	modify := func(state *StateDB, addr common.Address, i, tweak byte) {
    83  		state.SetBalance(addr, big.NewInt(int64(11*i)+int64(tweak)))
    84  		state.SetNonce(addr, uint64(42*i+tweak))
    85  		if i%2 == 0 {
    86  			state.SetState(addr, common.Hash{i, i, i, 0}, common.Hash{})
    87  			state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak})
    88  		}
    89  		if i%3 == 0 {
    90  			state.SetCode(addr, []byte{i, i, i, i, i, tweak})
    91  		}
    92  	}
    93  
    94  	// Modify the transient state.
    95  	for i := byte(0); i < 255; i++ {
    96  		modify(transState, common.Address{i}, i, 0)
    97  	}
    98  	// Write modifications to trie.
    99  	transState.IntermediateRoot(false)
   100  
   101  	// Overwrite all the data with new values in the transient database.
   102  	for i := byte(0); i < 255; i++ {
   103  		modify(transState, common.Address{i}, i, 99)
   104  		modify(finalState, common.Address{i}, i, 99)
   105  	}
   106  
   107  	// Commit and cross check the databases.
   108  	transRoot, err := transState.Commit(false)
   109  	if err != nil {
   110  		t.Fatalf("failed to commit transition state: %v", err)
   111  	}
   112  	if err = transState.Database().TrieDB().Commit(transRoot, false, nil); err != nil {
   113  		t.Errorf("can not commit trie %v to persistent database", transRoot.Hex())
   114  	}
   115  
   116  	finalRoot, err := finalState.Commit(false)
   117  	if err != nil {
   118  		t.Fatalf("failed to commit final state: %v", err)
   119  	}
   120  	if err = finalState.Database().TrieDB().Commit(finalRoot, false, nil); err != nil {
   121  		t.Errorf("can not commit trie %v to persistent database", finalRoot.Hex())
   122  	}
   123  
   124  	it := finalDb.NewIterator(nil, nil)
   125  	for it.Next() {
   126  		key, fvalue := it.Key(), it.Value()
   127  		tvalue, err := transDb.Get(key)
   128  		if err != nil {
   129  			t.Errorf("entry missing from the transition database: %x -> %x", key, fvalue)
   130  		}
   131  		if !bytes.Equal(fvalue, tvalue) {
   132  			t.Errorf("value mismatch at key %x: %x in transition database, %x in final database", key, tvalue, fvalue)
   133  		}
   134  	}
   135  	it.Release()
   136  
   137  	it = transDb.NewIterator(nil, nil)
   138  	for it.Next() {
   139  		key, tvalue := it.Key(), it.Value()
   140  		fvalue, err := finalDb.Get(key)
   141  		if err != nil {
   142  			t.Errorf("extra entry in the transition database: %x -> %x", key, it.Value())
   143  		}
   144  		if !bytes.Equal(fvalue, tvalue) {
   145  			t.Errorf("value mismatch at key %x: %x in transition database, %x in final database", key, tvalue, fvalue)
   146  		}
   147  	}
   148  }
   149  
   150  // TestCopy tests that copying a StateDB object indeed makes the original and
   151  // the copy independent of each other. This test is a regression test against
   152  // https://github.com/ethereum/go-ethereum/pull/15549.
   153  func TestCopy(t *testing.T) {
   154  	// Create a random state test to copy and modify "independently"
   155  	orig, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
   156  
   157  	for i := byte(0); i < 255; i++ {
   158  		obj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   159  		obj.AddBalance(big.NewInt(int64(i)))
   160  		orig.updateStateObject(obj)
   161  	}
   162  	orig.Finalise(false)
   163  
   164  	// Copy the state
   165  	copy := orig.Copy()
   166  
   167  	// Copy the copy state
   168  	ccopy := copy.Copy()
   169  
   170  	// modify all in memory
   171  	for i := byte(0); i < 255; i++ {
   172  		origObj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   173  		copyObj := copy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   174  		ccopyObj := ccopy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   175  
   176  		origObj.AddBalance(big.NewInt(2 * int64(i)))
   177  		copyObj.AddBalance(big.NewInt(3 * int64(i)))
   178  		ccopyObj.AddBalance(big.NewInt(4 * int64(i)))
   179  
   180  		orig.updateStateObject(origObj)
   181  		copy.updateStateObject(copyObj)
   182  		ccopy.updateStateObject(copyObj)
   183  	}
   184  
   185  	// Finalise the changes on all concurrently
   186  	finalise := func(wg *sync.WaitGroup, db *StateDB) {
   187  		defer wg.Done()
   188  		db.Finalise(true)
   189  	}
   190  
   191  	var wg sync.WaitGroup
   192  	wg.Add(3)
   193  	go finalise(&wg, orig)
   194  	go finalise(&wg, copy)
   195  	go finalise(&wg, ccopy)
   196  	wg.Wait()
   197  
   198  	// Verify that the three states have been updated independently
   199  	for i := byte(0); i < 255; i++ {
   200  		origObj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   201  		copyObj := copy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   202  		ccopyObj := ccopy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   203  
   204  		if want := big.NewInt(3 * int64(i)); origObj.Balance().Cmp(want) != 0 {
   205  			t.Errorf("orig obj %d: balance mismatch: have %v, want %v", i, origObj.Balance(), want)
   206  		}
   207  		if want := big.NewInt(4 * int64(i)); copyObj.Balance().Cmp(want) != 0 {
   208  			t.Errorf("copy obj %d: balance mismatch: have %v, want %v", i, copyObj.Balance(), want)
   209  		}
   210  		if want := big.NewInt(5 * int64(i)); ccopyObj.Balance().Cmp(want) != 0 {
   211  			t.Errorf("copy obj %d: balance mismatch: have %v, want %v", i, ccopyObj.Balance(), want)
   212  		}
   213  	}
   214  }
   215  
   216  func TestSnapshotRandom(t *testing.T) {
   217  	config := &quick.Config{MaxCount: 1000}
   218  	err := quick.Check((*snapshotTest).run, config)
   219  	if cerr, ok := err.(*quick.CheckError); ok {
   220  		test := cerr.In[0].(*snapshotTest)
   221  		t.Errorf("%v:\n%s", test.err, test)
   222  	} else if err != nil {
   223  		t.Error(err)
   224  	}
   225  }
   226  
   227  // A snapshotTest checks that reverting StateDB snapshots properly undoes all changes
   228  // captured by the snapshot. Instances of this test with pseudorandom content are created
   229  // by Generate.
   230  //
   231  // The test works as follows:
   232  //
   233  // A new state is created and all actions are applied to it. Several snapshots are taken
   234  // in between actions. The test then reverts each snapshot. For each snapshot the actions
   235  // leading up to it are replayed on a fresh, empty state. The behaviour of all public
   236  // accessor methods on the reverted state must match the return value of the equivalent
   237  // methods on the replayed state.
   238  type snapshotTest struct {
   239  	addrs     []common.Address // all account addresses
   240  	actions   []testAction     // modifications to the state
   241  	snapshots []int            // actions indexes at which snapshot is taken
   242  	err       error            // failure details are reported through this field
   243  }
   244  
   245  type testAction struct {
   246  	name   string
   247  	fn     func(testAction, *StateDB)
   248  	args   []int64
   249  	noAddr bool
   250  }
   251  
   252  // newTestAction creates a random action that changes state.
   253  func newTestAction(addr common.Address, r *rand.Rand) testAction {
   254  	actions := []testAction{
   255  		{
   256  			name: "SetBalance",
   257  			fn: func(a testAction, s *StateDB) {
   258  				s.SetBalance(addr, big.NewInt(a.args[0]))
   259  			},
   260  			args: make([]int64, 1),
   261  		},
   262  		{
   263  			name: "AddBalance",
   264  			fn: func(a testAction, s *StateDB) {
   265  				s.AddBalance(addr, big.NewInt(a.args[0]))
   266  			},
   267  			args: make([]int64, 1),
   268  		},
   269  		{
   270  			name: "SetNonce",
   271  			fn: func(a testAction, s *StateDB) {
   272  				s.SetNonce(addr, uint64(a.args[0]))
   273  			},
   274  			args: make([]int64, 1),
   275  		},
   276  		{
   277  			name: "SetState",
   278  			fn: func(a testAction, s *StateDB) {
   279  				var key, val common.Hash
   280  				binary.BigEndian.PutUint16(key[:], uint16(a.args[0]))
   281  				binary.BigEndian.PutUint16(val[:], uint16(a.args[1]))
   282  				s.SetState(addr, key, val)
   283  			},
   284  			args: make([]int64, 2),
   285  		},
   286  		{
   287  			name: "SetCode",
   288  			fn: func(a testAction, s *StateDB) {
   289  				code := make([]byte, 16)
   290  				binary.BigEndian.PutUint64(code, uint64(a.args[0]))
   291  				binary.BigEndian.PutUint64(code[8:], uint64(a.args[1]))
   292  				s.SetCode(addr, code)
   293  			},
   294  			args: make([]int64, 2),
   295  		},
   296  		{
   297  			name: "CreateAccount",
   298  			fn: func(a testAction, s *StateDB) {
   299  				s.CreateAccount(addr)
   300  			},
   301  		},
   302  		{
   303  			name: "Suicide",
   304  			fn: func(a testAction, s *StateDB) {
   305  				s.Suicide(addr)
   306  			},
   307  		},
   308  		{
   309  			name: "AddRefund",
   310  			fn: func(a testAction, s *StateDB) {
   311  				s.AddRefund(uint64(a.args[0]))
   312  			},
   313  			args:   make([]int64, 1),
   314  			noAddr: true,
   315  		},
   316  		{
   317  			name: "AddLog",
   318  			fn: func(a testAction, s *StateDB) {
   319  				data := make([]byte, 2)
   320  				binary.BigEndian.PutUint16(data, uint16(a.args[0]))
   321  				s.AddLog(&types.Log{Address: addr, Data: data})
   322  			},
   323  			args: make([]int64, 1),
   324  		},
   325  		{
   326  			name: "AddPreimage",
   327  			fn: func(a testAction, s *StateDB) {
   328  				preimage := []byte{1}
   329  				hash := common.BytesToHash(preimage)
   330  				s.AddPreimage(hash, preimage)
   331  			},
   332  			args: make([]int64, 1),
   333  		},
   334  		{
   335  			name: "AddAddressToAccessList",
   336  			fn: func(a testAction, s *StateDB) {
   337  				s.AddAddressToAccessList(addr)
   338  			},
   339  		},
   340  		{
   341  			name: "AddSlotToAccessList",
   342  			fn: func(a testAction, s *StateDB) {
   343  				s.AddSlotToAccessList(addr,
   344  					common.Hash{byte(a.args[0])})
   345  			},
   346  			args: make([]int64, 1),
   347  		},
   348  	}
   349  	action := actions[r.Intn(len(actions))]
   350  	var nameargs []string
   351  	if !action.noAddr {
   352  		nameargs = append(nameargs, addr.Hex())
   353  	}
   354  	for i := range action.args {
   355  		action.args[i] = rand.Int63n(100)
   356  		nameargs = append(nameargs, fmt.Sprint(action.args[i]))
   357  	}
   358  	action.name += strings.Join(nameargs, ", ")
   359  	return action
   360  }
   361  
   362  // Generate returns a new snapshot test of the given size. All randomness is
   363  // derived from r.
   364  func (*snapshotTest) Generate(r *rand.Rand, size int) reflect.Value {
   365  	// Generate random actions.
   366  	addrs := make([]common.Address, 50)
   367  	for i := range addrs {
   368  		addrs[i][0] = byte(i)
   369  	}
   370  	actions := make([]testAction, size)
   371  	for i := range actions {
   372  		addr := addrs[r.Intn(len(addrs))]
   373  		actions[i] = newTestAction(addr, r)
   374  	}
   375  	// Generate snapshot indexes.
   376  	nsnapshots := int(math.Sqrt(float64(size)))
   377  	if size > 0 && nsnapshots == 0 {
   378  		nsnapshots = 1
   379  	}
   380  	snapshots := make([]int, nsnapshots)
   381  	snaplen := len(actions) / nsnapshots
   382  	for i := range snapshots {
   383  		// Try to place the snapshots some number of actions apart from each other.
   384  		snapshots[i] = (i * snaplen) + r.Intn(snaplen)
   385  	}
   386  	return reflect.ValueOf(&snapshotTest{addrs, actions, snapshots, nil})
   387  }
   388  
   389  func (test *snapshotTest) String() string {
   390  	out := new(bytes.Buffer)
   391  	sindex := 0
   392  	for i, action := range test.actions {
   393  		if len(test.snapshots) > sindex && i == test.snapshots[sindex] {
   394  			fmt.Fprintf(out, "---- snapshot %d ----\n", sindex)
   395  			sindex++
   396  		}
   397  		fmt.Fprintf(out, "%4d: %s\n", i, action.name)
   398  	}
   399  	return out.String()
   400  }
   401  
   402  func (test *snapshotTest) run() bool {
   403  	// Run all actions and create snapshots.
   404  	var (
   405  		state, _     = New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
   406  		snapshotRevs = make([]int, len(test.snapshots))
   407  		sindex       = 0
   408  	)
   409  	for i, action := range test.actions {
   410  		if len(test.snapshots) > sindex && i == test.snapshots[sindex] {
   411  			snapshotRevs[sindex] = state.Snapshot()
   412  			sindex++
   413  		}
   414  		action.fn(action, state)
   415  	}
   416  	// Revert all snapshots in reverse order. Each revert must yield a state
   417  	// that is equivalent to fresh state with all actions up the snapshot applied.
   418  	for sindex--; sindex >= 0; sindex-- {
   419  		checkstate, _ := New(common.Hash{}, state.Database(), nil)
   420  		for _, action := range test.actions[:test.snapshots[sindex]] {
   421  			action.fn(action, checkstate)
   422  		}
   423  		state.RevertToSnapshot(snapshotRevs[sindex])
   424  		if err := test.checkEqual(state, checkstate); err != nil {
   425  			test.err = fmt.Errorf("state mismatch after revert to snapshot %d\n%v", sindex, err)
   426  			return false
   427  		}
   428  	}
   429  	return true
   430  }
   431  
   432  // checkEqual checks that methods of state and checkstate return the same values.
   433  func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
   434  	for _, addr := range test.addrs {
   435  		var err error
   436  		checkeq := func(op string, a, b interface{}) bool {
   437  			if err == nil && !reflect.DeepEqual(a, b) {
   438  				err = fmt.Errorf("got %s(%s) == %v, want %v", op, addr.Hex(), a, b)
   439  				return false
   440  			}
   441  			return true
   442  		}
   443  		// Check basic accessor methods.
   444  		checkeq("Exist", state.Exist(addr), checkstate.Exist(addr))
   445  		checkeq("HasSuicided", state.HasSuicided(addr), checkstate.HasSuicided(addr))
   446  		checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr))
   447  		checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr))
   448  		checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr))
   449  		checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr))
   450  		checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr))
   451  		// Check storage.
   452  		if obj := state.getStateObject(addr); obj != nil {
   453  			state.ForEachStorage(addr, func(key, value common.Hash) bool {
   454  				return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value)
   455  			})
   456  			checkstate.ForEachStorage(addr, func(key, value common.Hash) bool {
   457  				return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value)
   458  			})
   459  		}
   460  		if err != nil {
   461  			return err
   462  		}
   463  	}
   464  
   465  	if state.GetRefund() != checkstate.GetRefund() {
   466  		return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
   467  			state.GetRefund(), checkstate.GetRefund())
   468  	}
   469  	if !reflect.DeepEqual(state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{})) {
   470  		return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v",
   471  			state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{}))
   472  	}
   473  	return nil
   474  }
   475  
   476  func TestTouchDelete(t *testing.T) {
   477  	s := newStateTest()
   478  	s.state.GetOrNewStateObject(common.Address{})
   479  	root, _ := s.state.Commit(false)
   480  	s.state, _ = New(root, s.state.db, s.state.snaps)
   481  
   482  	snapshot := s.state.Snapshot()
   483  	s.state.AddBalance(common.Address{}, new(big.Int))
   484  
   485  	if len(s.state.journal.dirties) != 1 {
   486  		t.Fatal("expected one dirty state object")
   487  	}
   488  	s.state.RevertToSnapshot(snapshot)
   489  	if len(s.state.journal.dirties) != 0 {
   490  		t.Fatal("expected no dirty state object")
   491  	}
   492  }
   493  
   494  func TestMVHashMapReadWriteDelete(t *testing.T) {
   495  	t.Parallel()
   496  
   497  	db := NewDatabase(rawdb.NewMemoryDatabase())
   498  	mvhm := blockstm.MakeMVHashMap()
   499  	s, _ := NewWithMVHashmap(common.Hash{}, db, nil, mvhm)
   500  
   501  	states := []*StateDB{s}
   502  
   503  	// Create copies of the original state for each transition
   504  	for i := 1; i <= 4; i++ {
   505  		sCopy := s.Copy()
   506  		sCopy.txIndex = i
   507  		states = append(states, sCopy)
   508  	}
   509  
   510  	addr := common.HexToAddress("0x01")
   511  	key := common.HexToHash("0x01")
   512  	val := common.HexToHash("0x01")
   513  	balance := new(big.Int).SetUint64(uint64(100))
   514  
   515  	// Tx0 read
   516  	v := states[0].GetState(addr, key)
   517  
   518  	assert.Equal(t, common.Hash{}, v)
   519  
   520  	// Tx1 write
   521  	states[1].GetOrNewStateObject(addr)
   522  	states[1].SetState(addr, key, val)
   523  	states[1].SetBalance(addr, balance)
   524  	states[1].FlushMVWriteSet()
   525  
   526  	// Tx1 read
   527  	v = states[1].GetState(addr, key)
   528  	b := states[1].GetBalance(addr)
   529  
   530  	assert.Equal(t, val, v)
   531  	assert.Equal(t, balance, b)
   532  
   533  	// Tx2 read
   534  	v = states[2].GetState(addr, key)
   535  	b = states[2].GetBalance(addr)
   536  
   537  	assert.Equal(t, val, v)
   538  	assert.Equal(t, balance, b)
   539  
   540  	// Tx3 delete
   541  	states[3].Suicide(addr)
   542  
   543  	// Within Tx 3, the state should not change before finalize
   544  	v = states[3].GetState(addr, key)
   545  	assert.Equal(t, val, v)
   546  
   547  	// After finalizing Tx 3, the state will change
   548  	states[3].Finalise(false)
   549  	v = states[3].GetState(addr, key)
   550  	assert.Equal(t, common.Hash{}, v)
   551  	states[3].FlushMVWriteSet()
   552  
   553  	// Tx4 read
   554  	v = states[4].GetState(addr, key)
   555  	b = states[4].GetBalance(addr)
   556  
   557  	assert.Equal(t, common.Hash{}, v)
   558  	assert.Equal(t, common.Big0, b)
   559  }
   560  
   561  func TestMVHashMapRevert(t *testing.T) {
   562  	t.Parallel()
   563  
   564  	db := NewDatabase(rawdb.NewMemoryDatabase())
   565  	mvhm := blockstm.MakeMVHashMap()
   566  	s, _ := NewWithMVHashmap(common.Hash{}, db, nil, mvhm)
   567  
   568  	states := []*StateDB{s}
   569  
   570  	// Create copies of the original state for each transition
   571  	for i := 1; i <= 4; i++ {
   572  		sCopy := s.Copy()
   573  		sCopy.txIndex = i
   574  		states = append(states, sCopy)
   575  	}
   576  
   577  	addr := common.HexToAddress("0x01")
   578  	key := common.HexToHash("0x01")
   579  	val := common.HexToHash("0x01")
   580  	balance := new(big.Int).SetUint64(uint64(100))
   581  
   582  	// Tx0 write
   583  	states[0].GetOrNewStateObject(addr)
   584  	states[0].SetState(addr, key, val)
   585  	states[0].SetBalance(addr, balance)
   586  	states[0].FlushMVWriteSet()
   587  
   588  	// Tx1 perform some ops and then revert
   589  	snapshot := states[1].Snapshot()
   590  	states[1].AddBalance(addr, new(big.Int).SetUint64(uint64(100)))
   591  	states[1].SetState(addr, key, common.HexToHash("0x02"))
   592  	v := states[1].GetState(addr, key)
   593  	b := states[1].GetBalance(addr)
   594  	assert.Equal(t, new(big.Int).SetUint64(uint64(200)), b)
   595  	assert.Equal(t, common.HexToHash("0x02"), v)
   596  
   597  	states[1].Suicide(addr)
   598  
   599  	states[1].RevertToSnapshot(snapshot)
   600  
   601  	v = states[1].GetState(addr, key)
   602  	b = states[1].GetBalance(addr)
   603  
   604  	assert.Equal(t, val, v)
   605  	assert.Equal(t, balance, b)
   606  	states[1].Finalise(false)
   607  	states[1].FlushMVWriteSet()
   608  
   609  	// Tx2 check the state and balance
   610  	v = states[2].GetState(addr, key)
   611  	b = states[2].GetBalance(addr)
   612  
   613  	assert.Equal(t, val, v)
   614  	assert.Equal(t, balance, b)
   615  }
   616  
   617  func TestMVHashMapMarkEstimate(t *testing.T) {
   618  	t.Parallel()
   619  
   620  	db := NewDatabase(rawdb.NewMemoryDatabase())
   621  	mvhm := blockstm.MakeMVHashMap()
   622  	s, _ := NewWithMVHashmap(common.Hash{}, db, nil, mvhm)
   623  
   624  	states := []*StateDB{s}
   625  
   626  	// Create copies of the original state for each transition
   627  	for i := 1; i <= 4; i++ {
   628  		sCopy := s.Copy()
   629  		sCopy.txIndex = i
   630  		states = append(states, sCopy)
   631  	}
   632  
   633  	addr := common.HexToAddress("0x01")
   634  	key := common.HexToHash("0x01")
   635  	val := common.HexToHash("0x01")
   636  	balance := new(big.Int).SetUint64(uint64(100))
   637  
   638  	// Tx0 read
   639  	v := states[0].GetState(addr, key)
   640  	assert.Equal(t, common.Hash{}, v)
   641  
   642  	// Tx0 write
   643  	states[0].SetState(addr, key, val)
   644  	v = states[0].GetState(addr, key)
   645  	assert.Equal(t, val, v)
   646  	states[0].FlushMVWriteSet()
   647  
   648  	// Tx1 write
   649  	states[1].GetOrNewStateObject(addr)
   650  	states[1].SetState(addr, key, val)
   651  	states[1].SetBalance(addr, balance)
   652  	states[1].FlushMVWriteSet()
   653  
   654  	// Tx2 read
   655  	v = states[2].GetState(addr, key)
   656  	b := states[2].GetBalance(addr)
   657  
   658  	assert.Equal(t, val, v)
   659  	assert.Equal(t, balance, b)
   660  
   661  	// Tx1 mark estimate
   662  	for _, v := range states[1].MVWriteList() {
   663  		mvhm.MarkEstimate(v.Path, 1)
   664  	}
   665  
   666  	defer func() {
   667  		if r := recover(); r == nil {
   668  			t.Errorf("The code did not panic")
   669  		} else {
   670  			t.Log("Recovered in f", r)
   671  		}
   672  	}()
   673  
   674  	// Tx2 read again should get default (empty) vals because its dependency Tx1 is marked as estimate
   675  	states[2].GetState(addr, key)
   676  	states[2].GetBalance(addr)
   677  
   678  	// Tx1 read again should get Tx0 vals
   679  	v = states[1].GetState(addr, key)
   680  	assert.Equal(t, val, v)
   681  }
   682  
   683  func TestMVHashMapOverwrite(t *testing.T) {
   684  	t.Parallel()
   685  
   686  	db := NewDatabase(rawdb.NewMemoryDatabase())
   687  	mvhm := blockstm.MakeMVHashMap()
   688  	s, _ := NewWithMVHashmap(common.Hash{}, db, nil, mvhm)
   689  
   690  	states := []*StateDB{s}
   691  
   692  	// Create copies of the original state for each transition
   693  	for i := 1; i <= 4; i++ {
   694  		sCopy := s.Copy()
   695  		sCopy.txIndex = i
   696  		states = append(states, sCopy)
   697  	}
   698  
   699  	addr := common.HexToAddress("0x01")
   700  	key := common.HexToHash("0x01")
   701  	val1 := common.HexToHash("0x01")
   702  	balance1 := new(big.Int).SetUint64(uint64(100))
   703  	val2 := common.HexToHash("0x02")
   704  	balance2 := new(big.Int).SetUint64(uint64(200))
   705  
   706  	// Tx0 write
   707  	states[0].GetOrNewStateObject(addr)
   708  	states[0].SetState(addr, key, val1)
   709  	states[0].SetBalance(addr, balance1)
   710  	states[0].FlushMVWriteSet()
   711  
   712  	// Tx1 write
   713  	states[1].SetState(addr, key, val2)
   714  	states[1].SetBalance(addr, balance2)
   715  	v := states[1].GetState(addr, key)
   716  	b := states[1].GetBalance(addr)
   717  	states[1].FlushMVWriteSet()
   718  
   719  	assert.Equal(t, val2, v)
   720  	assert.Equal(t, balance2, b)
   721  
   722  	// Tx2 read should get Tx1's value
   723  	v = states[2].GetState(addr, key)
   724  	b = states[2].GetBalance(addr)
   725  
   726  	assert.Equal(t, val2, v)
   727  	assert.Equal(t, balance2, b)
   728  
   729  	// Tx1 delete
   730  	for _, v := range states[1].writeMap {
   731  		mvhm.Delete(v.Path, 1)
   732  
   733  		states[1].writeMap = nil
   734  	}
   735  
   736  	// Tx2 read should get Tx0's value
   737  	v = states[2].GetState(addr, key)
   738  	b = states[2].GetBalance(addr)
   739  
   740  	assert.Equal(t, val1, v)
   741  	assert.Equal(t, balance1, b)
   742  
   743  	// Tx1 read should get Tx0's value
   744  	v = states[1].GetState(addr, key)
   745  	b = states[1].GetBalance(addr)
   746  
   747  	assert.Equal(t, val1, v)
   748  	assert.Equal(t, balance1, b)
   749  
   750  	// Tx0 delete
   751  	for _, v := range states[0].writeMap {
   752  		mvhm.Delete(v.Path, 0)
   753  
   754  		states[0].writeMap = nil
   755  	}
   756  
   757  	// Tx2 read again should get default vals
   758  	v = states[2].GetState(addr, key)
   759  	b = states[2].GetBalance(addr)
   760  
   761  	assert.Equal(t, common.Hash{}, v)
   762  	assert.Equal(t, common.Big0, b)
   763  }
   764  
   765  func TestMVHashMapWriteNoConflict(t *testing.T) {
   766  	t.Parallel()
   767  
   768  	db := NewDatabase(rawdb.NewMemoryDatabase())
   769  	mvhm := blockstm.MakeMVHashMap()
   770  	s, _ := NewWithMVHashmap(common.Hash{}, db, nil, mvhm)
   771  
   772  	states := []*StateDB{s}
   773  
   774  	// Create copies of the original state for each transition
   775  	for i := 1; i <= 4; i++ {
   776  		sCopy := s.Copy()
   777  		sCopy.txIndex = i
   778  		states = append(states, sCopy)
   779  	}
   780  
   781  	addr := common.HexToAddress("0x01")
   782  	key1 := common.HexToHash("0x01")
   783  	key2 := common.HexToHash("0x02")
   784  	val1 := common.HexToHash("0x01")
   785  	balance1 := new(big.Int).SetUint64(uint64(100))
   786  	val2 := common.HexToHash("0x02")
   787  
   788  	// Tx0 write
   789  	states[0].GetOrNewStateObject(addr)
   790  	states[0].FlushMVWriteSet()
   791  
   792  	// Tx2 write
   793  	states[2].SetState(addr, key2, val2)
   794  	states[2].FlushMVWriteSet()
   795  
   796  	// Tx1 write
   797  	tx1Snapshot := states[1].Snapshot()
   798  	states[1].SetState(addr, key1, val1)
   799  	states[1].SetBalance(addr, balance1)
   800  	states[1].FlushMVWriteSet()
   801  
   802  	// Tx1 read
   803  	assert.Equal(t, val1, states[1].GetState(addr, key1))
   804  	assert.Equal(t, balance1, states[1].GetBalance(addr))
   805  	// Tx1 should see empty value in key2
   806  	assert.Equal(t, common.Hash{}, states[1].GetState(addr, key2))
   807  
   808  	// Tx2 read
   809  	assert.Equal(t, val2, states[2].GetState(addr, key2))
   810  	// Tx2 should see values written by Tx1
   811  	assert.Equal(t, val1, states[2].GetState(addr, key1))
   812  	assert.Equal(t, balance1, states[2].GetBalance(addr))
   813  
   814  	// Tx3 read
   815  	assert.Equal(t, val1, states[3].GetState(addr, key1))
   816  	assert.Equal(t, val2, states[3].GetState(addr, key2))
   817  	assert.Equal(t, balance1, states[3].GetBalance(addr))
   818  
   819  	// Tx2 delete
   820  	for _, v := range states[2].writeMap {
   821  		mvhm.Delete(v.Path, 2)
   822  
   823  		states[2].writeMap = nil
   824  	}
   825  
   826  	assert.Equal(t, val1, states[3].GetState(addr, key1))
   827  	assert.Equal(t, balance1, states[3].GetBalance(addr))
   828  	assert.Equal(t, common.Hash{}, states[3].GetState(addr, key2))
   829  
   830  	// Tx1 revert
   831  	states[1].RevertToSnapshot(tx1Snapshot)
   832  	states[1].FlushMVWriteSet()
   833  
   834  	assert.Equal(t, common.Hash{}, states[3].GetState(addr, key1))
   835  	assert.Equal(t, common.Hash{}, states[3].GetState(addr, key2))
   836  	assert.Equal(t, common.Big0, states[3].GetBalance(addr))
   837  
   838  	// Tx1 delete
   839  	for _, v := range states[1].writeMap {
   840  		mvhm.Delete(v.Path, 1)
   841  
   842  		states[1].writeMap = nil
   843  	}
   844  
   845  	assert.Equal(t, common.Hash{}, states[3].GetState(addr, key1))
   846  	assert.Equal(t, common.Hash{}, states[3].GetState(addr, key2))
   847  	assert.Equal(t, common.Big0, states[3].GetBalance(addr))
   848  }
   849  
   850  func TestApplyMVWriteSet(t *testing.T) {
   851  	t.Parallel()
   852  
   853  	db := NewDatabase(rawdb.NewMemoryDatabase())
   854  	mvhm := blockstm.MakeMVHashMap()
   855  	s, _ := NewWithMVHashmap(common.Hash{}, db, nil, mvhm)
   856  
   857  	sClean := s.Copy()
   858  	sClean.mvHashmap = nil
   859  
   860  	sSingleProcess := sClean.Copy()
   861  
   862  	states := []*StateDB{s}
   863  
   864  	// Create copies of the original state for each transition
   865  	for i := 1; i <= 4; i++ {
   866  		sCopy := s.Copy()
   867  		sCopy.txIndex = i
   868  		states = append(states, sCopy)
   869  	}
   870  
   871  	addr1 := common.HexToAddress("0x01")
   872  	addr2 := common.HexToAddress("0x02")
   873  	addr3 := common.HexToAddress("0x03")
   874  	key1 := common.HexToHash("0x01")
   875  	key2 := common.HexToHash("0x02")
   876  	val1 := common.HexToHash("0x01")
   877  	balance1 := new(big.Int).SetUint64(uint64(100))
   878  	val2 := common.HexToHash("0x02")
   879  	balance2 := new(big.Int).SetUint64(uint64(200))
   880  	code := []byte{1, 2, 3}
   881  
   882  	// Tx0 write
   883  	states[0].GetOrNewStateObject(addr1)
   884  	states[0].SetState(addr1, key1, val1)
   885  	states[0].SetBalance(addr1, balance1)
   886  	states[0].SetState(addr2, key2, val2)
   887  	states[0].GetOrNewStateObject(addr3)
   888  	states[0].Finalise(true)
   889  	states[0].FlushMVWriteSet()
   890  
   891  	sSingleProcess.GetOrNewStateObject(addr1)
   892  	sSingleProcess.SetState(addr1, key1, val1)
   893  	sSingleProcess.SetBalance(addr1, balance1)
   894  	sSingleProcess.SetState(addr2, key2, val2)
   895  	sSingleProcess.GetOrNewStateObject(addr3)
   896  
   897  	sClean.ApplyMVWriteSet(states[0].MVWriteList())
   898  
   899  	assert.Equal(t, sSingleProcess.IntermediateRoot(true), sClean.IntermediateRoot(true))
   900  
   901  	// Tx1 write
   902  	states[1].SetState(addr1, key2, val2)
   903  	states[1].SetBalance(addr1, balance2)
   904  	states[1].SetNonce(addr1, 1)
   905  	states[1].Finalise(true)
   906  	states[1].FlushMVWriteSet()
   907  
   908  	sSingleProcess.SetState(addr1, key2, val2)
   909  	sSingleProcess.SetBalance(addr1, balance2)
   910  	sSingleProcess.SetNonce(addr1, 1)
   911  
   912  	sClean.ApplyMVWriteSet(states[1].MVWriteList())
   913  
   914  	assert.Equal(t, sSingleProcess.IntermediateRoot(true), sClean.IntermediateRoot(true))
   915  
   916  	// Tx2 write
   917  	states[2].SetState(addr1, key1, val2)
   918  	states[2].SetBalance(addr1, balance2)
   919  	states[2].SetNonce(addr1, 2)
   920  	states[2].Finalise(true)
   921  	states[2].FlushMVWriteSet()
   922  
   923  	sSingleProcess.SetState(addr1, key1, val2)
   924  	sSingleProcess.SetBalance(addr1, balance2)
   925  	sSingleProcess.SetNonce(addr1, 2)
   926  
   927  	sClean.ApplyMVWriteSet(states[2].MVWriteList())
   928  
   929  	assert.Equal(t, sSingleProcess.IntermediateRoot(true), sClean.IntermediateRoot(true))
   930  
   931  	// Tx3 write
   932  	states[3].Suicide(addr2)
   933  	states[3].SetCode(addr1, code)
   934  	states[3].Finalise(true)
   935  	states[3].FlushMVWriteSet()
   936  
   937  	sSingleProcess.Suicide(addr2)
   938  	sSingleProcess.SetCode(addr1, code)
   939  
   940  	sClean.ApplyMVWriteSet(states[3].MVWriteList())
   941  
   942  	assert.Equal(t, sSingleProcess.IntermediateRoot(true), sClean.IntermediateRoot(true))
   943  }
   944  
   945  // TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
   946  // See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
   947  func TestCopyOfCopy(t *testing.T) {
   948  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
   949  	addr := common.HexToAddress("aaaa")
   950  	state.SetBalance(addr, big.NewInt(42))
   951  
   952  	if got := state.Copy().GetBalance(addr).Uint64(); got != 42 {
   953  		t.Fatalf("1st copy fail, expected 42, got %v", got)
   954  	}
   955  	if got := state.Copy().Copy().GetBalance(addr).Uint64(); got != 42 {
   956  		t.Fatalf("2nd copy fail, expected 42, got %v", got)
   957  	}
   958  }
   959  
   960  // Tests a regression where committing a copy lost some internal meta information,
   961  // leading to corrupted subsequent copies.
   962  //
   963  // See https://github.com/ethereum/go-ethereum/issues/20106.
   964  func TestCopyCommitCopy(t *testing.T) {
   965  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
   966  
   967  	// Create an account and check if the retrieved balance is correct
   968  	addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
   969  	skey := common.HexToHash("aaa")
   970  	sval := common.HexToHash("bbb")
   971  
   972  	state.SetBalance(addr, big.NewInt(42)) // Change the account trie
   973  	state.SetCode(addr, []byte("hello"))   // Change an external metadata
   974  	state.SetState(addr, skey, sval)       // Change the storage trie
   975  
   976  	if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   977  		t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42)
   978  	}
   979  	if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   980  		t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello"))
   981  	}
   982  	if val := state.GetState(addr, skey); val != sval {
   983  		t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval)
   984  	}
   985  	if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) {
   986  		t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{})
   987  	}
   988  	// Copy the non-committed state database and check pre/post commit balance
   989  	copyOne := state.Copy()
   990  	if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   991  		t.Fatalf("first copy pre-commit balance mismatch: have %v, want %v", balance, 42)
   992  	}
   993  	if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   994  		t.Fatalf("first copy pre-commit code mismatch: have %x, want %x", code, []byte("hello"))
   995  	}
   996  	if val := copyOne.GetState(addr, skey); val != sval {
   997  		t.Fatalf("first copy pre-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
   998  	}
   999  	if val := copyOne.GetCommittedState(addr, skey); val != (common.Hash{}) {
  1000  		t.Fatalf("first copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{})
  1001  	}
  1002  
  1003  	copyOne.Commit(false)
  1004  	if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1005  		t.Fatalf("first copy post-commit balance mismatch: have %v, want %v", balance, 42)
  1006  	}
  1007  	if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1008  		t.Fatalf("first copy post-commit code mismatch: have %x, want %x", code, []byte("hello"))
  1009  	}
  1010  	if val := copyOne.GetState(addr, skey); val != sval {
  1011  		t.Fatalf("first copy post-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
  1012  	}
  1013  	if val := copyOne.GetCommittedState(addr, skey); val != sval {
  1014  		t.Fatalf("first copy post-commit committed storage slot mismatch: have %x, want %x", val, sval)
  1015  	}
  1016  	// Copy the copy and check the balance once more
  1017  	copyTwo := copyOne.Copy()
  1018  	if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1019  		t.Fatalf("second copy balance mismatch: have %v, want %v", balance, 42)
  1020  	}
  1021  	if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1022  		t.Fatalf("second copy code mismatch: have %x, want %x", code, []byte("hello"))
  1023  	}
  1024  	if val := copyTwo.GetState(addr, skey); val != sval {
  1025  		t.Fatalf("second copy non-committed storage slot mismatch: have %x, want %x", val, sval)
  1026  	}
  1027  	if val := copyTwo.GetCommittedState(addr, skey); val != sval {
  1028  		t.Fatalf("second copy post-commit committed storage slot mismatch: have %x, want %x", val, sval)
  1029  	}
  1030  }
  1031  
  1032  // Tests a regression where committing a copy lost some internal meta information,
  1033  // leading to corrupted subsequent copies.
  1034  //
  1035  // See https://github.com/ethereum/go-ethereum/issues/20106.
  1036  func TestCopyCopyCommitCopy(t *testing.T) {
  1037  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1038  
  1039  	// Create an account and check if the retrieved balance is correct
  1040  	addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
  1041  	skey := common.HexToHash("aaa")
  1042  	sval := common.HexToHash("bbb")
  1043  
  1044  	state.SetBalance(addr, big.NewInt(42)) // Change the account trie
  1045  	state.SetCode(addr, []byte("hello"))   // Change an external metadata
  1046  	state.SetState(addr, skey, sval)       // Change the storage trie
  1047  
  1048  	if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1049  		t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42)
  1050  	}
  1051  	if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1052  		t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello"))
  1053  	}
  1054  	if val := state.GetState(addr, skey); val != sval {
  1055  		t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval)
  1056  	}
  1057  	if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) {
  1058  		t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{})
  1059  	}
  1060  	// Copy the non-committed state database and check pre/post commit balance
  1061  	copyOne := state.Copy()
  1062  	if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1063  		t.Fatalf("first copy balance mismatch: have %v, want %v", balance, 42)
  1064  	}
  1065  	if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1066  		t.Fatalf("first copy code mismatch: have %x, want %x", code, []byte("hello"))
  1067  	}
  1068  	if val := copyOne.GetState(addr, skey); val != sval {
  1069  		t.Fatalf("first copy non-committed storage slot mismatch: have %x, want %x", val, sval)
  1070  	}
  1071  	if val := copyOne.GetCommittedState(addr, skey); val != (common.Hash{}) {
  1072  		t.Fatalf("first copy committed storage slot mismatch: have %x, want %x", val, common.Hash{})
  1073  	}
  1074  	// Copy the copy and check the balance once more
  1075  	copyTwo := copyOne.Copy()
  1076  	if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1077  		t.Fatalf("second copy pre-commit balance mismatch: have %v, want %v", balance, 42)
  1078  	}
  1079  	if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1080  		t.Fatalf("second copy pre-commit code mismatch: have %x, want %x", code, []byte("hello"))
  1081  	}
  1082  	if val := copyTwo.GetState(addr, skey); val != sval {
  1083  		t.Fatalf("second copy pre-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
  1084  	}
  1085  	if val := copyTwo.GetCommittedState(addr, skey); val != (common.Hash{}) {
  1086  		t.Fatalf("second copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{})
  1087  	}
  1088  	copyTwo.Commit(false)
  1089  	if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1090  		t.Fatalf("second copy post-commit balance mismatch: have %v, want %v", balance, 42)
  1091  	}
  1092  	if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1093  		t.Fatalf("second copy post-commit code mismatch: have %x, want %x", code, []byte("hello"))
  1094  	}
  1095  	if val := copyTwo.GetState(addr, skey); val != sval {
  1096  		t.Fatalf("second copy post-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
  1097  	}
  1098  	if val := copyTwo.GetCommittedState(addr, skey); val != sval {
  1099  		t.Fatalf("second copy post-commit committed storage slot mismatch: have %x, want %x", val, sval)
  1100  	}
  1101  	// Copy the copy-copy and check the balance once more
  1102  	copyThree := copyTwo.Copy()
  1103  	if balance := copyThree.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
  1104  		t.Fatalf("third copy balance mismatch: have %v, want %v", balance, 42)
  1105  	}
  1106  	if code := copyThree.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
  1107  		t.Fatalf("third copy code mismatch: have %x, want %x", code, []byte("hello"))
  1108  	}
  1109  	if val := copyThree.GetState(addr, skey); val != sval {
  1110  		t.Fatalf("third copy non-committed storage slot mismatch: have %x, want %x", val, sval)
  1111  	}
  1112  	if val := copyThree.GetCommittedState(addr, skey); val != sval {
  1113  		t.Fatalf("third copy committed storage slot mismatch: have %x, want %x", val, sval)
  1114  	}
  1115  }
  1116  
  1117  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  1118  // while changing the internals of StateDB. The workflow is that a contract is
  1119  // self-destructed, then in a follow-up transaction (but same block) it's created
  1120  // again and the transaction reverted.
  1121  //
  1122  // The original StateDB implementation flushed dirty objects to the tries after
  1123  // each transaction, so this works ok. The rework accumulated writes in memory
  1124  // first, but the journal wiped the entire state object on create-revert.
  1125  func TestDeleteCreateRevert(t *testing.T) {
  1126  	// Create an initial state with a single contract
  1127  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1128  
  1129  	addr := common.BytesToAddress([]byte("so"))
  1130  	state.SetBalance(addr, big.NewInt(1))
  1131  
  1132  	root, _ := state.Commit(false)
  1133  	state, _ = New(root, state.db, state.snaps)
  1134  
  1135  	// Simulate self-destructing in one transaction, then create-reverting in another
  1136  	state.Suicide(addr)
  1137  	state.Finalise(true)
  1138  
  1139  	id := state.Snapshot()
  1140  	state.SetBalance(addr, big.NewInt(2))
  1141  	state.RevertToSnapshot(id)
  1142  
  1143  	// Commit the entire state and make sure we don't crash and have the correct state
  1144  	root, _ = state.Commit(true)
  1145  	state, _ = New(root, state.db, state.snaps)
  1146  
  1147  	if state.getStateObject(addr) != nil {
  1148  		t.Fatalf("self-destructed contract came alive")
  1149  	}
  1150  }
  1151  
  1152  // TestMissingTrieNodes tests that if the StateDB fails to load parts of the trie,
  1153  // the Commit operation fails with an error
  1154  // If we are missing trie nodes, we should not continue writing to the trie
  1155  func TestMissingTrieNodes(t *testing.T) {
  1156  
  1157  	// Create an initial state with a few accounts
  1158  	memDb := rawdb.NewMemoryDatabase()
  1159  	db := NewDatabase(memDb)
  1160  	var root common.Hash
  1161  	state, _ := New(common.Hash{}, db, nil)
  1162  	addr := common.BytesToAddress([]byte("so"))
  1163  	{
  1164  		state.SetBalance(addr, big.NewInt(1))
  1165  		state.SetCode(addr, []byte{1, 2, 3})
  1166  		a2 := common.BytesToAddress([]byte("another"))
  1167  		state.SetBalance(a2, big.NewInt(100))
  1168  		state.SetCode(a2, []byte{1, 2, 4})
  1169  		root, _ = state.Commit(false)
  1170  		t.Logf("root: %x", root)
  1171  		// force-flush
  1172  		state.Database().TrieDB().Cap(0)
  1173  	}
  1174  	// Create a new state on the old root
  1175  	state, _ = New(root, db, nil)
  1176  	// Now we clear out the memdb
  1177  	it := memDb.NewIterator(nil, nil)
  1178  	for it.Next() {
  1179  		k := it.Key()
  1180  		// Leave the root intact
  1181  		if !bytes.Equal(k, root[:]) {
  1182  			t.Logf("key: %x", k)
  1183  			memDb.Delete(k)
  1184  		}
  1185  	}
  1186  	balance := state.GetBalance(addr)
  1187  	// The removed elem should lead to it returning zero balance
  1188  	if exp, got := uint64(0), balance.Uint64(); got != exp {
  1189  		t.Errorf("expected %d, got %d", exp, got)
  1190  	}
  1191  	// Modify the state
  1192  	state.SetBalance(addr, big.NewInt(2))
  1193  	root, err := state.Commit(false)
  1194  	if err == nil {
  1195  		t.Fatalf("expected error, got root :%x", root)
  1196  	}
  1197  }
  1198  
  1199  func TestStateDBAccessList(t *testing.T) {
  1200  	// Some helpers
  1201  	addr := func(a string) common.Address {
  1202  		return common.HexToAddress(a)
  1203  	}
  1204  	slot := func(a string) common.Hash {
  1205  		return common.HexToHash(a)
  1206  	}
  1207  
  1208  	memDb := rawdb.NewMemoryDatabase()
  1209  	db := NewDatabase(memDb)
  1210  	state, _ := New(common.Hash{}, db, nil)
  1211  	state.accessList = newAccessList()
  1212  
  1213  	verifyAddrs := func(astrings ...string) {
  1214  		t.Helper()
  1215  		// convert to common.Address form
  1216  		var addresses []common.Address
  1217  		var addressMap = make(map[common.Address]struct{})
  1218  		for _, astring := range astrings {
  1219  			address := addr(astring)
  1220  			addresses = append(addresses, address)
  1221  			addressMap[address] = struct{}{}
  1222  		}
  1223  		// Check that the given addresses are in the access list
  1224  		for _, address := range addresses {
  1225  			if !state.AddressInAccessList(address) {
  1226  				t.Fatalf("expected %x to be in access list", address)
  1227  			}
  1228  		}
  1229  		// Check that only the expected addresses are present in the acesslist
  1230  		for address := range state.accessList.addresses {
  1231  			if _, exist := addressMap[address]; !exist {
  1232  				t.Fatalf("extra address %x in access list", address)
  1233  			}
  1234  		}
  1235  	}
  1236  	verifySlots := func(addrString string, slotStrings ...string) {
  1237  		if !state.AddressInAccessList(addr(addrString)) {
  1238  			t.Fatalf("scope missing address/slots %v", addrString)
  1239  		}
  1240  		var address = addr(addrString)
  1241  		// convert to common.Hash form
  1242  		var slots []common.Hash
  1243  		var slotMap = make(map[common.Hash]struct{})
  1244  		for _, slotString := range slotStrings {
  1245  			s := slot(slotString)
  1246  			slots = append(slots, s)
  1247  			slotMap[s] = struct{}{}
  1248  		}
  1249  		// Check that the expected items are in the access list
  1250  		for i, s := range slots {
  1251  			if _, slotPresent := state.SlotInAccessList(address, s); !slotPresent {
  1252  				t.Fatalf("input %d: scope missing slot %v (address %v)", i, s, addrString)
  1253  			}
  1254  		}
  1255  		// Check that no extra elements are in the access list
  1256  		index := state.accessList.addresses[address]
  1257  		if index >= 0 {
  1258  			stateSlots := state.accessList.slots[index]
  1259  			for s := range stateSlots {
  1260  				if _, slotPresent := slotMap[s]; !slotPresent {
  1261  					t.Fatalf("scope has extra slot %v (address %v)", s, addrString)
  1262  				}
  1263  			}
  1264  		}
  1265  	}
  1266  
  1267  	state.AddAddressToAccessList(addr("aa"))          // 1
  1268  	state.AddSlotToAccessList(addr("bb"), slot("01")) // 2,3
  1269  	state.AddSlotToAccessList(addr("bb"), slot("02")) // 4
  1270  	verifyAddrs("aa", "bb")
  1271  	verifySlots("bb", "01", "02")
  1272  
  1273  	// Make a copy
  1274  	stateCopy1 := state.Copy()
  1275  	if exp, got := 4, state.journal.length(); exp != got {
  1276  		t.Fatalf("journal length mismatch: have %d, want %d", got, exp)
  1277  	}
  1278  
  1279  	// same again, should cause no journal entries
  1280  	state.AddSlotToAccessList(addr("bb"), slot("01"))
  1281  	state.AddSlotToAccessList(addr("bb"), slot("02"))
  1282  	state.AddAddressToAccessList(addr("aa"))
  1283  	if exp, got := 4, state.journal.length(); exp != got {
  1284  		t.Fatalf("journal length mismatch: have %d, want %d", got, exp)
  1285  	}
  1286  	// some new ones
  1287  	state.AddSlotToAccessList(addr("bb"), slot("03")) // 5
  1288  	state.AddSlotToAccessList(addr("aa"), slot("01")) // 6
  1289  	state.AddSlotToAccessList(addr("cc"), slot("01")) // 7,8
  1290  	state.AddAddressToAccessList(addr("cc"))
  1291  	if exp, got := 8, state.journal.length(); exp != got {
  1292  		t.Fatalf("journal length mismatch: have %d, want %d", got, exp)
  1293  	}
  1294  
  1295  	verifyAddrs("aa", "bb", "cc")
  1296  	verifySlots("aa", "01")
  1297  	verifySlots("bb", "01", "02", "03")
  1298  	verifySlots("cc", "01")
  1299  
  1300  	// now start rolling back changes
  1301  	state.journal.revert(state, 7)
  1302  	if _, ok := state.SlotInAccessList(addr("cc"), slot("01")); ok {
  1303  		t.Fatalf("slot present, expected missing")
  1304  	}
  1305  	verifyAddrs("aa", "bb", "cc")
  1306  	verifySlots("aa", "01")
  1307  	verifySlots("bb", "01", "02", "03")
  1308  
  1309  	state.journal.revert(state, 6)
  1310  	if state.AddressInAccessList(addr("cc")) {
  1311  		t.Fatalf("addr present, expected missing")
  1312  	}
  1313  	verifyAddrs("aa", "bb")
  1314  	verifySlots("aa", "01")
  1315  	verifySlots("bb", "01", "02", "03")
  1316  
  1317  	state.journal.revert(state, 5)
  1318  	if _, ok := state.SlotInAccessList(addr("aa"), slot("01")); ok {
  1319  		t.Fatalf("slot present, expected missing")
  1320  	}
  1321  	verifyAddrs("aa", "bb")
  1322  	verifySlots("bb", "01", "02", "03")
  1323  
  1324  	state.journal.revert(state, 4)
  1325  	if _, ok := state.SlotInAccessList(addr("bb"), slot("03")); ok {
  1326  		t.Fatalf("slot present, expected missing")
  1327  	}
  1328  	verifyAddrs("aa", "bb")
  1329  	verifySlots("bb", "01", "02")
  1330  
  1331  	state.journal.revert(state, 3)
  1332  	if _, ok := state.SlotInAccessList(addr("bb"), slot("02")); ok {
  1333  		t.Fatalf("slot present, expected missing")
  1334  	}
  1335  	verifyAddrs("aa", "bb")
  1336  	verifySlots("bb", "01")
  1337  
  1338  	state.journal.revert(state, 2)
  1339  	if _, ok := state.SlotInAccessList(addr("bb"), slot("01")); ok {
  1340  		t.Fatalf("slot present, expected missing")
  1341  	}
  1342  	verifyAddrs("aa", "bb")
  1343  
  1344  	state.journal.revert(state, 1)
  1345  	if state.AddressInAccessList(addr("bb")) {
  1346  		t.Fatalf("addr present, expected missing")
  1347  	}
  1348  	verifyAddrs("aa")
  1349  
  1350  	state.journal.revert(state, 0)
  1351  	if state.AddressInAccessList(addr("aa")) {
  1352  		t.Fatalf("addr present, expected missing")
  1353  	}
  1354  	if got, exp := len(state.accessList.addresses), 0; got != exp {
  1355  		t.Fatalf("expected empty, got %d", got)
  1356  	}
  1357  	if got, exp := len(state.accessList.slots), 0; got != exp {
  1358  		t.Fatalf("expected empty, got %d", got)
  1359  	}
  1360  	// Check the copy
  1361  	// Make a copy
  1362  	state = stateCopy1
  1363  	verifyAddrs("aa", "bb")
  1364  	verifySlots("bb", "01", "02")
  1365  	if got, exp := len(state.accessList.addresses), 2; got != exp {
  1366  		t.Fatalf("expected empty, got %d", got)
  1367  	}
  1368  	if got, exp := len(state.accessList.slots), 1; got != exp {
  1369  		t.Fatalf("expected empty, got %d", got)
  1370  	}
  1371  }