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