| 848 | } |
| 849 | |
| 850 | FlatFilePos BlockManager::FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime) |
| 851 | { |
| 852 | AssertLockHeld(::cs_main); |
| 853 | const BlockfileType chain_type = BlockfileTypeForHeight(nHeight); |
| 854 | |
| 855 | if (!m_blockfile_cursors[chain_type]) { |
| 856 | // If a snapshot is loaded during runtime, we may not have initialized this cursor yet. |
| 857 | assert(chain_type == BlockfileType::ASSUMED); |
| 858 | const auto new_cursor = BlockfileCursor{this->MaxBlockfileNum() + 1}; |
| 859 | m_blockfile_cursors[chain_type] = new_cursor; |
| 860 | LogDebug(BCLog::BLOCKSTORAGE, "[%s] initializing blockfile cursor to %s\n", chain_type, new_cursor); |
| 861 | } |
| 862 | const int last_blockfile = m_blockfile_cursors[chain_type]->file_num; |
| 863 | |
| 864 | int nFile = last_blockfile; |
| 865 | if (static_cast<int>(m_blockfile_info.size()) <= nFile) { |
| 866 | m_blockfile_info.resize(nFile + 1); |
| 867 | } |
| 868 | |
| 869 | bool finalize_undo = false; |
| 870 | unsigned int max_blockfile_size{MAX_BLOCKFILE_SIZE}; |
| 871 | // Use smaller blockfiles in test-only -fastprune mode - but avoid |
| 872 | // the possibility of having a block not fit into the block file. |
| 873 | if (m_opts.fast_prune) { |
| 874 | max_blockfile_size = 0x10000; // 64kiB |
| 875 | if (nAddSize >= max_blockfile_size) { |
| 876 | // dynamically adjust the blockfile size to be larger than the added size |
| 877 | max_blockfile_size = nAddSize + 1; |
| 878 | } |
| 879 | } |
| 880 | assert(nAddSize < max_blockfile_size); |
| 881 | |
| 882 | while (m_blockfile_info[nFile].nSize + nAddSize >= max_blockfile_size) { |
| 883 | // when the undo file is keeping up with the block file, we want to flush it explicitly |
| 884 | // when it is lagging behind (more blocks arrive than are being connected), we let the |
| 885 | // undo block write case handle it |
| 886 | finalize_undo = (static_cast<int>(m_blockfile_info[nFile].nHeightLast) == |
| 887 | Assert(m_blockfile_cursors[chain_type])->undo_height); |
| 888 | |
| 889 | // Try the next unclaimed blockfile number |
| 890 | nFile = this->MaxBlockfileNum() + 1; |
| 891 | // Set to increment MaxBlockfileNum() for next iteration |
| 892 | m_blockfile_cursors[chain_type] = BlockfileCursor{nFile}; |
| 893 | |
| 894 | if (static_cast<int>(m_blockfile_info.size()) <= nFile) { |
| 895 | m_blockfile_info.resize(nFile + 1); |
| 896 | } |
| 897 | } |
| 898 | FlatFilePos pos; |
| 899 | pos.nFile = nFile; |
| 900 | pos.nPos = m_blockfile_info[nFile].nSize; |
| 901 | |
| 902 | if (nFile != last_blockfile) { |
| 903 | LogDebug(BCLog::BLOCKSTORAGE, "Leaving block file %i: %s (onto %i) (height %i)\n", |
| 904 | last_blockfile, m_blockfile_info[last_blockfile].ToString(), nFile, nHeight); |
| 905 | |
| 906 | // Do not propagate the return code. The flush concerns a previous block |
| 907 | // and undo file that has already been written to. If a flush fails |