fix possible block db breakage during re-index #5864

pull theuni wants to merge 1 commits into bitcoin:master from theuni:fix-reindex-corruption changing 1 files +4 −1
  1. theuni commented at 1:48 am on March 7, 2015: member

    I could really use some more eyes on this. I discussed it briefly with @sipa on IRC a few days ago.

    I noticed this while looking into #5668 . This is one possible explanation I can come up with for overlapping block data. Whether it has anything to do with that issue or not, I think this still needs to be addressed.

    When re-indexing, there are a few cases where garbage data may be skipped in the block files. In these cases, the indices are correctly written to the index db, however the pointer to the next position for writing in the current block file is calculated by adding the sizes of the valid blocks found.

    As a result, when the re-index is finished, the index db is correct for all existing blocks, but the next block will be written to an incorrect offset, likely overwriting existing blocks.

    Rather than using the sum of all valid blocks to determine the next write position, use the end of the last block written to the file. Don’t assume that the current block is the last one in the file, since they may be read out-of-order.

    I was able to trigger this problem by inserting some garbage data between two valid blocks on disk in the last .dat file, then reindexing. After that, run normally for a few min in order to write a few new blocks to disk, then run with -checkblocks=0.

    Before this change, I would get different errors (de-serialization, eof, etc) depending on what garbage i add and where. After the change, it appears to survive the re-index without issue regardless of the garbage.

  2. sipa commented at 12:11 pm on March 7, 2015: member
    Seems very reasonable to me. Even if this doesn’t fix anything, it should be safe.
  3. pstratem commented at 5:37 am on March 9, 2015: contributor

    I ran into this issue today.

    Power failured during IBD.

    Restarted with -reindex=1

    Waited for IBD to finish and then called getblock RPC call for all blocks and got about a dozen ReadBlockFromDisk

  4. in src/main.cpp: in 9add379b92 outdated
    2454@@ -2455,8 +2455,11 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
    2455     }
    2456 
    2457     nLastBlockFile = nFile;
    2458-    vinfoBlockFile[nFile].nSize += nAddSize;
    2459     vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
    2460+    if (fKnown && vinfoBlockFile[nFile].nSize < (pos.nPos + nAddSize))
    2461+        vinfoBlockFile[nFile].nSize = pos.nPos + nAddSize;
    


    laanwj commented at 8:26 am on March 9, 2015:

    Looks good to me, although I’m not sure about the fKnown && vinfoBlockFile[nFile].nSize >= (pos.nPos + nAddSize) case. Would we want to increase nSize at all? Or is this better:

    0if (fKnown)
    1    vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
    2else
    3    vinfoBlockFile[nFile].nSize += nAddSize;
    

    sipa commented at 10:05 am on March 9, 2015:
    ACK this suggested change.

    jgarzik commented at 12:00 pm on March 9, 2015:
    +1

    eN0Rm commented at 2:02 pm on March 9, 2015:

    When can I fetch latest source code, compile and test?

    On Mon, Mar 9, 2015 at 1:01 PM, Jeff Garzik notifications@github.com wrote:

    In src/main.cpp #5864 (review):

    0 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
    
    • if (fKnown && vinfoBlockFile[nFile].nSize < (pos.nPos + nAddSize))
    •    vinfoBlockFile[nFile].nSize = pos.nPos + nAddSize;
      

    +1

    — Reply to this email directly or view it on GitHub https://github.com/bitcoin/bitcoin/pull/5864/files#r26029884.

    Mvh -fredrik-normann-

    Sent from my Gmail Account


    theuni commented at 6:40 pm on March 9, 2015:
    @laanwj Yes, thanks for catching that.
  5. laanwj added the label UTXO Db and Indexes on Mar 9, 2015
  6. laanwj added this to the milestone 0.10.0 on Mar 9, 2015
  7. morcos commented at 6:54 pm on March 9, 2015: member
    I tested this in the this little RPC test, https://gist.github.com/morcos/ae506817284cd776d5b2. Warning it does some raw file IO to munge your block files. Tested and works with and without the suggested change, but fails on master.
  8. theuni force-pushed on Mar 9, 2015
  9. theuni commented at 7:55 pm on March 9, 2015: member
    Updated for @laanwj’s suggestion. @morcos Big thanks for that, much nicer than my manual testnet dd+hexedit hackery :)
  10. theuni force-pushed on Mar 10, 2015
  11. fix possible block db breakage during re-index
    When re-indexing, there are a few cases where garbage data may be skipped in
    the block files. In these cases, the indices are correctly written to the index
    db, however the pointer to the next position for writing in the current block
    file is calculated by adding the sizes of the valid blocks found.
    
    As a result, when the re-index is finished, the index db is correct for all
    existing blocks, but the next block will be written to an incorrect offset,
    likely overwriting existing blocks.
    
    Rather than using the sum of all valid blocks to determine the next write
    position, use the end of the last block written to the file. Don't assume that
    the current block is the last one in the file, since they may be read
    out-of-order.
    bb6acff079
  12. laanwj merged this on Mar 11, 2015
  13. laanwj closed this on Mar 11, 2015

  14. laanwj referenced this in commit 45b7dc2c25 on Mar 11, 2015
  15. laanwj referenced this in commit 002c8a2411 on Mar 11, 2015
  16. laanwj commented at 7:48 am on March 11, 2015: member
    Cherry-picked to 0.10 as 002c8a24119d205b09ee10484097a4b18f4a17a9
  17. reddink referenced this in commit dd46daf548 on May 27, 2020
  18. MarcoFalke locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-10-06 16:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me