github.com/Night-mk/quorum@v21.1.0+incompatible/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/ethereum/go-ethereum/private/engine"
    33  
    34  	"gopkg.in/check.v1"
    35  
    36  	"github.com/ethereum/go-ethereum/common"
    37  	"github.com/ethereum/go-ethereum/core/rawdb"
    38  	"github.com/ethereum/go-ethereum/core/types"
    39  )
    40  
    41  // Tests that updating a state trie does not leak any database writes prior to
    42  // actually committing the state.
    43  func TestUpdateLeaks(t *testing.T) {
    44  	// Create an empty state database
    45  	db := rawdb.NewMemoryDatabase()
    46  	state, _ := New(common.Hash{}, NewDatabase(db))
    47  
    48  	// Update it with some accounts
    49  	for i := byte(0); i < 255; i++ {
    50  		addr := common.BytesToAddress([]byte{i})
    51  		state.AddBalance(addr, big.NewInt(int64(11*i)))
    52  		state.SetNonce(addr, uint64(42*i))
    53  		if i%2 == 0 {
    54  			state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
    55  		}
    56  		if i%3 == 0 {
    57  			state.SetCode(addr, []byte{i, i, i, i, i})
    58  		}
    59  	}
    60  
    61  	root := state.IntermediateRoot(false)
    62  	if err := state.Database().TrieDB().Commit(root, false); err != nil {
    63  		t.Errorf("can not commit trie %v to persistent database", root.Hex())
    64  	}
    65  
    66  	// Ensure that no data was leaked into the database
    67  	it := db.NewIterator()
    68  	for it.Next() {
    69  		t.Errorf("State leaked into database: %x -> %x", it.Key(), it.Value())
    70  	}
    71  	it.Release()
    72  }
    73  
    74  // Tests that no intermediate state of an object is stored into the database,
    75  // only the one right before the commit.
    76  func TestIntermediateLeaks(t *testing.T) {
    77  	// Create two state databases, one transitioning to the final state, the other final from the beginning
    78  	transDb := rawdb.NewMemoryDatabase()
    79  	finalDb := rawdb.NewMemoryDatabase()
    80  	transState, _ := New(common.Hash{}, NewDatabase(transDb))
    81  	finalState, _ := New(common.Hash{}, NewDatabase(finalDb))
    82  
    83  	modify := func(state *StateDB, addr common.Address, i, tweak byte) {
    84  		state.SetBalance(addr, big.NewInt(int64(11*i)+int64(tweak)))
    85  		state.SetNonce(addr, uint64(42*i+tweak))
    86  		if i%2 == 0 {
    87  			state.SetState(addr, common.Hash{i, i, i, 0}, common.Hash{})
    88  			state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak})
    89  		}
    90  		if i%3 == 0 {
    91  			state.SetCode(addr, []byte{i, i, i, i, i, tweak})
    92  		}
    93  	}
    94  
    95  	// Modify the transient state.
    96  	for i := byte(0); i < 255; i++ {
    97  		modify(transState, common.Address{i}, i, 0)
    98  	}
    99  	// Write modifications to trie.
   100  	transState.IntermediateRoot(false)
   101  
   102  	// Overwrite all the data with new values in the transient database.
   103  	for i := byte(0); i < 255; i++ {
   104  		modify(transState, common.Address{i}, i, 99)
   105  		modify(finalState, common.Address{i}, i, 99)
   106  	}
   107  
   108  	// Commit and cross check the databases.
   109  	transRoot, err := transState.Commit(false)
   110  	if err != nil {
   111  		t.Fatalf("failed to commit transition state: %v", err)
   112  	}
   113  	if err = transState.Database().TrieDB().Commit(transRoot, false); err != nil {
   114  		t.Errorf("can not commit trie %v to persistent database", transRoot.Hex())
   115  	}
   116  
   117  	finalRoot, err := finalState.Commit(false)
   118  	if err != nil {
   119  		t.Fatalf("failed to commit final state: %v", err)
   120  	}
   121  	if err = finalState.Database().TrieDB().Commit(finalRoot, false); err != nil {
   122  		t.Errorf("can not commit trie %v to persistent database", finalRoot.Hex())
   123  	}
   124  
   125  	it := finalDb.NewIterator()
   126  	for it.Next() {
   127  		key, fvalue := it.Key(), it.Value()
   128  		tvalue, err := transDb.Get(key)
   129  		if err != nil {
   130  			t.Errorf("entry missing from the transition database: %x -> %x", key, fvalue)
   131  		}
   132  		if !bytes.Equal(fvalue, tvalue) {
   133  			t.Errorf("the value associate key %x is mismatch,: %x in transition database ,%x in final database", key, tvalue, fvalue)
   134  		}
   135  	}
   136  	it.Release()
   137  
   138  	it = transDb.NewIterator()
   139  	for it.Next() {
   140  		key, tvalue := it.Key(), it.Value()
   141  		fvalue, err := finalDb.Get(key)
   142  		if err != nil {
   143  			t.Errorf("extra entry in the transition database: %x -> %x", key, it.Value())
   144  		}
   145  		if !bytes.Equal(fvalue, tvalue) {
   146  			t.Errorf("the value associate key %x is mismatch,: %x in transition database ,%x in final database", key, tvalue, fvalue)
   147  		}
   148  	}
   149  }
   150  
   151  func TestStorageRoot(t *testing.T) {
   152  	var (
   153  		mem      = rawdb.NewMemoryDatabase()
   154  		db       = NewDatabase(mem)
   155  		state, _ = New(common.Hash{}, db)
   156  		addr     = common.Address{1}
   157  		key      = common.Hash{1}
   158  		value    = common.Hash{42}
   159  
   160  		empty = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
   161  	)
   162  
   163  	so := state.GetOrNewStateObject(addr)
   164  
   165  	emptyRoot := so.storageRoot(db)
   166  	if emptyRoot != empty {
   167  		t.Errorf("Invalid empty storage root, expected %x, got %x", empty, emptyRoot)
   168  	}
   169  
   170  	// add a bit of state
   171  	so.SetState(db, key, value)
   172  	state.Commit(false)
   173  
   174  	root := so.storageRoot(db)
   175  	expected := common.HexToHash("63511abd258fa907afa30cb118b53744a4f49055bb3f531da512c6b866fc2ffb")
   176  
   177  	if expected != root {
   178  		t.Errorf("Invalid storage root, expected %x, got %x", expected, root)
   179  	}
   180  }
   181  
   182  // TestCopy tests that copying a statedb object indeed makes the original and
   183  // the copy independent of each other. This test is a regression test against
   184  // https://github.com/ethereum/go-ethereum/pull/15549.
   185  func TestCopy(t *testing.T) {
   186  	// Create a random state test to copy and modify "independently"
   187  	orig, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
   188  
   189  	for i := byte(0); i < 255; i++ {
   190  		obj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   191  		obj.AddBalance(big.NewInt(int64(i)))
   192  		orig.updateStateObject(obj)
   193  	}
   194  	orig.Finalise(false)
   195  
   196  	// Copy the state
   197  	copy := orig.Copy()
   198  
   199  	// Copy the copy state
   200  	ccopy := copy.Copy()
   201  
   202  	// modify all in memory
   203  	for i := byte(0); i < 255; i++ {
   204  		origObj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   205  		copyObj := copy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   206  		ccopyObj := ccopy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   207  
   208  		origObj.AddBalance(big.NewInt(2 * int64(i)))
   209  		copyObj.AddBalance(big.NewInt(3 * int64(i)))
   210  		ccopyObj.AddBalance(big.NewInt(4 * int64(i)))
   211  
   212  		orig.updateStateObject(origObj)
   213  		copy.updateStateObject(copyObj)
   214  		ccopy.updateStateObject(copyObj)
   215  	}
   216  
   217  	// Finalise the changes on all concurrently
   218  	finalise := func(wg *sync.WaitGroup, db *StateDB) {
   219  		defer wg.Done()
   220  		db.Finalise(true)
   221  	}
   222  
   223  	var wg sync.WaitGroup
   224  	wg.Add(3)
   225  	go finalise(&wg, orig)
   226  	go finalise(&wg, copy)
   227  	go finalise(&wg, ccopy)
   228  	wg.Wait()
   229  
   230  	// Verify that the three states have been updated independently
   231  	for i := byte(0); i < 255; i++ {
   232  		origObj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   233  		copyObj := copy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   234  		ccopyObj := ccopy.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
   235  
   236  		if want := big.NewInt(3 * int64(i)); origObj.Balance().Cmp(want) != 0 {
   237  			t.Errorf("orig obj %d: balance mismatch: have %v, want %v", i, origObj.Balance(), want)
   238  		}
   239  		if want := big.NewInt(4 * int64(i)); copyObj.Balance().Cmp(want) != 0 {
   240  			t.Errorf("copy obj %d: balance mismatch: have %v, want %v", i, copyObj.Balance(), want)
   241  		}
   242  		if want := big.NewInt(5 * int64(i)); ccopyObj.Balance().Cmp(want) != 0 {
   243  			t.Errorf("copy obj %d: balance mismatch: have %v, want %v", i, ccopyObj.Balance(), want)
   244  		}
   245  	}
   246  }
   247  
   248  func TestSnapshotRandom(t *testing.T) {
   249  	config := &quick.Config{MaxCount: 1000}
   250  	err := quick.Check((*snapshotTest).run, config)
   251  	if cerr, ok := err.(*quick.CheckError); ok {
   252  		test := cerr.In[0].(*snapshotTest)
   253  		t.Errorf("%v:\n%s", test.err, test)
   254  	} else if err != nil {
   255  		t.Error(err)
   256  	}
   257  }
   258  
   259  // A snapshotTest checks that reverting StateDB snapshots properly undoes all changes
   260  // captured by the snapshot. Instances of this test with pseudorandom content are created
   261  // by Generate.
   262  //
   263  // The test works as follows:
   264  //
   265  // A new state is created and all actions are applied to it. Several snapshots are taken
   266  // in between actions. The test then reverts each snapshot. For each snapshot the actions
   267  // leading up to it are replayed on a fresh, empty state. The behaviour of all public
   268  // accessor methods on the reverted state must match the return value of the equivalent
   269  // methods on the replayed state.
   270  type snapshotTest struct {
   271  	addrs     []common.Address // all account addresses
   272  	actions   []testAction     // modifications to the state
   273  	snapshots []int            // actions indexes at which snapshot is taken
   274  	err       error            // failure details are reported through this field
   275  }
   276  
   277  type testAction struct {
   278  	name   string
   279  	fn     func(testAction, *StateDB)
   280  	args   []int64
   281  	noAddr bool
   282  }
   283  
   284  // newTestAction creates a random action that changes state.
   285  func newTestAction(addr common.Address, r *rand.Rand) testAction {
   286  	actions := []testAction{
   287  		{
   288  			name: "SetBalance",
   289  			fn: func(a testAction, s *StateDB) {
   290  				s.SetBalance(addr, big.NewInt(a.args[0]))
   291  			},
   292  			args: make([]int64, 1),
   293  		},
   294  		{
   295  			name: "AddBalance",
   296  			fn: func(a testAction, s *StateDB) {
   297  				s.AddBalance(addr, big.NewInt(a.args[0]))
   298  			},
   299  			args: make([]int64, 1),
   300  		},
   301  		{
   302  			name: "SetNonce",
   303  			fn: func(a testAction, s *StateDB) {
   304  				s.SetNonce(addr, uint64(a.args[0]))
   305  			},
   306  			args: make([]int64, 1),
   307  		},
   308  		{
   309  			name: "SetState",
   310  			fn: func(a testAction, s *StateDB) {
   311  				var key, val common.Hash
   312  				binary.BigEndian.PutUint16(key[:], uint16(a.args[0]))
   313  				binary.BigEndian.PutUint16(val[:], uint16(a.args[1]))
   314  				s.SetState(addr, key, val)
   315  			},
   316  			args: make([]int64, 2),
   317  		},
   318  		{
   319  			name: "SetCode",
   320  			fn: func(a testAction, s *StateDB) {
   321  				code := make([]byte, 16)
   322  				binary.BigEndian.PutUint64(code, uint64(a.args[0]))
   323  				binary.BigEndian.PutUint64(code[8:], uint64(a.args[1]))
   324  				s.SetCode(addr, code)
   325  			},
   326  			args: make([]int64, 2),
   327  		},
   328  		{
   329  			name: "SetPrivacyMetadata",
   330  			fn: func(a testAction, s *StateDB) {
   331  
   332  				privFlag := engine.PrivacyFlagType((uint64(a.args[0])%2)*2 + 1) // the only possible values should be 1 and 3
   333  				b := make([]byte, 8)
   334  				binary.BigEndian.PutUint64(b, uint64(a.args[1]))
   335  				hash := common.BytesToEncryptedPayloadHash(b)
   336  
   337  				s.SetPrivacyMetadata(addr, &PrivacyMetadata{
   338  					CreationTxHash: hash,
   339  					PrivacyFlag:    privFlag,
   340  				})
   341  			},
   342  			args: make([]int64, 2),
   343  		},
   344  		{
   345  			name: "CreateAccount",
   346  			fn: func(a testAction, s *StateDB) {
   347  				s.CreateAccount(addr)
   348  			},
   349  		},
   350  		{
   351  			name: "Suicide",
   352  			fn: func(a testAction, s *StateDB) {
   353  				s.Suicide(addr)
   354  			},
   355  		},
   356  		{
   357  			name: "AddRefund",
   358  			fn: func(a testAction, s *StateDB) {
   359  				s.AddRefund(uint64(a.args[0]))
   360  			},
   361  			args:   make([]int64, 1),
   362  			noAddr: true,
   363  		},
   364  		{
   365  			name: "AddLog",
   366  			fn: func(a testAction, s *StateDB) {
   367  				data := make([]byte, 2)
   368  				binary.BigEndian.PutUint16(data, uint16(a.args[0]))
   369  				s.AddLog(&types.Log{Address: addr, Data: data})
   370  			},
   371  			args: make([]int64, 1),
   372  		},
   373  		{
   374  			name: "AddPreimage",
   375  			fn: func(a testAction, s *StateDB) {
   376  				preimage := []byte{1}
   377  				hash := common.BytesToHash(preimage)
   378  				s.AddPreimage(hash, preimage)
   379  			},
   380  			args: make([]int64, 1),
   381  		},
   382  	}
   383  	action := actions[r.Intn(len(actions))]
   384  	var nameargs []string
   385  	if !action.noAddr {
   386  		nameargs = append(nameargs, addr.Hex())
   387  	}
   388  	for i := range action.args {
   389  		action.args[i] = rand.Int63n(100)
   390  		nameargs = append(nameargs, fmt.Sprint(action.args[i]))
   391  	}
   392  	action.name += strings.Join(nameargs, ", ")
   393  	return action
   394  }
   395  
   396  // Generate returns a new snapshot test of the given size. All randomness is
   397  // derived from r.
   398  func (*snapshotTest) Generate(r *rand.Rand, size int) reflect.Value {
   399  	// Generate random actions.
   400  	addrs := make([]common.Address, 50)
   401  	for i := range addrs {
   402  		addrs[i][0] = byte(i)
   403  	}
   404  	actions := make([]testAction, size)
   405  	for i := range actions {
   406  		addr := addrs[r.Intn(len(addrs))]
   407  		actions[i] = newTestAction(addr, r)
   408  	}
   409  	// Generate snapshot indexes.
   410  	nsnapshots := int(math.Sqrt(float64(size)))
   411  	if size > 0 && nsnapshots == 0 {
   412  		nsnapshots = 1
   413  	}
   414  	snapshots := make([]int, nsnapshots)
   415  	snaplen := len(actions) / nsnapshots
   416  	for i := range snapshots {
   417  		// Try to place the snapshots some number of actions apart from each other.
   418  		snapshots[i] = (i * snaplen) + r.Intn(snaplen)
   419  	}
   420  	return reflect.ValueOf(&snapshotTest{addrs, actions, snapshots, nil})
   421  }
   422  
   423  func (test *snapshotTest) String() string {
   424  	out := new(bytes.Buffer)
   425  	sindex := 0
   426  	for i, action := range test.actions {
   427  		if len(test.snapshots) > sindex && i == test.snapshots[sindex] {
   428  			fmt.Fprintf(out, "---- snapshot %d ----\n", sindex)
   429  			sindex++
   430  		}
   431  		fmt.Fprintf(out, "%4d: %s\n", i, action.name)
   432  	}
   433  	return out.String()
   434  }
   435  
   436  func (test *snapshotTest) run() bool {
   437  	// Run all actions and create snapshots.
   438  	var (
   439  		state, _     = New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
   440  		snapshotRevs = make([]int, len(test.snapshots))
   441  		sindex       = 0
   442  	)
   443  	for i, action := range test.actions {
   444  		if len(test.snapshots) > sindex && i == test.snapshots[sindex] {
   445  			snapshotRevs[sindex] = state.Snapshot()
   446  			sindex++
   447  		}
   448  		action.fn(action, state)
   449  	}
   450  	// Revert all snapshots in reverse order. Each revert must yield a state
   451  	// that is equivalent to fresh state with all actions up the snapshot applied.
   452  	for sindex--; sindex >= 0; sindex-- {
   453  		checkstate, _ := New(common.Hash{}, state.Database())
   454  		for _, action := range test.actions[:test.snapshots[sindex]] {
   455  			action.fn(action, checkstate)
   456  		}
   457  		state.RevertToSnapshot(snapshotRevs[sindex])
   458  		if err := test.checkEqual(state, checkstate); err != nil {
   459  			test.err = fmt.Errorf("state mismatch after revert to snapshot %d\n%v", sindex, err)
   460  			return false
   461  		}
   462  	}
   463  	return true
   464  }
   465  
   466  // checkEqual checks that methods of state and checkstate return the same values.
   467  func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
   468  	for _, addr := range test.addrs {
   469  		var err error
   470  		checkeq := func(op string, a, b interface{}) bool {
   471  			if err == nil && !reflect.DeepEqual(a, b) {
   472  				err = fmt.Errorf("got %s(%s) == %v, want %v", op, addr.Hex(), a, b)
   473  				return false
   474  			}
   475  			return true
   476  		}
   477  		// Check basic accessor methods.
   478  		checkeq("Exist", state.Exist(addr), checkstate.Exist(addr))
   479  		checkeq("HasSuicided", state.HasSuicided(addr), checkstate.HasSuicided(addr))
   480  		checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr))
   481  		checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr))
   482  		checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr))
   483  		checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr))
   484  		checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr))
   485  		statePM, _ := state.GetPrivacyMetadata(addr)
   486  		checkStatePM, _ := checkstate.GetPrivacyMetadata(addr)
   487  		checkeq("GetPrivacyMetadata", statePM, checkStatePM)
   488  		// Check storage.
   489  		if obj := state.getStateObject(addr); obj != nil {
   490  			state.ForEachStorage(addr, func(key, value common.Hash) bool {
   491  				return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value)
   492  			})
   493  			checkstate.ForEachStorage(addr, func(key, value common.Hash) bool {
   494  				return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value)
   495  			})
   496  		}
   497  		if err != nil {
   498  			return err
   499  		}
   500  	}
   501  
   502  	if state.GetRefund() != checkstate.GetRefund() {
   503  		return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
   504  			state.GetRefund(), checkstate.GetRefund())
   505  	}
   506  	if !reflect.DeepEqual(state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) {
   507  		return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v",
   508  			state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{}))
   509  	}
   510  	return nil
   511  }
   512  
   513  func (s *StateSuite) TestTouchDelete(c *check.C) {
   514  	s.state.GetOrNewStateObject(common.Address{})
   515  	root, _ := s.state.Commit(false)
   516  	s.state.Reset(root)
   517  
   518  	snapshot := s.state.Snapshot()
   519  	s.state.AddBalance(common.Address{}, new(big.Int))
   520  
   521  	if len(s.state.journal.dirties) != 1 {
   522  		c.Fatal("expected one dirty state object")
   523  	}
   524  	s.state.RevertToSnapshot(snapshot)
   525  	if len(s.state.journal.dirties) != 0 {
   526  		c.Fatal("expected no dirty state object")
   527  	}
   528  }
   529  
   530  // TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
   531  // See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
   532  func TestCopyOfCopy(t *testing.T) {
   533  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
   534  	addr := common.HexToAddress("aaaa")
   535  	state.SetBalance(addr, big.NewInt(42))
   536  
   537  	if got := state.Copy().GetBalance(addr).Uint64(); got != 42 {
   538  		t.Fatalf("1st copy fail, expected 42, got %v", got)
   539  	}
   540  	if got := state.Copy().Copy().GetBalance(addr).Uint64(); got != 42 {
   541  		t.Fatalf("2nd copy fail, expected 42, got %v", got)
   542  	}
   543  }
   544  
   545  // Tests a regression where committing a copy lost some internal meta information,
   546  // leading to corrupted subsequent copies.
   547  //
   548  // See https://github.com/ethereum/go-ethereum/issues/20106.
   549  func TestCopyCommitCopy(t *testing.T) {
   550  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
   551  
   552  	// Create an account and check if the retrieved balance is correct
   553  	addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
   554  	skey := common.HexToHash("aaa")
   555  	sval := common.HexToHash("bbb")
   556  
   557  	state.SetBalance(addr, big.NewInt(42)) // Change the account trie
   558  	state.SetCode(addr, []byte("hello"))   // Change an external metadata
   559  	state.SetState(addr, skey, sval)       // Change the storage trie
   560  
   561  	if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   562  		t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42)
   563  	}
   564  	if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   565  		t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello"))
   566  	}
   567  	if val := state.GetState(addr, skey); val != sval {
   568  		t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval)
   569  	}
   570  	if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) {
   571  		t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{})
   572  	}
   573  	// Copy the non-committed state database and check pre/post commit balance
   574  	copyOne := state.Copy()
   575  	if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   576  		t.Fatalf("first copy pre-commit balance mismatch: have %v, want %v", balance, 42)
   577  	}
   578  	if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   579  		t.Fatalf("first copy pre-commit code mismatch: have %x, want %x", code, []byte("hello"))
   580  	}
   581  	if val := copyOne.GetState(addr, skey); val != sval {
   582  		t.Fatalf("first copy pre-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
   583  	}
   584  	if val := copyOne.GetCommittedState(addr, skey); val != (common.Hash{}) {
   585  		t.Fatalf("first copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{})
   586  	}
   587  
   588  	copyOne.Commit(false)
   589  	if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   590  		t.Fatalf("first copy post-commit balance mismatch: have %v, want %v", balance, 42)
   591  	}
   592  	if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   593  		t.Fatalf("first copy post-commit code mismatch: have %x, want %x", code, []byte("hello"))
   594  	}
   595  	if val := copyOne.GetState(addr, skey); val != sval {
   596  		t.Fatalf("first copy post-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
   597  	}
   598  	if val := copyOne.GetCommittedState(addr, skey); val != sval {
   599  		t.Fatalf("first copy post-commit committed storage slot mismatch: have %x, want %x", val, sval)
   600  	}
   601  	// Copy the copy and check the balance once more
   602  	copyTwo := copyOne.Copy()
   603  	if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   604  		t.Fatalf("second copy balance mismatch: have %v, want %v", balance, 42)
   605  	}
   606  	if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   607  		t.Fatalf("second copy code mismatch: have %x, want %x", code, []byte("hello"))
   608  	}
   609  	if val := copyTwo.GetState(addr, skey); val != sval {
   610  		t.Fatalf("second copy non-committed storage slot mismatch: have %x, want %x", val, sval)
   611  	}
   612  	if val := copyTwo.GetCommittedState(addr, skey); val != sval {
   613  		t.Fatalf("second copy post-commit committed storage slot mismatch: have %x, want %x", val, sval)
   614  	}
   615  }
   616  
   617  // Tests a regression where committing a copy lost some internal meta information,
   618  // leading to corrupted subsequent copies.
   619  //
   620  // See https://github.com/ethereum/go-ethereum/issues/20106.
   621  func TestCopyCopyCommitCopy(t *testing.T) {
   622  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
   623  
   624  	// Create an account and check if the retrieved balance is correct
   625  	addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
   626  	skey := common.HexToHash("aaa")
   627  	sval := common.HexToHash("bbb")
   628  
   629  	state.SetBalance(addr, big.NewInt(42)) // Change the account trie
   630  	state.SetCode(addr, []byte("hello"))   // Change an external metadata
   631  	state.SetState(addr, skey, sval)       // Change the storage trie
   632  
   633  	if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   634  		t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42)
   635  	}
   636  	if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   637  		t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello"))
   638  	}
   639  	if val := state.GetState(addr, skey); val != sval {
   640  		t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval)
   641  	}
   642  	if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) {
   643  		t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{})
   644  	}
   645  	// Copy the non-committed state database and check pre/post commit balance
   646  	copyOne := state.Copy()
   647  	if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   648  		t.Fatalf("first copy balance mismatch: have %v, want %v", balance, 42)
   649  	}
   650  	if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   651  		t.Fatalf("first copy code mismatch: have %x, want %x", code, []byte("hello"))
   652  	}
   653  	if val := copyOne.GetState(addr, skey); val != sval {
   654  		t.Fatalf("first copy non-committed storage slot mismatch: have %x, want %x", val, sval)
   655  	}
   656  	if val := copyOne.GetCommittedState(addr, skey); val != (common.Hash{}) {
   657  		t.Fatalf("first copy committed storage slot mismatch: have %x, want %x", val, common.Hash{})
   658  	}
   659  	// Copy the copy and check the balance once more
   660  	copyTwo := copyOne.Copy()
   661  	if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   662  		t.Fatalf("second copy pre-commit balance mismatch: have %v, want %v", balance, 42)
   663  	}
   664  	if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   665  		t.Fatalf("second copy pre-commit code mismatch: have %x, want %x", code, []byte("hello"))
   666  	}
   667  	if val := copyTwo.GetState(addr, skey); val != sval {
   668  		t.Fatalf("second copy pre-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
   669  	}
   670  	if val := copyTwo.GetCommittedState(addr, skey); val != (common.Hash{}) {
   671  		t.Fatalf("second copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{})
   672  	}
   673  	copyTwo.Commit(false)
   674  	if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   675  		t.Fatalf("second copy post-commit balance mismatch: have %v, want %v", balance, 42)
   676  	}
   677  	if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   678  		t.Fatalf("second copy post-commit code mismatch: have %x, want %x", code, []byte("hello"))
   679  	}
   680  	if val := copyTwo.GetState(addr, skey); val != sval {
   681  		t.Fatalf("second copy post-commit non-committed storage slot mismatch: have %x, want %x", val, sval)
   682  	}
   683  	if val := copyTwo.GetCommittedState(addr, skey); val != sval {
   684  		t.Fatalf("second copy post-commit committed storage slot mismatch: have %x, want %x", val, sval)
   685  	}
   686  	// Copy the copy-copy and check the balance once more
   687  	copyThree := copyTwo.Copy()
   688  	if balance := copyThree.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
   689  		t.Fatalf("third copy balance mismatch: have %v, want %v", balance, 42)
   690  	}
   691  	if code := copyThree.GetCode(addr); !bytes.Equal(code, []byte("hello")) {
   692  		t.Fatalf("third copy code mismatch: have %x, want %x", code, []byte("hello"))
   693  	}
   694  	if val := copyThree.GetState(addr, skey); val != sval {
   695  		t.Fatalf("third copy non-committed storage slot mismatch: have %x, want %x", val, sval)
   696  	}
   697  	if val := copyThree.GetCommittedState(addr, skey); val != sval {
   698  		t.Fatalf("third copy committed storage slot mismatch: have %x, want %x", val, sval)
   699  	}
   700  }
   701  
   702  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
   703  // while changing the internals of statedb. The workflow is that a contract is
   704  // self destructed, then in a followup transaction (but same block) it's created
   705  // again and the transaction reverted.
   706  //
   707  // The original statedb implementation flushed dirty objects to the tries after
   708  // each transaction, so this works ok. The rework accumulated writes in memory
   709  // first, but the journal wiped the entire state object on create-revert.
   710  func TestDeleteCreateRevert(t *testing.T) {
   711  	// Create an initial state with a single contract
   712  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
   713  
   714  	addr := toAddr([]byte("so"))
   715  	state.SetBalance(addr, big.NewInt(1))
   716  
   717  	root, _ := state.Commit(false)
   718  	state.Reset(root)
   719  
   720  	// Simulate self-destructing in one transaction, then create-reverting in another
   721  	state.Suicide(addr)
   722  	state.Finalise(true)
   723  
   724  	id := state.Snapshot()
   725  	state.SetBalance(addr, big.NewInt(2))
   726  	state.RevertToSnapshot(id)
   727  
   728  	// Commit the entire state and make sure we don't crash and have the correct state
   729  	root, _ = state.Commit(true)
   730  	state.Reset(root)
   731  
   732  	if state.getStateObject(addr) != nil {
   733  		t.Fatalf("self-destructed contract came alive")
   734  	}
   735  }
   736  
   737  // Quorum - Privacy Enhancements
   738  func TestPrivacyMetadataIsSavedOnStateDbCommit(t *testing.T) {
   739  	ethDb := rawdb.NewMemoryDatabase()
   740  	stateDb := NewDatabase(ethDb)
   741  	state, _ := New(common.Hash{}, stateDb)
   742  
   743  	addr := common.Address{1}
   744  	state.CreateAccount(addr)
   745  
   746  	state.SetNonce(addr, uint64(1))
   747  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   748  		PrivacyFlag:    engine.PrivacyFlagPartyProtection,
   749  		CreationTxHash: common.EncryptedPayloadHash{1},
   750  	})
   751  
   752  	privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr)
   753  	if privMetaData != nil {
   754  		t.Errorf("privacy metadata should not have been stored before commit")
   755  	}
   756  
   757  	state.Commit(false)
   758  
   759  	privMetaData, _ = state.GetCommittedStatePrivacyMetadata(addr)
   760  	if privMetaData == nil {
   761  		t.Errorf("privacy metadata should have been stored during commit")
   762  	}
   763  }
   764  
   765  func TestPrivacyMetadataIsUpdatedOnAccountReCreateWithDifferentPrivacyMetadata(t *testing.T) {
   766  	ethDb := rawdb.NewMemoryDatabase()
   767  	stateDb := NewDatabase(ethDb)
   768  	state, _ := New(common.Hash{}, stateDb)
   769  
   770  	addr := common.Address{1}
   771  	state.CreateAccount(addr)
   772  
   773  	state.SetNonce(addr, uint64(1))
   774  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   775  		PrivacyFlag:    engine.PrivacyFlagPartyProtection,
   776  		CreationTxHash: common.EncryptedPayloadHash{1},
   777  	})
   778  	state.Commit(false)
   779  
   780  	privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr)
   781  	if privMetaData == nil {
   782  		t.Errorf("privacy metadata should have been stored during commit")
   783  	}
   784  
   785  	state.CreateAccount(addr)
   786  	state.SetNonce(addr, uint64(1))
   787  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   788  		PrivacyFlag:    engine.PrivacyFlagStateValidation,
   789  		CreationTxHash: common.EncryptedPayloadHash{1},
   790  	})
   791  
   792  	state.Commit(false)
   793  
   794  	privMetaData, _ = state.GetCommittedStatePrivacyMetadata(addr)
   795  	if privMetaData == nil {
   796  		t.Errorf("privacy metadata should have been updated during commit")
   797  	} else if privMetaData.PrivacyFlag != engine.PrivacyFlagStateValidation {
   798  		t.Errorf("privacy metadata should have StateValidation as the the privacy flag")
   799  	}
   800  }
   801  
   802  func TestPrivacyMetadataIsRemovedOnAccountSuicide(t *testing.T) {
   803  	ethDb := rawdb.NewMemoryDatabase()
   804  	stateDb := NewDatabase(ethDb)
   805  	state, _ := New(common.Hash{}, stateDb)
   806  
   807  	addr := common.Address{1}
   808  	state.CreateAccount(addr)
   809  
   810  	state.SetNonce(addr, uint64(1))
   811  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   812  		PrivacyFlag:    engine.PrivacyFlagPartyProtection,
   813  		CreationTxHash: common.EncryptedPayloadHash{1},
   814  	})
   815  	state.Commit(false)
   816  
   817  	privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr)
   818  	if privMetaData == nil {
   819  		t.Errorf("privacy metadata should have been stored during commit")
   820  	}
   821  
   822  	state.Suicide(addr)
   823  	state.Commit(false)
   824  
   825  	privMetaData, _ = state.GetCommittedStatePrivacyMetadata(addr)
   826  	if privMetaData != nil {
   827  		t.Errorf("privacy metadata should have been deleted during account suicide")
   828  	}
   829  }
   830  
   831  func TestPrivacyMetadataChangesAreRolledBackOnRevert(t *testing.T) {
   832  	ethDb := rawdb.NewMemoryDatabase()
   833  	stateDb := NewDatabase(ethDb)
   834  	state, _ := New(common.Hash{}, stateDb)
   835  
   836  	addr := common.Address{1}
   837  	state.CreateAccount(addr)
   838  
   839  	state.SetNonce(addr, uint64(1))
   840  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   841  		PrivacyFlag:    engine.PrivacyFlagPartyProtection,
   842  		CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("one")),
   843  	})
   844  	state.Commit(false)
   845  
   846  	privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr)
   847  	if privMetaData == nil {
   848  		t.Errorf("privacy metadata should have been stored during commit")
   849  	}
   850  
   851  	// update privacy metadata
   852  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   853  		PrivacyFlag:    engine.PrivacyFlagStateValidation,
   854  		CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("two")),
   855  	})
   856  
   857  	// record the snapshot
   858  	snapshot := state.Snapshot()
   859  
   860  	privMetaData, _ = state.GetPrivacyMetadata(addr)
   861  	if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("two")) {
   862  		t.Errorf("current privacy metadata creation tx hash does not match the expected value")
   863  	}
   864  
   865  	// update the metadata
   866  	state.SetPrivacyMetadata(addr, &PrivacyMetadata{
   867  		PrivacyFlag:    engine.PrivacyFlagStateValidation,
   868  		CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("three")),
   869  	})
   870  
   871  	privMetaData, _ = state.GetPrivacyMetadata(addr)
   872  	if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("three")) {
   873  		t.Errorf("current privacy metadata creation tx hash does not match the expected value")
   874  	}
   875  
   876  	// revert to snapshot
   877  	state.RevertToSnapshot(snapshot)
   878  
   879  	privMetaData, _ = state.GetPrivacyMetadata(addr)
   880  	if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("two")) {
   881  		t.Errorf("current privacy metadata creation tx hash does not match the expected value")
   882  	}
   883  
   884  }
   885  
   886  // End Quorum - Privacy Enhancements