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