| 184 | } |
| 185 | |
| 186 | size_t BlockFilterIndex::WriteFilterToDisk(FlatFilePos& pos, const BlockFilter& filter) |
| 187 | { |
| 188 | assert(filter.GetFilterType() == GetFilterType()); |
| 189 | |
| 190 | uint64_t data_size{ |
| 191 | GetSerializeSize(filter.GetBlockHash()) + |
| 192 | GetSerializeSize(filter.GetEncodedFilter())}; |
| 193 | |
| 194 | // If writing the filter would overflow the file, flush and move to the next one. |
| 195 | if (pos.nPos + data_size > MAX_FLTR_FILE_SIZE) { |
| 196 | AutoFile last_file{m_filter_fileseq->Open(pos)}; |
| 197 | if (last_file.IsNull()) { |
| 198 | LogError("Failed to open filter file %d", pos.nFile); |
| 199 | return 0; |
| 200 | } |
| 201 | if (!last_file.Truncate(pos.nPos)) { |
| 202 | LogError("Failed to truncate filter file %d", pos.nFile); |
| 203 | return 0; |
| 204 | } |
| 205 | if (!last_file.Commit()) { |
| 206 | LogError("Failed to commit filter file %d", pos.nFile); |
| 207 | (void)last_file.fclose(); |
| 208 | return 0; |
| 209 | } |
| 210 | if (last_file.fclose() != 0) { |
| 211 | LogError("Failed to close filter file %d after commit: %s", pos.nFile, SysErrorString(errno)); |
| 212 | return 0; |
| 213 | } |
| 214 | |
| 215 | pos.nFile++; |
| 216 | pos.nPos = 0; |
| 217 | } |
| 218 | |
| 219 | // Pre-allocate sufficient space for filter data. |
| 220 | bool out_of_space; |
| 221 | m_filter_fileseq->Allocate(pos, data_size, out_of_space); |
| 222 | if (out_of_space) { |
| 223 | LogError("out of disk space"); |
| 224 | return 0; |
| 225 | } |
| 226 | |
| 227 | AutoFile fileout{m_filter_fileseq->Open(pos)}; |
| 228 | if (fileout.IsNull()) { |
| 229 | LogError("Failed to open filter file %d", pos.nFile); |
| 230 | return 0; |
| 231 | } |
| 232 | |
| 233 | fileout << filter.GetBlockHash() << filter.GetEncodedFilter(); |
| 234 | |
| 235 | if (fileout.fclose() != 0) { |
| 236 | LogError("Failed to close filter file %d: %s", pos.nFile, SysErrorString(errno)); |
| 237 | return 0; |
| 238 | } |
| 239 | |
| 240 | return data_size; |
| 241 | } |
| 242 | |
| 243 | std::optional<uint256> BlockFilterIndex::ReadFilterHeader(int height, const uint256& expected_block_hash) |
nothing calls this directly
no test coverage detected