From the PR description:
The function GetFirstStoredBlock() helps us find the first block for which we have data. So far this function only looked for a block with BLOCK_HAVE_DATA. However, this doesn't mean that we also have the undo data of that block, and undo data might be required for what a user would like to do with those blocks. One example of how this might happen is if some blocks were fetched using the getblockfrompeer RPC. Blocks fetched from a peer will have data but no undo data.
In the second commit I am applying the undo check to the RPCs that report pruneheight to the user. I find this much more intuitive because I think the user expects to be able to do all operations on blocks up until the pruneheight but that is not the case if undo data is missing. I personally ran into this once before and now again when testing for assumeutxo when I had used getblockfrompeer. The following commit adds test coverage for this change of behavior.
This is a partial backport of core#29668 and core#30429
https://github.com/bitcoin/bitcoin/pull/29668/commits/4a1975008b602aeacdad9a74d1837a7455148074
https://github.com/bitcoin/bitcoin/pull/29668/commits/8789dc8f315a9d9ad7142d831bc9412f780248e7
https://github.com/bitcoin/bitcoin/pull/30429/commits/fa6270737eb9655bfb4e29b7070ecb6cd2087b7f
Depends on D17924