|
12 | 12 |
|
13 | 13 | using node::BlockManager; |
14 | 14 | using node::BLOCK_SERIALIZATION_HEADER_SIZE; |
| 15 | +using node::MAX_BLOCKFILE_SIZE; |
| 16 | +using node::OpenBlockFile; |
15 | 17 |
|
16 | 18 | // use BasicTestingSetup here for the data directory configuration, setup, and cleanup |
17 | 19 | BOOST_FIXTURE_TEST_SUITE(blockmanager_tests, BasicTestingSetup) |
@@ -42,4 +44,45 @@ BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos) |
42 | 44 | BOOST_CHECK_EQUAL(actual.nPos, BLOCK_SERIALIZATION_HEADER_SIZE + ::GetSerializeSize(params->GenesisBlock(), CLIENT_VERSION) + BLOCK_SERIALIZATION_HEADER_SIZE); |
43 | 45 | } |
44 | 46 |
|
| 47 | +BOOST_FIXTURE_TEST_CASE(blockmanager_scan_unlink_already_pruned_files, TestChain100Setup) |
| 48 | +{ |
| 49 | + // Cap last block file size, and mine new block in a new block file. |
| 50 | + const auto& chainman = Assert(m_node.chainman); |
| 51 | + auto& blockman = chainman->m_blockman; |
| 52 | + const CBlockIndex* old_tip{WITH_LOCK(chainman->GetMutex(), return chainman->ActiveChain().Tip())}; |
| 53 | + WITH_LOCK(chainman->GetMutex(), blockman.GetBlockFileInfo(old_tip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE); |
| 54 | + CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); |
| 55 | + |
| 56 | + // Prune the older block file, but don't unlink it |
| 57 | + int file_number; |
| 58 | + { |
| 59 | + LOCK(chainman->GetMutex()); |
| 60 | + file_number = old_tip->GetBlockPos().nFile; |
| 61 | + blockman.PruneOneBlockFile(file_number); |
| 62 | + } |
| 63 | + |
| 64 | + const FlatFilePos pos(file_number, 0); |
| 65 | + |
| 66 | + // Check that the file is not unlinked after ScanAndUnlinkAlreadyPrunedFiles |
| 67 | + // if m_have_pruned is not yet set |
| 68 | + WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles()); |
| 69 | + BOOST_CHECK(!AutoFile(OpenBlockFile(pos, true)).IsNull()); |
| 70 | + |
| 71 | + // Check that the file is unlinked after ScanAndUnlinkAlreadyPrunedFiles |
| 72 | + // once m_have_pruned is set |
| 73 | + blockman.m_have_pruned = true; |
| 74 | + WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles()); |
| 75 | + BOOST_CHECK(AutoFile(OpenBlockFile(pos, true)).IsNull()); |
| 76 | + |
| 77 | + // Check that calling with already pruned files doesn't cause an error |
| 78 | + WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles()); |
| 79 | + |
| 80 | + // Check that the new tip file has not been removed |
| 81 | + const CBlockIndex* new_tip{WITH_LOCK(chainman->GetMutex(), return chainman->ActiveChain().Tip())}; |
| 82 | + BOOST_CHECK_NE(old_tip, new_tip); |
| 83 | + const int new_file_number{WITH_LOCK(chainman->GetMutex(), return new_tip->GetBlockPos().nFile)}; |
| 84 | + const FlatFilePos new_pos(new_file_number, 0); |
| 85 | + BOOST_CHECK(!AutoFile(OpenBlockFile(new_pos, true)).IsNull()); |
| 86 | +} |
| 87 | + |
45 | 88 | BOOST_AUTO_TEST_SUITE_END() |
0 commit comments