Yes, the above is correct (or at least coincides with my understanding for this elusive code!) - I think the code will do what you describe and that it is the correct behavior wrt finalizing the undo.
However, one piece is missing from the above - when do we flush block file 0?
We go find a position and end up in the next block file (1), at which point we flush the undo file (0)
… and after this we flush the blk file 0.
Just to be explicit, something like this may be warranted, delay the flush of the undo until after we have flushed the block file:
0+ int thisUndoNeedsFlushingAndFinalizing = -1;
1+
2 if (!fKnown) {
3 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
4 // when the undo file is keeping up with the block file, we flush it explicitly, here
5 // when it is lagging behind (more blocks arrive than are being connected), we let the
6 // undo block write case handle it
7 LogPrintf("iterating nFile: last height = %d; chain tip height = %d -> %s\n",
8 vinfoBlockFile[nFile].nHeightLast,
9 ChainActive().Tip()->nHeight,
10 vinfoBlockFile[nFile].nHeightLast == ChainActive().Tip()->nHeight ? "FLUSH UNDO FILE" : "DO NOT FLUSH UNDO FILE");
11 if (vinfoBlockFile[nFile].nHeightLast == ChainActive().Tip()->nHeight) {
12- FlushUndoFile(nFile, true);
13+ thisUndoNeedsFlushingAndFinalizing = nFile;
14 }
15 nFile++;
16 if (vinfoBlockFile.size() <= nFile) {
17 vinfoBlockFile.resize(nFile + 1);
18 }
19 }
20 pos.nFile = nFile;
21 pos.nPos = vinfoBlockFile[nFile].nSize;
22 }
23
24 if ((int)nFile != nLastBlockFile) {
25 if (!fKnown) {
26 LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
27 }
28+ // Order is important: first FlushBlockFile(), then FlushUndoFile().
29+ // FlushBlockFile() will flush internally nLastBlockFile and at this
30+ // point I believe thisUndoNeedsFlushingAndFinalizing == nLastBlockFile
31+ // so we will flush corresponding blk and undo files.
32 FlushBlockFile(!fKnown);
33+ if (thisUndoNeedsFlushingAndFinalizing != -1) {
34+ FlushUndoFile(thisUndoNeedsFlushingAndFinalizing, true);
35+ }
36 nLastBlockFile = nFile;
37 }