github.com/klaytn/klaytn@v1.12.1/storage/database/db_manager_test.go (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package database
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"encoding/json"
    22  	"fmt"
    23  	"math/big"
    24  	"math/rand"
    25  	"os"
    26  	"strconv"
    27  	"strings"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/klaytn/klaytn/blockchain/types"
    32  	"github.com/klaytn/klaytn/common"
    33  	"github.com/klaytn/klaytn/crypto"
    34  	"github.com/klaytn/klaytn/log"
    35  	"github.com/klaytn/klaytn/params"
    36  	"github.com/klaytn/klaytn/rlp"
    37  	"github.com/stretchr/testify/assert"
    38  )
    39  
    40  var (
    41  	dbManagers  []DBManager
    42  	dbConfigs   = make([]*DBConfig, 0, len(baseConfigs)*3)
    43  	baseConfigs = []*DBConfig{
    44  		{DBType: LevelDB, SingleDB: false, NumStateTrieShards: 1, ParallelDBWrite: false},
    45  		{DBType: LevelDB, SingleDB: false, NumStateTrieShards: 1, ParallelDBWrite: true},
    46  		{DBType: LevelDB, SingleDB: false, NumStateTrieShards: 4, ParallelDBWrite: false},
    47  		{DBType: LevelDB, SingleDB: false, NumStateTrieShards: 4, ParallelDBWrite: true},
    48  
    49  		{DBType: LevelDB, SingleDB: true, NumStateTrieShards: 1, ParallelDBWrite: false},
    50  		{DBType: LevelDB, SingleDB: true, NumStateTrieShards: 1, ParallelDBWrite: true},
    51  		{DBType: LevelDB, SingleDB: true, NumStateTrieShards: 4, ParallelDBWrite: false},
    52  		{DBType: LevelDB, SingleDB: true, NumStateTrieShards: 4, ParallelDBWrite: true},
    53  	}
    54  )
    55  
    56  var (
    57  	num1 = uint64(20190815)
    58  	num2 = uint64(20199999)
    59  	num3 = uint64(12345678)
    60  	num4 = uint64(87654321)
    61  )
    62  
    63  var (
    64  	hash1 = common.HexToHash("1341655") // 20190805 in hexadecimal
    65  	hash2 = common.HexToHash("1343A3F") // 20199999 in hexadecimal
    66  	hash3 = common.HexToHash("BC614E")  // 12345678 in hexadecimal
    67  	hash4 = common.HexToHash("5397FB1") // 87654321 in hexadecimal
    68  )
    69  
    70  var (
    71  	key    *ecdsa.PrivateKey
    72  	addr   common.Address
    73  	signer types.Signer
    74  )
    75  
    76  var addRocksDB = false
    77  
    78  func init() {
    79  	GetOpenFilesLimit()
    80  
    81  	key, _ = crypto.GenerateKey()
    82  	addr = crypto.PubkeyToAddress(key.PublicKey)
    83  	signer = types.LatestSignerForChainID(big.NewInt(18))
    84  
    85  	for _, bc := range baseConfigs {
    86  		badgerConfig := *bc
    87  		badgerConfig.DBType = BadgerDB
    88  		memoryConfig := *bc
    89  		memoryConfig.DBType = MemoryDB
    90  		rockdbConfig := *bc
    91  		rockdbConfig.DBType = RocksDB
    92  
    93  		dbConfigs = append(dbConfigs, bc)
    94  		dbConfigs = append(dbConfigs, &badgerConfig)
    95  		dbConfigs = append(dbConfigs, &memoryConfig)
    96  		if addRocksDB {
    97  			dbConfigs = append(dbConfigs, &rockdbConfig)
    98  		}
    99  	}
   100  
   101  	dbManagers = createDBManagers(dbConfigs)
   102  }
   103  
   104  // createDBManagers generates a list of DBManagers to test various combinations of DBConfig.
   105  func createDBManagers(configs []*DBConfig) []DBManager {
   106  	dbManagers := make([]DBManager, 0, len(configs))
   107  
   108  	for i, c := range configs {
   109  		c.Dir, _ = os.MkdirTemp(os.TempDir(), fmt.Sprintf("test-db-manager-%v", i))
   110  		dbManagers = append(dbManagers, NewDBManager(c))
   111  	}
   112  
   113  	return dbManagers
   114  }
   115  
   116  // TestDBManager_IsParallelDBWrite compares the return value of IsParallelDBWrite with the value in the config.
   117  func TestDBManager_IsParallelDBWrite(t *testing.T) {
   118  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   119  	for i, dbm := range dbManagers {
   120  		c := dbConfigs[i]
   121  		assert.Equal(t, c.ParallelDBWrite, dbm.IsParallelDBWrite())
   122  	}
   123  }
   124  
   125  // TestDBManager_CanonicalHash tests read, write and delete operations of canonical hash.
   126  func TestDBManager_CanonicalHash(t *testing.T) {
   127  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   128  	for _, dbm := range dbManagers {
   129  		// 1. Read from empty database, shouldn't be found.
   130  		assert.Equal(t, common.Hash{}, dbm.ReadCanonicalHash(0))
   131  		assert.Equal(t, common.Hash{}, dbm.ReadCanonicalHash(100))
   132  
   133  		// 2. Write a row to the database.
   134  		dbm.WriteCanonicalHash(hash1, num1)
   135  
   136  		// 3. Read from the database, only written key-value pair should be found.
   137  		assert.Equal(t, common.Hash{}, dbm.ReadCanonicalHash(0))
   138  		assert.Equal(t, common.Hash{}, dbm.ReadCanonicalHash(100))
   139  		assert.Equal(t, hash1, dbm.ReadCanonicalHash(num1)) // should be found
   140  
   141  		// 4. Overwrite existing key with different value, value should be changed.
   142  		hash2 := common.HexToHash("1343A3F")                // 20199999 in hexadecimal
   143  		dbm.WriteCanonicalHash(hash2, num1)                 // overwrite hash1 by hash2 with same key
   144  		assert.Equal(t, hash2, dbm.ReadCanonicalHash(num1)) // should be hash2
   145  
   146  		// 5. Delete non-existing value.
   147  		dbm.DeleteCanonicalHash(num2)
   148  		assert.Equal(t, hash2, dbm.ReadCanonicalHash(num1)) // should be hash2, not deleted
   149  
   150  		// 6. Delete existing value.
   151  		dbm.DeleteCanonicalHash(num1)
   152  		assert.Equal(t, common.Hash{}, dbm.ReadCanonicalHash(num1)) // shouldn't be found
   153  	}
   154  }
   155  
   156  // TestDBManager_HeadHeaderHash tests read and write operations of head header hash.
   157  func TestDBManager_HeadHeaderHash(t *testing.T) {
   158  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   159  	for _, dbm := range dbManagers {
   160  		assert.Equal(t, common.Hash{}, dbm.ReadHeadHeaderHash())
   161  
   162  		dbm.WriteHeadHeaderHash(hash1)
   163  		assert.Equal(t, hash1, dbm.ReadHeadHeaderHash())
   164  
   165  		dbm.WriteHeadHeaderHash(hash2)
   166  		assert.Equal(t, hash2, dbm.ReadHeadHeaderHash())
   167  	}
   168  }
   169  
   170  // TestDBManager_HeadBlockHash tests read and write operations of head block hash.
   171  func TestDBManager_HeadBlockHash(t *testing.T) {
   172  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   173  	for _, dbm := range dbManagers {
   174  		assert.Equal(t, common.Hash{}, dbm.ReadHeadBlockHash())
   175  
   176  		dbm.WriteHeadBlockHash(hash1)
   177  		assert.Equal(t, hash1, dbm.ReadHeadBlockHash())
   178  
   179  		dbm.WriteHeadBlockHash(hash2)
   180  		assert.Equal(t, hash2, dbm.ReadHeadBlockHash())
   181  	}
   182  }
   183  
   184  // TestDBManager_HeadFastBlockHash tests read and write operations of head fast block hash.
   185  func TestDBManager_HeadFastBlockHash(t *testing.T) {
   186  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   187  	for _, dbm := range dbManagers {
   188  		assert.Equal(t, common.Hash{}, dbm.ReadHeadFastBlockHash())
   189  
   190  		dbm.WriteHeadFastBlockHash(hash1)
   191  		assert.Equal(t, hash1, dbm.ReadHeadFastBlockHash())
   192  
   193  		dbm.WriteHeadFastBlockHash(hash2)
   194  		assert.Equal(t, hash2, dbm.ReadHeadFastBlockHash())
   195  	}
   196  }
   197  
   198  // TestDBManager_FastTrieProgress tests read and write operations of fast trie progress.
   199  func TestDBManager_FastTrieProgress(t *testing.T) {
   200  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   201  	for _, dbm := range dbManagers {
   202  		assert.Equal(t, uint64(0), dbm.ReadFastTrieProgress())
   203  
   204  		dbm.WriteFastTrieProgress(num1)
   205  		assert.Equal(t, num1, dbm.ReadFastTrieProgress())
   206  
   207  		dbm.WriteFastTrieProgress(num2)
   208  		assert.Equal(t, num2, dbm.ReadFastTrieProgress())
   209  	}
   210  }
   211  
   212  // TestDBManager_Header tests read, write and delete operations of blockchain headers.
   213  func TestDBManager_Header(t *testing.T) {
   214  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   215  	header := &types.Header{Number: big.NewInt(int64(num1))}
   216  	headerHash := header.Hash()
   217  
   218  	encodedHeader, err := rlp.EncodeToBytes(header)
   219  	if err != nil {
   220  		t.Fatal("Failed to encode header!", "err", err)
   221  	}
   222  
   223  	for _, dbm := range dbManagers {
   224  		assert.False(t, dbm.HasHeader(headerHash, num1))
   225  		assert.Nil(t, dbm.ReadHeader(headerHash, num1))
   226  		assert.Nil(t, dbm.ReadHeaderNumber(headerHash))
   227  
   228  		dbm.WriteHeader(header)
   229  
   230  		assert.True(t, dbm.HasHeader(headerHash, num1))
   231  		assert.Equal(t, header, dbm.ReadHeader(headerHash, num1))
   232  		assert.Equal(t, rlp.RawValue(encodedHeader), dbm.ReadHeaderRLP(headerHash, num1))
   233  		assert.Equal(t, num1, *dbm.ReadHeaderNumber(headerHash))
   234  
   235  		dbm.DeleteHeader(headerHash, num1)
   236  
   237  		assert.False(t, dbm.HasHeader(headerHash, num1))
   238  		assert.Nil(t, dbm.ReadHeader(headerHash, num1))
   239  		assert.Nil(t, dbm.ReadHeaderNumber(headerHash))
   240  	}
   241  }
   242  
   243  // TestDBManager_Body tests read, write and delete operations of blockchain bodies.
   244  func TestDBManager_Body(t *testing.T) {
   245  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   246  	body := &types.Body{Transactions: types.Transactions{}}
   247  	encodedBody, err := rlp.EncodeToBytes(body)
   248  	if err != nil {
   249  		t.Fatal("Failed to encode body!", "err", err)
   250  	}
   251  
   252  	for _, dbm := range dbManagers {
   253  		assert.False(t, dbm.HasBody(hash1, num1))
   254  		assert.Nil(t, dbm.ReadBody(hash1, num1))
   255  		assert.Nil(t, dbm.ReadBodyInCache(hash1))
   256  		assert.Nil(t, dbm.ReadBodyRLP(hash1, num1))
   257  		assert.Nil(t, dbm.ReadBodyRLPByHash(hash1))
   258  
   259  		dbm.WriteBody(hash1, num1, body)
   260  
   261  		assert.True(t, dbm.HasBody(hash1, num1))
   262  		assert.Equal(t, body, dbm.ReadBody(hash1, num1))
   263  		assert.Equal(t, body, dbm.ReadBodyInCache(hash1))
   264  		assert.Equal(t, rlp.RawValue(encodedBody), dbm.ReadBodyRLP(hash1, num1))
   265  		assert.Equal(t, rlp.RawValue(encodedBody), dbm.ReadBodyRLPByHash(hash1))
   266  
   267  		dbm.DeleteBody(hash1, num1)
   268  
   269  		assert.False(t, dbm.HasBody(hash1, num1))
   270  		assert.Nil(t, dbm.ReadBody(hash1, num1))
   271  		assert.Nil(t, dbm.ReadBodyInCache(hash1))
   272  		assert.Nil(t, dbm.ReadBodyRLP(hash1, num1))
   273  		assert.Nil(t, dbm.ReadBodyRLPByHash(hash1))
   274  
   275  		dbm.WriteBodyRLP(hash1, num1, encodedBody)
   276  
   277  		assert.True(t, dbm.HasBody(hash1, num1))
   278  		assert.Equal(t, body, dbm.ReadBody(hash1, num1))
   279  		assert.Equal(t, body, dbm.ReadBodyInCache(hash1))
   280  		assert.Equal(t, rlp.RawValue(encodedBody), dbm.ReadBodyRLP(hash1, num1))
   281  		assert.Equal(t, rlp.RawValue(encodedBody), dbm.ReadBodyRLPByHash(hash1))
   282  
   283  		bodyBatch := dbm.NewBatch(BodyDB)
   284  		dbm.PutBodyToBatch(bodyBatch, hash2, num2, body)
   285  		if err := bodyBatch.Write(); err != nil {
   286  			t.Fatal("Failed to write batch!", "err", err)
   287  		}
   288  
   289  		assert.True(t, dbm.HasBody(hash2, num2))
   290  		assert.Equal(t, body, dbm.ReadBody(hash2, num2))
   291  		assert.Equal(t, body, dbm.ReadBodyInCache(hash2))
   292  		assert.Equal(t, rlp.RawValue(encodedBody), dbm.ReadBodyRLP(hash2, num2))
   293  		assert.Equal(t, rlp.RawValue(encodedBody), dbm.ReadBodyRLPByHash(hash2))
   294  	}
   295  }
   296  
   297  // TestDBManager_Td tests read, write and delete operations of blockchain headers' total difficulty.
   298  func TestDBManager_Td(t *testing.T) {
   299  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   300  	for _, dbm := range dbManagers {
   301  		assert.Nil(t, dbm.ReadTd(hash1, num1))
   302  
   303  		dbm.WriteTd(hash1, num1, big.NewInt(12345))
   304  		assert.Equal(t, big.NewInt(12345), dbm.ReadTd(hash1, num1))
   305  
   306  		dbm.WriteTd(hash1, num1, big.NewInt(54321))
   307  		assert.Equal(t, big.NewInt(54321), dbm.ReadTd(hash1, num1))
   308  
   309  		dbm.DeleteTd(hash1, num1)
   310  		assert.Nil(t, dbm.ReadTd(hash1, num1))
   311  	}
   312  }
   313  
   314  // TestDBManager_Receipts read, write and delete operations of blockchain receipts.
   315  func TestDBManager_Receipts(t *testing.T) {
   316  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   317  	header := &types.Header{Number: big.NewInt(int64(num1))}
   318  	headerHash := header.Hash()
   319  	receipts := types.Receipts{genReceipt(111)}
   320  
   321  	for _, dbm := range dbManagers {
   322  		assert.Nil(t, dbm.ReadReceipts(headerHash, num1))
   323  		assert.Nil(t, dbm.ReadReceiptsByBlockHash(headerHash))
   324  
   325  		dbm.WriteReceipts(headerHash, num1, receipts)
   326  		dbm.WriteHeader(header)
   327  
   328  		assert.Equal(t, receipts, dbm.ReadReceipts(headerHash, num1))
   329  		assert.Equal(t, receipts, dbm.ReadReceiptsByBlockHash(headerHash))
   330  
   331  		dbm.DeleteReceipts(headerHash, num1)
   332  
   333  		assert.Nil(t, dbm.ReadReceipts(headerHash, num1))
   334  		assert.Nil(t, dbm.ReadReceiptsByBlockHash(headerHash))
   335  	}
   336  }
   337  
   338  // TestDBManager_Block read, write and delete operations of blockchain blocks.
   339  func TestDBManager_Block(t *testing.T) {
   340  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   341  	header := &types.Header{Number: big.NewInt(int64(num1))}
   342  	headerHash := header.Hash()
   343  	block := types.NewBlockWithHeader(header)
   344  
   345  	for _, dbm := range dbManagers {
   346  		assert.False(t, dbm.HasBlock(headerHash, num1))
   347  		assert.Nil(t, dbm.ReadBlock(headerHash, num1))
   348  		assert.Nil(t, dbm.ReadBlockByHash(headerHash))
   349  		assert.Nil(t, dbm.ReadBlockByNumber(num1))
   350  
   351  		dbm.WriteBlock(block)
   352  		dbm.WriteCanonicalHash(headerHash, num1)
   353  
   354  		assert.True(t, dbm.HasBlock(headerHash, num1))
   355  
   356  		blockFromDB1 := dbm.ReadBlock(headerHash, num1)
   357  		blockFromDB2 := dbm.ReadBlockByHash(headerHash)
   358  		blockFromDB3 := dbm.ReadBlockByNumber(num1)
   359  
   360  		assert.Equal(t, headerHash, blockFromDB1.Hash())
   361  		assert.Equal(t, headerHash, blockFromDB2.Hash())
   362  		assert.Equal(t, headerHash, blockFromDB3.Hash())
   363  
   364  		dbm.DeleteBlock(headerHash, num1)
   365  		dbm.DeleteCanonicalHash(num1)
   366  
   367  		assert.False(t, dbm.HasBlock(headerHash, num1))
   368  		assert.Nil(t, dbm.ReadBlock(headerHash, num1))
   369  		assert.Nil(t, dbm.ReadBlockByHash(headerHash))
   370  		assert.Nil(t, dbm.ReadBlockByNumber(num1))
   371  	}
   372  }
   373  
   374  func TestDBManager_BadBlock(t *testing.T) {
   375  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   376  	header := &types.Header{Number: big.NewInt(int64(num1))}
   377  	headertwo := &types.Header{Number: big.NewInt(int64(num2))}
   378  	for _, dbm := range dbManagers {
   379  		// block #1 test
   380  		block := types.NewBlockWithHeader(header)
   381  
   382  		if entry := dbm.ReadBadBlock(block.Hash()); entry != nil {
   383  			t.Fatalf("Non existance block returned, %v", entry)
   384  		}
   385  		dbm.WriteBadBlock(block)
   386  		if entry := dbm.ReadBadBlock(block.Hash()); entry == nil {
   387  			t.Fatalf("Existing bad block didn't returned, %v", entry)
   388  		} else if entry.Hash() != block.Hash() {
   389  			t.Fatalf("retrived block mismatching, have %v, want %v", entry, block)
   390  		}
   391  		if badblocks, _ := dbm.ReadAllBadBlocks(); len(badblocks) != 1 {
   392  			for _, b := range badblocks {
   393  				t.Log(b)
   394  			}
   395  			t.Fatalf("bad blocks length mismatching, have %d, want %d", len(badblocks), 1)
   396  
   397  		}
   398  
   399  		// block #2 test
   400  		blocktwo := types.NewBlockWithHeader(headertwo)
   401  		dbm.WriteBadBlock(blocktwo)
   402  		if entry := dbm.ReadBadBlock(blocktwo.Hash()); entry == nil {
   403  			t.Fatalf("Existing bad block didn't returned, %v", entry)
   404  		} else if entry.Hash() != blocktwo.Hash() {
   405  			t.Fatalf("retrived block mismatching, have %v, want %v", entry, block)
   406  		}
   407  
   408  		// block #1 insert again
   409  		dbm.WriteBadBlock(block)
   410  		badBlocks, _ := dbm.ReadAllBadBlocks()
   411  		if len(badBlocks) != 2 {
   412  			t.Fatalf("bad block db len mismatching, have %d, want %d", len(badBlocks), 2)
   413  		}
   414  
   415  		// Write a bunch of bad blocks, all the blocks are should sorted
   416  		// in reverse order. The extra blocks should be truncated.
   417  		for _, n := range rand.Perm(110) {
   418  			block := types.NewBlockWithHeader(&types.Header{
   419  				Number: big.NewInt(int64(n)),
   420  			})
   421  			dbm.WriteBadBlock(block)
   422  		}
   423  		badBlocks, _ = dbm.ReadAllBadBlocks()
   424  		if len(badBlocks) != badBlockToKeep {
   425  			t.Fatalf("The number of persised bad blocks in incorrect %d", len(badBlocks))
   426  		}
   427  		for i := 0; i < len(badBlocks)-1; i++ {
   428  			if badBlocks[i].NumberU64() < badBlocks[i+1].NumberU64() {
   429  				t.Fatalf("The bad blocks are not sorted #[%d](%d) < #[%d](%d)", i, i+1, badBlocks[i].NumberU64(), badBlocks[i+1].NumberU64())
   430  			}
   431  		}
   432  
   433  		// DeleteBadBlocks deletes all the bad blocks from the database. Not used anywhere except this testcode.
   434  		dbm.DeleteBadBlocks()
   435  		if badblocks, _ := dbm.ReadAllBadBlocks(); len(badblocks) != 0 {
   436  			t.Fatalf("Failed to delete bad blocks")
   437  		}
   438  
   439  	}
   440  }
   441  
   442  // TestDBManager_IstanbulSnapshot tests read and write operations of istanbul snapshots.
   443  func TestDBManager_IstanbulSnapshot(t *testing.T) {
   444  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   445  	for _, dbm := range dbManagers {
   446  		snapshot, _ := dbm.ReadIstanbulSnapshot(hash3)
   447  		assert.Nil(t, snapshot)
   448  
   449  		dbm.WriteIstanbulSnapshot(hash3, hash2[:])
   450  		snapshot, _ = dbm.ReadIstanbulSnapshot(hash3)
   451  		assert.Equal(t, hash2[:], snapshot)
   452  
   453  		dbm.WriteIstanbulSnapshot(hash3, hash1[:])
   454  		snapshot, _ = dbm.ReadIstanbulSnapshot(hash3)
   455  		assert.Equal(t, hash1[:], snapshot)
   456  	}
   457  }
   458  
   459  // TestDBManager_TrieNode tests read and write operations of state trie nodes.
   460  func TestDBManager_TrieNode(t *testing.T) {
   461  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   462  	var (
   463  		key1  = hash1.ExtendZero()
   464  		key2  = hash2.Extend()
   465  		node1 = hash1[:]
   466  		node2 = hash2[:]
   467  	)
   468  	for _, dbm := range dbManagers {
   469  		cachedNode, _ := dbm.ReadTrieNode(key1)
   470  		assert.Nil(t, cachedNode)
   471  		hasStateTrieNode, _ := dbm.HasTrieNode(key1)
   472  		assert.False(t, hasStateTrieNode)
   473  
   474  		batch := dbm.NewBatch(StateTrieDB)
   475  		dbm.PutTrieNodeToBatch(batch, key1, node2)
   476  		if _, err := WriteBatches(batch); err != nil {
   477  			t.Fatal("Failed writing batch", "err", err)
   478  		}
   479  
   480  		cachedNode, _ = dbm.ReadTrieNode(key1)
   481  		assert.Equal(t, node2, cachedNode)
   482  
   483  		dbm.PutTrieNodeToBatch(batch, key1, node1)
   484  		if _, err := WriteBatches(batch); err != nil {
   485  			t.Fatal("Failed writing batch", "err", err)
   486  		}
   487  
   488  		cachedNode, _ = dbm.ReadTrieNode(key1)
   489  		assert.Equal(t, node1, cachedNode)
   490  
   491  		hasStateTrieNode, _ = dbm.HasTrieNode(key1)
   492  		assert.True(t, hasStateTrieNode)
   493  
   494  		if dbm.IsSingle() {
   495  			continue
   496  		}
   497  		err := dbm.CreateMigrationDBAndSetStatus(123)
   498  		assert.NoError(t, err)
   499  
   500  		cachedNode, _ = dbm.ReadTrieNode(key1)
   501  		oldCachedNode, _ := dbm.ReadTrieNodeFromOld(key1)
   502  		assert.Equal(t, node1, cachedNode)
   503  		assert.Equal(t, node1, oldCachedNode)
   504  
   505  		hasStateTrieNode, _ = dbm.HasTrieNode(key1)
   506  		hasOldStateTrieNode, _ := dbm.HasTrieNodeFromOld(key1)
   507  		assert.True(t, hasStateTrieNode)
   508  		assert.True(t, hasOldStateTrieNode)
   509  
   510  		batch = dbm.NewBatch(StateTrieDB)
   511  		dbm.PutTrieNodeToBatch(batch, key2, node2)
   512  		if _, err := WriteBatches(batch); err != nil {
   513  			t.Fatal("Failed writing batch", "err", err)
   514  		}
   515  
   516  		cachedNode, _ = dbm.ReadTrieNode(key2)
   517  		oldCachedNode, _ = dbm.ReadTrieNodeFromOld(key2)
   518  		assert.Equal(t, node2, cachedNode)
   519  		assert.Equal(t, node2, oldCachedNode)
   520  
   521  		hasStateTrieNode, _ = dbm.HasTrieNode(key2)
   522  		hasOldStateTrieNode, _ = dbm.HasTrieNodeFromOld(key2)
   523  		assert.True(t, hasStateTrieNode)
   524  		assert.True(t, hasOldStateTrieNode)
   525  
   526  		dbm.FinishStateMigration(true)
   527  	}
   528  }
   529  
   530  func TestDBManager_PruningMarks(t *testing.T) {
   531  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   532  	for _, dbm := range dbManagers {
   533  		if dbm.GetMiscDB().Type() == BadgerDB {
   534  			continue // badgerDB doesn't support NewIterator, so cannot test ReadPruningMarks.
   535  		}
   536  
   537  		assert.False(t, dbm.ReadPruningEnabled())
   538  		dbm.WritePruningEnabled()
   539  		assert.True(t, dbm.ReadPruningEnabled())
   540  		dbm.DeletePruningEnabled()
   541  		assert.False(t, dbm.ReadPruningEnabled())
   542  
   543  		var (
   544  			node1 = hash1.Extend()
   545  			node2 = hash2.Extend()
   546  			node3 = hash3.Extend()
   547  			node4 = hash4.Extend()
   548  			value = []byte("value")
   549  		)
   550  
   551  		dbm.WriteTrieNode(node1, value)
   552  		dbm.WriteTrieNode(node2, value)
   553  		dbm.WriteTrieNode(node3, value)
   554  		dbm.WriteTrieNode(node4, value)
   555  		dbm.WritePruningMarks([]PruningMark{
   556  			{100, node1}, {200, node2}, {300, node3}, {400, node4},
   557  		})
   558  
   559  		marks := dbm.ReadPruningMarks(300, 0)
   560  		assert.Equal(t, []PruningMark{{300, node3}, {400, node4}}, marks)
   561  		marks = dbm.ReadPruningMarks(0, 300)
   562  		assert.Equal(t, []PruningMark{{100, node1}, {200, node2}}, marks)
   563  
   564  		dbm.PruneTrieNodes(marks) // delete node1, node2
   565  		has := func(hash common.ExtHash) bool { ok, _ := dbm.HasTrieNode(hash); return ok }
   566  		assert.False(t, has(node1))
   567  		assert.False(t, has(node2))
   568  		assert.True(t, has(node3))
   569  		assert.True(t, has(node4))
   570  
   571  		dbm.DeletePruningMarks(marks)
   572  		marks = dbm.ReadPruningMarks(0, 0)
   573  		assert.Equal(t, []PruningMark{{300, node3}, {400, node4}}, marks)
   574  	}
   575  }
   576  
   577  // TestDBManager_TxLookupEntry tests read, write and delete operations of TxLookupEntries.
   578  func TestDBManager_TxLookupEntry(t *testing.T) {
   579  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   580  	tx, err := genTransaction(num1)
   581  	assert.NoError(t, err, "Failed to generate a transaction")
   582  
   583  	body := &types.Body{Transactions: types.Transactions{tx}}
   584  	for _, dbm := range dbManagers {
   585  		blockHash, blockIndex, entryIndex := dbm.ReadTxLookupEntry(tx.Hash())
   586  		assert.Equal(t, common.Hash{}, blockHash)
   587  		assert.Equal(t, uint64(0), blockIndex)
   588  		assert.Equal(t, uint64(0), entryIndex)
   589  
   590  		header := &types.Header{Number: big.NewInt(int64(num1))}
   591  		block := types.NewBlockWithHeader(header)
   592  		block = block.WithBody(body.Transactions)
   593  
   594  		dbm.WriteTxLookupEntries(block)
   595  
   596  		blockHash, blockIndex, entryIndex = dbm.ReadTxLookupEntry(tx.Hash())
   597  		assert.Equal(t, block.Hash(), blockHash)
   598  		assert.Equal(t, block.NumberU64(), blockIndex)
   599  		assert.Equal(t, uint64(0), entryIndex)
   600  
   601  		dbm.DeleteTxLookupEntry(tx.Hash())
   602  
   603  		blockHash, blockIndex, entryIndex = dbm.ReadTxLookupEntry(tx.Hash())
   604  		assert.Equal(t, common.Hash{}, blockHash)
   605  		assert.Equal(t, uint64(0), blockIndex)
   606  		assert.Equal(t, uint64(0), entryIndex)
   607  
   608  		dbm.WriteAndCacheTxLookupEntries(block)
   609  		blockHash, blockIndex, entryIndex = dbm.ReadTxLookupEntry(tx.Hash())
   610  		assert.Equal(t, block.Hash(), blockHash)
   611  		assert.Equal(t, block.NumberU64(), blockIndex)
   612  		assert.Equal(t, uint64(0), entryIndex)
   613  
   614  		batch := dbm.NewSenderTxHashToTxHashBatch()
   615  		if err := dbm.PutSenderTxHashToTxHashToBatch(batch, hash1, hash2); err != nil {
   616  			t.Fatal("Failed while calling PutSenderTxHashToTxHashToBatch", "err", err)
   617  		}
   618  
   619  		if err := batch.Write(); err != nil {
   620  			t.Fatal("Failed writing SenderTxHashToTxHashToBatch", "err", err)
   621  		}
   622  
   623  		assert.Equal(t, hash2, dbm.ReadTxHashFromSenderTxHash(hash1))
   624  	}
   625  }
   626  
   627  // TestDBManager_BloomBits tests read, write and delete operations of bloom bits
   628  func TestDBManager_BloomBits(t *testing.T) {
   629  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   630  	for _, dbm := range dbManagers {
   631  		hash1 := common.HexToHash("123456")
   632  		hash2 := common.HexToHash("654321")
   633  
   634  		sh, _ := dbm.ReadBloomBits(hash1[:])
   635  		assert.Nil(t, sh)
   636  
   637  		err := dbm.WriteBloomBits(hash1[:], hash1[:])
   638  		if err != nil {
   639  			t.Fatal("Failed to write bloom bits", "err", err)
   640  		}
   641  
   642  		sh, err = dbm.ReadBloomBits(hash1[:])
   643  		if err != nil {
   644  			t.Fatal("Failed to read bloom bits", "err", err)
   645  		}
   646  		assert.Equal(t, hash1[:], sh)
   647  
   648  		err = dbm.WriteBloomBits(hash1[:], hash2[:])
   649  		if err != nil {
   650  			t.Fatal("Failed to write bloom bits", "err", err)
   651  		}
   652  
   653  		sh, err = dbm.ReadBloomBits(hash1[:])
   654  		if err != nil {
   655  			t.Fatal("Failed to read bloom bits", "err", err)
   656  		}
   657  		assert.Equal(t, hash2[:], sh)
   658  	}
   659  }
   660  
   661  // TestDBManager_Sections tests read, write and delete operations of ValidSections and SectionHead.
   662  func TestDBManager_Sections(t *testing.T) {
   663  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   664  	for _, dbm := range dbManagers {
   665  		// ValidSections
   666  		vs, _ := dbm.ReadValidSections()
   667  		assert.Nil(t, vs)
   668  
   669  		dbm.WriteValidSections(hash1[:])
   670  
   671  		vs, _ = dbm.ReadValidSections()
   672  		assert.Equal(t, hash1[:], vs)
   673  
   674  		// SectionHead
   675  		sh, _ := dbm.ReadSectionHead(hash1[:])
   676  		assert.Nil(t, sh)
   677  
   678  		dbm.WriteSectionHead(hash1[:], hash1)
   679  
   680  		sh, _ = dbm.ReadSectionHead(hash1[:])
   681  		assert.Equal(t, hash1[:], sh)
   682  
   683  		dbm.DeleteSectionHead(hash1[:])
   684  
   685  		sh, _ = dbm.ReadSectionHead(hash1[:])
   686  		assert.Nil(t, sh)
   687  	}
   688  }
   689  
   690  // TestDBManager_DatabaseVersion tests read/write operations of database version.
   691  func TestDBManager_DatabaseVersion(t *testing.T) {
   692  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   693  	for _, dbm := range dbManagers {
   694  		assert.Nil(t, dbm.ReadDatabaseVersion())
   695  
   696  		dbm.WriteDatabaseVersion(uint64(1))
   697  		assert.NotNil(t, dbm.ReadDatabaseVersion())
   698  		assert.Equal(t, uint64(1), *dbm.ReadDatabaseVersion())
   699  
   700  		dbm.WriteDatabaseVersion(uint64(2))
   701  		assert.NotNil(t, dbm.ReadDatabaseVersion())
   702  		assert.Equal(t, uint64(2), *dbm.ReadDatabaseVersion())
   703  	}
   704  }
   705  
   706  // TestDBManager_ChainConfig tests read/write operations of chain configuration.
   707  func TestDBManager_ChainConfig(t *testing.T) {
   708  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   709  	for _, dbm := range dbManagers {
   710  		assert.Nil(t, nil, dbm.ReadChainConfig(hash1))
   711  
   712  		cc1 := &params.ChainConfig{UnitPrice: 12345}
   713  		cc2 := &params.ChainConfig{UnitPrice: 54321}
   714  
   715  		dbm.WriteChainConfig(hash1, cc1)
   716  		assert.Equal(t, cc1, dbm.ReadChainConfig(hash1))
   717  		assert.NotEqual(t, cc2, dbm.ReadChainConfig(hash1))
   718  
   719  		dbm.WriteChainConfig(hash1, cc2)
   720  		assert.NotEqual(t, cc1, dbm.ReadChainConfig(hash1))
   721  		assert.Equal(t, cc2, dbm.ReadChainConfig(hash1))
   722  	}
   723  }
   724  
   725  // TestDBManager_Preimage tests read/write operations of preimages.
   726  func TestDBManager_Preimage(t *testing.T) {
   727  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   728  	for _, dbm := range dbManagers {
   729  		assert.Nil(t, nil, dbm.ReadPreimage(hash1))
   730  
   731  		preimages1 := map[common.Hash][]byte{hash1: hash2[:], hash2: hash1[:]}
   732  		dbm.WritePreimages(num1, preimages1)
   733  
   734  		assert.Equal(t, hash2[:], dbm.ReadPreimage(hash1))
   735  		assert.Equal(t, hash1[:], dbm.ReadPreimage(hash2))
   736  
   737  		preimages2 := map[common.Hash][]byte{hash1: hash1[:], hash2: hash2[:]}
   738  		dbm.WritePreimages(num1, preimages2)
   739  
   740  		assert.Equal(t, hash1[:], dbm.ReadPreimage(hash1))
   741  		assert.Equal(t, hash2[:], dbm.ReadPreimage(hash2))
   742  	}
   743  }
   744  
   745  // TestDBManager_ParentChain tests service chain related database operations, used in the parent chain.
   746  func TestDBManager_ParentChain(t *testing.T) {
   747  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   748  	for _, dbm := range dbManagers {
   749  		// 1. Read/Write SerivceChainTxHash
   750  		assert.Equal(t, common.Hash{}, dbm.ConvertChildChainBlockHashToParentChainTxHash(hash1))
   751  
   752  		dbm.WriteChildChainTxHash(hash1, hash1)
   753  		assert.Equal(t, hash1, dbm.ConvertChildChainBlockHashToParentChainTxHash(hash1))
   754  
   755  		dbm.WriteChildChainTxHash(hash1, hash2)
   756  		assert.Equal(t, hash2, dbm.ConvertChildChainBlockHashToParentChainTxHash(hash1))
   757  
   758  		// 2. Read/Write LastIndexedBlockNumber
   759  		assert.Equal(t, uint64(0), dbm.GetLastIndexedBlockNumber())
   760  
   761  		dbm.WriteLastIndexedBlockNumber(num1)
   762  		assert.Equal(t, num1, dbm.GetLastIndexedBlockNumber())
   763  
   764  		dbm.WriteLastIndexedBlockNumber(num2)
   765  		assert.Equal(t, num2, dbm.GetLastIndexedBlockNumber())
   766  	}
   767  }
   768  
   769  // TestDBManager_ChildChain tests service chain related database operations, used in the child chain.
   770  func TestDBManager_ChildChain(t *testing.T) {
   771  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   772  	for _, dbm := range dbManagers {
   773  		// 1. Read/Write AnchoredBlockNumber
   774  		assert.Equal(t, uint64(0), dbm.ReadAnchoredBlockNumber())
   775  
   776  		dbm.WriteAnchoredBlockNumber(num1)
   777  		assert.Equal(t, num1, dbm.ReadAnchoredBlockNumber())
   778  
   779  		dbm.WriteAnchoredBlockNumber(num2)
   780  		assert.Equal(t, num2, dbm.ReadAnchoredBlockNumber())
   781  
   782  		// 2. Read/Write ReceiptFromParentChain
   783  		// TODO-Klaytn-Database Implement this!
   784  
   785  		// 3. Read/Write HandleTxHashFromRequestTxHash
   786  		assert.Equal(t, common.Hash{}, dbm.ReadHandleTxHashFromRequestTxHash(hash1))
   787  
   788  		dbm.WriteHandleTxHashFromRequestTxHash(hash1, hash1)
   789  		assert.Equal(t, hash1, dbm.ReadHandleTxHashFromRequestTxHash(hash1))
   790  
   791  		dbm.WriteHandleTxHashFromRequestTxHash(hash1, hash2)
   792  		assert.Equal(t, hash2, dbm.ReadHandleTxHashFromRequestTxHash(hash1))
   793  	}
   794  }
   795  
   796  // TestDBManager_CliqueSnapshot tests read and write operations of clique snapshots.
   797  func TestDBManager_CliqueSnapshot(t *testing.T) {
   798  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   799  	for _, dbm := range dbManagers {
   800  		data, err := dbm.ReadCliqueSnapshot(hash1)
   801  		assert.NotNil(t, err)
   802  		assert.Nil(t, data)
   803  
   804  		err = dbm.WriteCliqueSnapshot(hash1, hash1[:])
   805  		assert.Nil(t, err)
   806  
   807  		data, _ = dbm.ReadCliqueSnapshot(hash1)
   808  		assert.Equal(t, hash1[:], data)
   809  
   810  		err = dbm.WriteCliqueSnapshot(hash1, hash2[:])
   811  		assert.Nil(t, err)
   812  
   813  		data, _ = dbm.ReadCliqueSnapshot(hash1)
   814  		assert.Equal(t, hash2[:], data)
   815  	}
   816  }
   817  
   818  func TestDBManager_Governance(t *testing.T) {
   819  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   820  	// TODO-Klaytn-Database Implement this!
   821  }
   822  
   823  func TestDatabaseManager_CreateMigrationDBAndSetStatus(t *testing.T) {
   824  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   825  	for i, dbm := range dbManagers {
   826  		if dbConfigs[i].DBType == MemoryDB {
   827  			continue
   828  		}
   829  
   830  		// check if migration fails on single DB
   831  		if dbm.IsSingle() {
   832  			migrationBlockNum := uint64(12345)
   833  
   834  			// check if not in migration
   835  			assert.False(t, dbManagers[i].InMigration(), "migration status should be not set before testing")
   836  
   837  			// check if create migration fails
   838  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum)
   839  			assert.Error(t, err, "error expected on single DB") // expect error
   840  
   841  			continue
   842  		}
   843  
   844  		// check if migration fails when in migration
   845  		{
   846  			migrationBlockNum := uint64(34567)
   847  
   848  			// check if not in migration
   849  			assert.False(t, dbManagers[i].InMigration(), "migration status should be not set before testing")
   850  
   851  			// set migration status
   852  			dbm.setStateTrieMigrationStatus(migrationBlockNum)
   853  			assert.True(t, dbManagers[i].InMigration())
   854  
   855  			// check if create migration fails
   856  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum)
   857  			assert.Error(t, err, "error expected when in migration state") // expect error
   858  
   859  			// reset migration status for next test
   860  			dbm.setStateTrieMigrationStatus(0)
   861  		}
   862  
   863  		// check if CreateMigrationDBAndSetStatus works as expected
   864  		{
   865  			migrationBlockNum := uint64(56789)
   866  
   867  			// check if not in migration state
   868  			assert.False(t, dbManagers[i].InMigration(), "migration status should be not set before testing")
   869  
   870  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum)
   871  			assert.NoError(t, err)
   872  
   873  			// check if in migration state
   874  			assert.True(t, dbm.InMigration())
   875  
   876  			// check migration DB path in MiscDB
   877  			migrationDBPathKey := append(databaseDirPrefix, common.Int64ToByteBigEndian(uint64(StateTrieMigrationDB))...)
   878  			fetchedMigrationPath, err := dbm.getDatabase(MiscDB).Get(migrationDBPathKey)
   879  			assert.NoError(t, err)
   880  			expectedMigrationPath := "statetrie_migrated_" + strconv.FormatUint(migrationBlockNum, 10)
   881  			assert.Equal(t, expectedMigrationPath, string(fetchedMigrationPath))
   882  
   883  			// check block number in MiscDB
   884  			fetchedBlockNum, err := dbm.getDatabase(MiscDB).Get(migrationStatusKey)
   885  			assert.NoError(t, err)
   886  			assert.Equal(t, common.Int64ToByteBigEndian(migrationBlockNum), fetchedBlockNum)
   887  
   888  			// reset migration status for next test
   889  			dbm.FinishStateMigration(false) // migration fail
   890  		}
   891  	}
   892  }
   893  
   894  func TestDatabaseManager_FinishStateMigration(t *testing.T) {
   895  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   896  	for i, dbm := range dbManagers {
   897  		if dbm.IsSingle() || dbConfigs[i].DBType == MemoryDB {
   898  			continue
   899  		}
   900  
   901  		migrationBlockNum := uint64(12345)
   902  		migrationBlockNum2 := uint64(23456)
   903  
   904  		// check status in miscDB on state migration failure
   905  		{
   906  			// check if not in migration state
   907  			assert.False(t, dbManagers[i].InMigration(), "migration status should be not set before testing")
   908  			// fetch state trie db name before migration
   909  			initialDirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
   910  			assert.Equal(t, 1, len(initialDirNames), "migration status should be not set before testing")
   911  
   912  			// finish migration with failure
   913  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum)
   914  			assert.NoError(t, err)
   915  			endCheck := dbm.FinishStateMigration(false) // migration fail
   916  			select {
   917  			case <-endCheck: // wait for removing DB
   918  			case <-time.After(1 * time.Second):
   919  				t.Log("Take too long for a DB to be removed")
   920  				t.FailNow()
   921  			}
   922  
   923  			// check if in migration state
   924  			assert.False(t, dbm.InMigration())
   925  
   926  			// check if state DB Path is set to old DB in MiscDB
   927  			statDBPathKey := append(databaseDirPrefix, common.Int64ToByteBigEndian(uint64(StateTrieDB))...)
   928  			fetchedStateDBPath, err := dbm.getDatabase(MiscDB).Get(statDBPathKey)
   929  			assert.NoError(t, err)
   930  			dirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
   931  			assert.Equal(t, 1, len(dirNames)) // check if DB is removed
   932  			assert.Equal(t, initialDirNames[0], string(fetchedStateDBPath), "old DB should remain")
   933  
   934  			// check if migration DB Path is not set in MiscDB
   935  			migrationDBPathKey := append(databaseDirPrefix, common.Int64ToByteBigEndian(uint64(StateTrieMigrationDB))...)
   936  			fetchedMigrationPath, err := dbm.getDatabase(MiscDB).Get(migrationDBPathKey)
   937  			assert.NoError(t, err)
   938  			assert.Equal(t, "", string(fetchedMigrationPath))
   939  
   940  			// check if block number is not set in MiscDB
   941  			fetchedBlockNum, err := dbm.getDatabase(MiscDB).Get(migrationStatusKey)
   942  			assert.NoError(t, err)
   943  			assert.Equal(t, common.Int64ToByteBigEndian(0), fetchedBlockNum)
   944  		}
   945  
   946  		// check status in miscDB on successful state migration
   947  		{
   948  			// check if not in migration state
   949  			assert.False(t, dbManagers[i].InMigration(), "migration status should be not set before testing")
   950  
   951  			// finish migration successfully
   952  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum2)
   953  			assert.NoError(t, err)
   954  			endCheck := dbm.FinishStateMigration(true) // migration succeed
   955  			select {
   956  			case <-endCheck: // wait for removing DB
   957  			case <-time.After(1 * time.Second):
   958  				t.Log("Take too long for a DB to be removed")
   959  				t.FailNow()
   960  			}
   961  
   962  			// check if in migration state
   963  			assert.False(t, dbm.InMigration())
   964  
   965  			// check if state DB Path is set to new DB in MiscDB
   966  			statDBPathKey := append(databaseDirPrefix, common.Int64ToByteBigEndian(uint64(StateTrieDB))...)
   967  			fetchedStateDBPath, err := dbm.getDatabase(MiscDB).Get(statDBPathKey)
   968  			assert.NoError(t, err)
   969  			dirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
   970  			assert.Equal(t, 1, len(dirNames))                                                         // check if DB is removed
   971  			expectedStateDBPath := "statetrie_migrated_" + strconv.FormatUint(migrationBlockNum2, 10) // new DB format
   972  			assert.Equal(t, expectedStateDBPath, string(fetchedStateDBPath), "new DB should remain")
   973  
   974  			// check if migration DB Path is not set in MiscDB
   975  			migrationDBPathKey := append(databaseDirPrefix, common.Int64ToByteBigEndian(uint64(StateTrieMigrationDB))...)
   976  			fetchedMigrationPath, err := dbm.getDatabase(MiscDB).Get(migrationDBPathKey)
   977  			assert.NoError(t, err)
   978  			assert.Equal(t, "", string(fetchedMigrationPath))
   979  
   980  			// check if block number is not set in MiscDB
   981  			fetchedBlockNum, err := dbm.getDatabase(MiscDB).Get(migrationStatusKey)
   982  			assert.NoError(t, err)
   983  			assert.Equal(t, common.Int64ToByteBigEndian(0), fetchedBlockNum)
   984  		}
   985  	}
   986  }
   987  
   988  // While state trie migration, directory should be created with expected name
   989  func TestDBManager_StateMigrationDBPath(t *testing.T) {
   990  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   991  	for i, dbm := range dbManagers {
   992  		if dbm.IsSingle() || dbConfigs[i].DBType == MemoryDB {
   993  			continue
   994  		}
   995  
   996  		// check directory creation on successful migration
   997  		{
   998  			migrationBlockNum := uint64(12345)
   999  			NewMigrationPath := dbBaseDirs[StateTrieMigrationDB] + "_" + strconv.FormatUint(migrationBlockNum, 10)
  1000  
  1001  			// check if there is only one state trie db before migration
  1002  			initialDirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
  1003  			assert.Equal(t, 1, len(initialDirNames), "migration status should be not set before testing")
  1004  
  1005  			// check if new db is created
  1006  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum)
  1007  			assert.NoError(t, err)
  1008  			dirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
  1009  			assert.Equal(t, 2, len(dirNames))
  1010  			assert.True(t, dirNames[0] == NewMigrationPath || dirNames[1] == NewMigrationPath)
  1011  
  1012  			// check if old db is deleted on migration success
  1013  			endCheck := dbm.FinishStateMigration(true) // migration succeed
  1014  			select {
  1015  			case <-endCheck: // wait for removing DB
  1016  			case <-time.After(1 * time.Second):
  1017  				t.Log("Take too long for a DB to be removed")
  1018  				t.FailNow()
  1019  			}
  1020  
  1021  			newDirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
  1022  			assert.Equal(t, 1, len(newDirNames)) // check if DB is removed
  1023  			assert.Equal(t, NewMigrationPath, newDirNames[0], "new DB should remain")
  1024  		}
  1025  
  1026  		// check directory creation on failed migration
  1027  		{
  1028  			migrationBlockNum := uint64(54321)
  1029  			NewMigrationPath := dbBaseDirs[StateTrieMigrationDB] + "_" + strconv.FormatUint(migrationBlockNum, 10)
  1030  
  1031  			// check if there is only one state trie db before migration
  1032  			initialDirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
  1033  			assert.Equal(t, 1, len(initialDirNames), "migration status should be not set before testing")
  1034  
  1035  			// check if new db is created
  1036  			err := dbm.CreateMigrationDBAndSetStatus(migrationBlockNum)
  1037  			assert.NoError(t, err)
  1038  			dirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, "statetrie")
  1039  			assert.Equal(t, 2, len(dirNames))
  1040  
  1041  			assert.True(t, dirNames[0] == NewMigrationPath || dirNames[1] == NewMigrationPath)
  1042  
  1043  			// check if new db is deleted on migration fail
  1044  			endCheck := dbm.FinishStateMigration(false) // migration fail
  1045  			select {
  1046  			case <-endCheck: // wait for removing DB
  1047  			case <-time.After(1 * time.Second):
  1048  				t.Log("Take too long for a DB to be removed")
  1049  				t.FailNow()
  1050  			}
  1051  
  1052  			newDirNames := getFilesInDir(t, dbm.GetDBConfig().Dir, dbm.getDBDir(StateTrieDB))
  1053  			assert.Equal(t, 1, len(newDirNames)) // check if DB is removed
  1054  			assert.Equal(t, initialDirNames[0], newDirNames[0], "old DB should remain")
  1055  		}
  1056  	}
  1057  }
  1058  
  1059  func TestDBManager_WriteGovernanceIdx(t *testing.T) {
  1060  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1061  	testIdxes := []uint64{100, 200, 300}
  1062  
  1063  	for _, dbm := range dbManagers {
  1064  		// normal case
  1065  		{
  1066  			// write test indexes
  1067  			for _, idx := range testIdxes {
  1068  				assert.Nil(t, dbm.WriteGovernanceIdx(idx))
  1069  			}
  1070  
  1071  			// get the stored indexes
  1072  			encodedIdxes, err := dbm.GetMiscDB().Get(governanceHistoryKey)
  1073  			assert.Nil(t, err)
  1074  
  1075  			// read and check the indexes from the database
  1076  			actualIdxes := make([]uint64, 0)
  1077  			assert.Nil(t, json.Unmarshal(encodedIdxes, &actualIdxes))
  1078  			assert.Equal(t, testIdxes, actualIdxes)
  1079  		}
  1080  
  1081  		// unexpected case: try to write a governance index not in ascending order
  1082  		{
  1083  			assert.NotNil(t, dbm.WriteGovernanceIdx(testIdxes[0]))
  1084  		}
  1085  
  1086  		// remove test data from database
  1087  		_ = dbm.GetMiscDB().Delete(governanceHistoryKey)
  1088  	}
  1089  }
  1090  
  1091  func TestDBManager_ReadRecentGovernanceIdx(t *testing.T) {
  1092  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1093  	testIdxes := []uint64{100, 200, 300}
  1094  
  1095  	for _, dbm := range dbManagers {
  1096  		// check empty
  1097  		idxes, err := dbm.ReadRecentGovernanceIdx(0)
  1098  		assert.Nil(t, idxes)
  1099  		assert.NotNil(t, err)
  1100  
  1101  		// normal case
  1102  		{
  1103  			// write indexes on the database
  1104  			data, err := json.Marshal(testIdxes)
  1105  			assert.Nil(t, err)
  1106  			assert.Nil(t, dbm.GetMiscDB().Put(governanceHistoryKey, data))
  1107  
  1108  			// read and check the indexes from the database
  1109  			idxes, err = dbm.ReadRecentGovernanceIdx(0)
  1110  			assert.Equal(t, testIdxes, idxes)
  1111  			assert.Nil(t, err)
  1112  		}
  1113  
  1114  		// unexpected case: the governance indexes in the database is not in ascending order
  1115  		{
  1116  			invalidTestIdxes := append(testIdxes, testIdxes[0])
  1117  			expectedIdxes := append([]uint64{testIdxes[0]}, testIdxes...)
  1118  
  1119  			// write invalid indexes on the database
  1120  			data, err := json.Marshal(invalidTestIdxes)
  1121  			assert.Nil(t, err)
  1122  			assert.Nil(t, dbm.GetMiscDB().Put(governanceHistoryKey, data))
  1123  
  1124  			// read and check the indexes from the database
  1125  			idxes, err = dbm.ReadRecentGovernanceIdx(0)
  1126  			assert.Nil(t, err)
  1127  			assert.Equal(t, expectedIdxes, idxes)
  1128  		}
  1129  
  1130  		// remove test data from database
  1131  		_ = dbm.GetMiscDB().Delete(governanceHistoryKey)
  1132  	}
  1133  }
  1134  
  1135  func genReceipt(gasUsed int) *types.Receipt {
  1136  	log := &types.Log{Topics: []common.Hash{}, Data: []uint8{}, BlockNumber: uint64(gasUsed)}
  1137  	log.Topics = append(log.Topics, common.HexToHash(strconv.Itoa(gasUsed)))
  1138  	return &types.Receipt{
  1139  		TxHash:  common.HexToHash(strconv.Itoa(gasUsed)),
  1140  		GasUsed: uint64(gasUsed),
  1141  		Status:  types.ReceiptStatusSuccessful,
  1142  		Logs:    []*types.Log{log},
  1143  	}
  1144  }
  1145  
  1146  func genTransaction(val uint64) (*types.Transaction, error) {
  1147  	return types.SignTx(
  1148  		types.NewTransaction(0, addr,
  1149  			big.NewInt(int64(val)), 0, big.NewInt(int64(val)), nil), signer, key)
  1150  }
  1151  
  1152  // getFilesInDir returns all file names containing the substring in the directory
  1153  func getFilesInDir(t *testing.T, dirPath string, substr string) []string {
  1154  	files, err := os.ReadDir(dirPath)
  1155  	assert.NoError(t, err)
  1156  
  1157  	var dirNames []string
  1158  	for _, f := range files {
  1159  		if strings.Contains(f.Name(), substr) {
  1160  			dirNames = append(dirNames, f.Name())
  1161  		}
  1162  	}
  1163  
  1164  	return dirNames
  1165  }
  1166  
  1167  func TestDBManager_WriteAndReadAccountSnapshot(t *testing.T) {
  1168  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1169  	var (
  1170  		hash     common.Hash
  1171  		expected []byte
  1172  		actual   []byte
  1173  	)
  1174  
  1175  	for _, dbm := range dbManagers {
  1176  		// read unknown key
  1177  		hash, _ = genRandomData()
  1178  		actual = dbm.ReadAccountSnapshot(hash)
  1179  		assert.Nil(t, actual)
  1180  
  1181  		// write and read with empty hash
  1182  		_, expected = genRandomData()
  1183  		dbm.WriteAccountSnapshot(common.Hash{}, expected)
  1184  		actual = dbm.ReadAccountSnapshot(common.Hash{})
  1185  		assert.Equal(t, expected, actual)
  1186  
  1187  		// write and read with empty data
  1188  		hash, _ = genRandomData()
  1189  		dbm.WriteAccountSnapshot(hash, []byte{})
  1190  		actual = dbm.ReadAccountSnapshot(hash)
  1191  		assert.Equal(t, []byte{}, actual)
  1192  
  1193  		// write and read with random hash and data
  1194  		hash, expected = genRandomData()
  1195  		dbm.WriteAccountSnapshot(hash, expected)
  1196  		actual = dbm.ReadAccountSnapshot(hash)
  1197  		assert.Equal(t, expected, actual)
  1198  	}
  1199  }
  1200  
  1201  func TestDBManager_DeleteAccountSnapshot(t *testing.T) {
  1202  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1203  	var (
  1204  		hash     common.Hash
  1205  		expected []byte
  1206  		actual   []byte
  1207  	)
  1208  
  1209  	for _, dbm := range dbManagers {
  1210  		// delete unknown key
  1211  		hash, _ = genRandomData()
  1212  		dbm.DeleteAccountSnapshot(hash)
  1213  		actual = dbm.ReadAccountSnapshot(hash)
  1214  		assert.Nil(t, actual)
  1215  
  1216  		// delete empty hash
  1217  		_, expected = genRandomData()
  1218  		dbm.WriteAccountSnapshot(common.Hash{}, expected)
  1219  		dbm.DeleteAccountSnapshot(common.Hash{})
  1220  		actual = dbm.ReadAccountSnapshot(hash)
  1221  		assert.Nil(t, actual)
  1222  
  1223  		// write and read with empty data
  1224  		hash, _ = genRandomData()
  1225  		dbm.WriteAccountSnapshot(hash, []byte{})
  1226  		dbm.DeleteAccountSnapshot(hash)
  1227  		actual = dbm.ReadAccountSnapshot(hash)
  1228  		assert.Nil(t, actual)
  1229  
  1230  		// write and read with random hash and data
  1231  		hash, expected = genRandomData()
  1232  		dbm.WriteAccountSnapshot(hash, expected)
  1233  		dbm.DeleteAccountSnapshot(hash)
  1234  		actual = dbm.ReadAccountSnapshot(hash)
  1235  		assert.Nil(t, actual)
  1236  	}
  1237  }
  1238  
  1239  func TestDBManager_WriteCode(t *testing.T) {
  1240  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1241  	for i, dbm := range dbManagers {
  1242  		if dbm.IsSingle() || dbConfigs[i].DBType == MemoryDB {
  1243  			continue
  1244  		}
  1245  
  1246  		// write code before statedb migration
  1247  		hash1, data1 := genRandomData()
  1248  		dbm.WriteCode(hash1, data1)
  1249  
  1250  		ret1 := dbm.ReadCode(hash1)
  1251  		assert.Equal(t, data1, ret1)
  1252  
  1253  		// start migration
  1254  		assert.NoError(t, dbm.CreateMigrationDBAndSetStatus(uint64(i+100)))
  1255  
  1256  		// write code while statedb migration
  1257  		hash2, data2 := genRandomData()
  1258  		dbm.WriteCode(hash2, data2)
  1259  
  1260  		ret1 = dbm.ReadCode(hash1)
  1261  		assert.Equal(t, data1, ret1)
  1262  		ret2 := dbm.ReadCode(hash2)
  1263  		assert.Equal(t, data2, ret2)
  1264  
  1265  		// finished migration
  1266  		errCh := dbm.FinishStateMigration(true)
  1267  		select {
  1268  		case <-errCh:
  1269  		case <-time.NewTicker(1 * time.Second).C:
  1270  			t.Fatalf("takes too much time to delete original db")
  1271  		}
  1272  
  1273  		// write code after statedb migration
  1274  		hash3, data3 := genRandomData()
  1275  		dbm.WriteCode(hash3, data3)
  1276  
  1277  		ret1 = dbm.ReadCode(hash1)
  1278  		assert.Nil(t, ret1) // returns nil after removing original db
  1279  		ret2 = dbm.ReadCode(hash2)
  1280  		assert.Equal(t, data2, ret2)
  1281  		ret3 := dbm.ReadCode(hash3)
  1282  		assert.Equal(t, data3, ret3)
  1283  	}
  1284  }
  1285  
  1286  func genRandomData() (common.Hash, []byte) {
  1287  	rb := common.MakeRandomBytes(common.HashLength)
  1288  	hash := common.BytesToHash(rb)
  1289  	data := common.MakeRandomBytes(100)
  1290  	return hash, data
  1291  }