gitlab.com/flarenetwork/coreth@v0.1.1/core/state/snapshot/wipe_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 2019 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 snapshot
    28  
    29  import (
    30  	"math/rand"
    31  	"testing"
    32  
    33  	"github.com/ethereum/go-ethereum/common"
    34  	"github.com/ethereum/go-ethereum/ethdb/memorydb"
    35  	"gitlab.com/flarenetwork/coreth/core/rawdb"
    36  )
    37  
    38  // Tests that given a database with random data content, all parts of a snapshot
    39  // can be crrectly wiped without touching anything else.
    40  func TestWipe(t *testing.T) {
    41  	// Create a database with some random snapshot data
    42  	db := memorydb.New()
    43  
    44  	for i := 0; i < 128; i++ {
    45  		account := randomHash()
    46  		rawdb.WriteAccountSnapshot(db, account, randomHash().Bytes())
    47  		for j := 0; j < 1024; j++ {
    48  			rawdb.WriteStorageSnapshot(db, account, randomHash(), randomHash().Bytes())
    49  		}
    50  	}
    51  	rawdb.WriteSnapshotBlockHash(db, randomHash())
    52  	rawdb.WriteSnapshotRoot(db, randomHash())
    53  
    54  	// Add some random non-snapshot data too to make wiping harder
    55  	for i := 0; i < 65536; i++ {
    56  		// Generate a key that's the wrong length for a state snapshot item
    57  		var keysize int
    58  		for keysize == 0 || keysize == 32 || keysize == 64 {
    59  			keysize = 8 + rand.Intn(64) // +8 to ensure we will "never" randomize duplicates
    60  		}
    61  		// Randomize the suffix, dedup and inject it under the snapshot namespace
    62  		keysuffix := make([]byte, keysize)
    63  		rand.Read(keysuffix)
    64  
    65  		if rand.Int31n(2) == 0 {
    66  			db.Put(append(rawdb.SnapshotAccountPrefix, keysuffix...), randomHash().Bytes())
    67  		} else {
    68  			db.Put(append(rawdb.SnapshotStoragePrefix, keysuffix...), randomHash().Bytes())
    69  		}
    70  	}
    71  	// Sanity check that all the keys are present
    72  	var items int
    73  
    74  	it := db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
    75  	defer it.Release()
    76  
    77  	for it.Next() {
    78  		key := it.Key()
    79  		if len(key) == len(rawdb.SnapshotAccountPrefix)+common.HashLength {
    80  			items++
    81  		}
    82  	}
    83  	it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil)
    84  	defer it.Release()
    85  
    86  	for it.Next() {
    87  		key := it.Key()
    88  		if len(key) == len(rawdb.SnapshotStoragePrefix)+2*common.HashLength {
    89  			items++
    90  		}
    91  	}
    92  	if items != 128+128*1024 {
    93  		t.Fatalf("snapshot size mismatch: have %d, want %d", items, 128+128*1024)
    94  	}
    95  	if hash := rawdb.ReadSnapshotBlockHash(db); hash == (common.Hash{}) {
    96  		t.Errorf("snapshot block hash marker mismatch: have %#x, want <not-nil>", hash)
    97  	}
    98  	if hash := rawdb.ReadSnapshotRoot(db); hash == (common.Hash{}) {
    99  		t.Errorf("snapshot block root marker mismatch: have %#x, want <not-nil>", hash)
   100  	}
   101  	// Wipe all snapshot entries from the database
   102  	<-wipeSnapshot(db, true)
   103  
   104  	// Iterate over the database end ensure no snapshot information remains
   105  	it = db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
   106  	defer it.Release()
   107  
   108  	for it.Next() {
   109  		key := it.Key()
   110  		if len(key) == len(rawdb.SnapshotAccountPrefix)+common.HashLength {
   111  			t.Errorf("snapshot entry remained after wipe: %x", key)
   112  		}
   113  	}
   114  	it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil)
   115  	defer it.Release()
   116  
   117  	for it.Next() {
   118  		key := it.Key()
   119  		if len(key) == len(rawdb.SnapshotStoragePrefix)+2*common.HashLength {
   120  			t.Errorf("snapshot entry remained after wipe: %x", key)
   121  		}
   122  	}
   123  	if hash := rawdb.ReadSnapshotBlockHash(db); hash != (common.Hash{}) {
   124  		t.Errorf("snapshot block hash marker remained after wipe: %#x", hash)
   125  	}
   126  	if hash := rawdb.ReadSnapshotRoot(db); hash != (common.Hash{}) {
   127  		t.Errorf("snapshot block root marker remained after wipe: %#x", hash)
   128  	}
   129  	// Iterate over the database and ensure miscellaneous items are present
   130  	items = 0
   131  
   132  	it = db.NewIterator(nil, nil)
   133  	defer it.Release()
   134  
   135  	for it.Next() {
   136  		items++
   137  	}
   138  	if items != 65536 {
   139  		t.Fatalf("misc item count mismatch: have %d, want %d", items, 65536)
   140  	}
   141  }