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