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 := ¶ms.ChainConfig{UnitPrice: 12345} 713 cc2 := ¶ms.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 }