github.com/MetalBlockchain/subnet-evm@v0.4.9/core/state/trie_prefetcher_test.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2021 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package state
    28  
    29  import (
    30  	"math/big"
    31  	"testing"
    32  	"time"
    33  
    34  	"github.com/MetalBlockchain/subnet-evm/core/rawdb"
    35  	"github.com/ethereum/go-ethereum/common"
    36  )
    37  
    38  func filledStateDB() *StateDB {
    39  	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
    40  
    41  	// Create an account and check if the retrieved balance is correct
    42  	addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
    43  	skey := common.HexToHash("aaa")
    44  	sval := common.HexToHash("bbb")
    45  
    46  	state.SetBalance(addr, big.NewInt(42)) // Change the account trie
    47  	state.SetCode(addr, []byte("hello"))   // Change an external metadata
    48  	state.SetState(addr, skey, sval)       // Change the storage trie
    49  	for i := 0; i < 100; i++ {
    50  		sk := common.BigToHash(big.NewInt(int64(i)))
    51  		state.SetState(addr, sk, sk) // Change the storage trie
    52  	}
    53  	return state
    54  }
    55  
    56  func TestCopyAndClose(t *testing.T) {
    57  	db := filledStateDB()
    58  	prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
    59  	skey := common.HexToHash("aaa")
    60  	prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    61  	prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    62  	time.Sleep(1 * time.Second)
    63  	a := prefetcher.trie(common.Hash{}, db.originalRoot)
    64  	prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    65  	b := prefetcher.trie(common.Hash{}, db.originalRoot)
    66  	cpy := prefetcher.copy()
    67  	cpy.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    68  	cpy.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    69  	c := cpy.trie(common.Hash{}, db.originalRoot)
    70  	prefetcher.close()
    71  	cpy2 := cpy.copy()
    72  	cpy2.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    73  	d := cpy2.trie(common.Hash{}, db.originalRoot)
    74  	cpy.close()
    75  	cpy2.close()
    76  	if a.Hash() != b.Hash() || a.Hash() != c.Hash() || a.Hash() != d.Hash() {
    77  		t.Fatalf("Invalid trie, hashes should be equal: %v %v %v %v", a.Hash(), b.Hash(), c.Hash(), d.Hash())
    78  	}
    79  }
    80  
    81  func TestUseAfterClose(t *testing.T) {
    82  	db := filledStateDB()
    83  	prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
    84  	skey := common.HexToHash("aaa")
    85  	prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
    86  	a := prefetcher.trie(common.Hash{}, db.originalRoot)
    87  	prefetcher.close()
    88  	b := prefetcher.trie(common.Hash{}, db.originalRoot)
    89  	if a == nil {
    90  		t.Fatal("Prefetching before close should not return nil")
    91  	}
    92  	if b != nil {
    93  		t.Fatal("Trie after close should return nil")
    94  	}
    95  }
    96  
    97  func TestCopyClose(t *testing.T) {
    98  	db := filledStateDB()
    99  	prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
   100  	skey := common.HexToHash("aaa")
   101  	prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
   102  	cpy := prefetcher.copy()
   103  	a := prefetcher.trie(common.Hash{}, db.originalRoot)
   104  	b := cpy.trie(common.Hash{}, db.originalRoot)
   105  	prefetcher.close()
   106  	c := prefetcher.trie(common.Hash{}, db.originalRoot)
   107  	d := cpy.trie(common.Hash{}, db.originalRoot)
   108  	if a == nil {
   109  		t.Fatal("Prefetching before close should not return nil")
   110  	}
   111  	if b == nil {
   112  		t.Fatal("Copy trie should return nil")
   113  	}
   114  	if c != nil {
   115  		t.Fatal("Trie after close should return nil")
   116  	}
   117  	if d == nil {
   118  		t.Fatal("Copy trie should not return nil")
   119  	}
   120  }