blockstorage: XOR blocksdir *.dat files #28052

pull maflcko wants to merge 3 commits into bitcoin:master from maflcko:2306-fs_stuff- changing 10 files +97 −16
  1. maflcko commented at 8:07 AM on July 8, 2023: member

    Currently the *.dat files in the blocksdir store the data received from remote peers as-is. This may be problematic when a program other than Bitcoin Core tries to interpret them by accident. For example, an anti-virus program or other program may scan them and move them into quarantine, or delete them, or corrupt them. This may cause Bitcoin Core to fail a reorg, or fail to reply to block requests (via P2P, RPC, REST, ...).

    Fix this, similar to #6650, by rolling a random XOR pattern over the dat files when writing or reading them.

    Obviously this can only protect against programs that accidentally and unintentionally are trying to mess with the dat files. Any program that intentionally wants to mess with the dat files can still trivially do so.

    The XOR pattern is only applied when the blocksdir is freshly created, and there is an option to disable it (on creation), so that people can disable it, if needed.

  2. DrahtBot commented at 8:07 AM on July 8, 2023: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage

    For detailed information about the code coverage, see the test coverage report.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #28687 (C++20 std::views::reverse by stickies-v)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. maflcko renamed this:
    XOR blocksdir *.dat files
    blockstorage: XOR blocksdir *.dat files
    on Jul 8, 2023
  4. DrahtBot added the label Block storage on Jul 8, 2023
  5. DrahtBot added the label CI failed on Jul 8, 2023
  6. maflcko force-pushed on Jul 8, 2023
  7. jamesob commented at 5:19 PM on July 8, 2023: contributor

    Concept ACK. Certainly worth doing.

  8. sipa marked this as ready for review on Jul 8, 2023
  9. sipa commented at 5:28 PM on July 8, 2023: member

    Oops, I clicked wrong.

    I just meant to Concept ACK.

  10. maflcko marked this as a draft on Jul 9, 2023
  11. luke-jr commented at 6:02 PM on July 9, 2023: member

    AFAIK there is software which reads these files intentionally. IMO they can be expected to adapt, but having the option to disable it seems like a good idea in case they aren't ready right away.

  12. sedited commented at 8:30 AM on July 10, 2023: contributor

    Strong Concept ACK.

  13. maflcko force-pushed on Jul 10, 2023
  14. maflcko commented at 10:21 AM on July 10, 2023: member

    Thanks for the feedback so far. I've kept the option to disable, but made it a simple bool instead of allowing the user to pick the XOR-key.

    If someone is interested, a new commit can be added to upgrade the linearize scripts to read the XOR-key.

  15. DrahtBot added the label Needs rebase on Jul 11, 2023
  16. maflcko force-pushed on Jul 12, 2023
  17. DrahtBot removed the label Needs rebase on Jul 12, 2023
  18. dergoegge commented at 12:19 PM on July 13, 2023: member

    Concept ACK

  19. DrahtBot added the label Needs rebase on Jul 31, 2023
  20. maflcko force-pushed on Aug 1, 2023
  21. maflcko commented at 2:06 PM on August 1, 2023: member
  22. DrahtBot removed the label Needs rebase on Aug 1, 2023
  23. fanquake referenced this in commit ceda819886 on Aug 1, 2023
  24. DrahtBot removed the label CI failed on Aug 1, 2023
  25. in test/functional/feature_reindex.py:44 in f0d2c3f73e outdated
      39 | @@ -39,9 +40,18 @@ def out_of_order(self):
      40 |          # we're generating them rather than getting them from peers), so to
      41 |          # test out-of-order handling, swap blocks 1 and 2 on disk.
      42 |          blk0 = self.nodes[0].blocks_path / "blk00000.dat"
      43 | +        with open(self.nodes[0].blocks_path / "xor.key", "rb") as xor_f:
      44 | +            xor_dat = deser_string(xor_f)
    


    maflcko commented at 4:39 PM on August 1, 2023:

    I guess it may be simpler to serialize and deserialize the xor key as a raw byte span (without the size indicator). This should make it even easier to read in external scripts, for example in vanilla python.

    Edit: And readers can assume it to be constant size. For example:

    NUM_XOR_BYTES{8}
    

    maflcko commented at 8:06 AM on August 2, 2023:

    Done

  26. maflcko force-pushed on Aug 1, 2023
  27. darosior commented at 7:23 AM on August 2, 2023: member

    Concept ACK.

  28. maflcko marked this as ready for review on Aug 2, 2023
  29. maflcko force-pushed on Aug 2, 2023
  30. maflcko force-pushed on Aug 2, 2023
  31. maflcko commented at 8:25 AM on August 2, 2023: member

    Rebased, and made every commit a refactor, except for the one that has release notes and test changes :)

  32. willcl-ark commented at 1:53 PM on August 2, 2023: member

    Concept ACK.

    I've not reviewed the code in detail yet, but this is a nice followup to #28060.

    It seems to work well so far. I wrote a quick-n-dirty python script to manually xor my data dir using the same 8 byte key from this pull, and Bitcoin Core at commit fa3c1d230a didn't have any problems reading the xored blocks or key afterwards.

  33. DrahtBot added the label CI failed on Sep 10, 2023
  34. maflcko force-pushed on Sep 11, 2023
  35. kristapsk commented at 11:29 AM on September 11, 2023: contributor

    Concept ACK

  36. DrahtBot removed the label CI failed on Sep 11, 2023
  37. fanquake referenced this in commit 8209e86eeb on Sep 14, 2023
  38. DrahtBot added the label Needs rebase on Sep 14, 2023
  39. maflcko force-pushed on Sep 14, 2023
  40. DrahtBot removed the label Needs rebase on Sep 14, 2023
  41. DrahtBot added the label CI failed on Sep 14, 2023
  42. maflcko force-pushed on Sep 14, 2023
  43. maflcko commented at 3:14 PM on September 14, 2023: member

    Given that most of this is refactoring, which makes sense on its own, I've split that up into #28483 and turned this pull into a draft for now.

  44. maflcko marked this as a draft on Sep 14, 2023
  45. DrahtBot removed the label CI failed on Sep 14, 2023
  46. fanquake referenced this in commit c9f288244b on Sep 26, 2023
  47. DrahtBot added the label Needs rebase on Sep 26, 2023
  48. maflcko marked this as ready for review on Sep 28, 2023
  49. maflcko force-pushed on Sep 28, 2023
  50. DrahtBot added the label CI failed on Sep 28, 2023
  51. DrahtBot removed the label Needs rebase on Sep 28, 2023
  52. DrahtBot removed the label CI failed on Sep 28, 2023
  53. maflcko force-pushed on Oct 4, 2023
  54. pablomartin4btc commented at 7:55 PM on October 26, 2023: member

    tACK fa9f3f70011842e2c4358d15ab4639734d976f5c

    <details> <summary>Played around with the <code>xor.key</code> file, if I changed it (use case: "<code>The created XOR-key will be zeros for an existing blocksdir</code>"), I got the <code>Corrupted block database detected</code> error, which can be easily resolved just deleting the file and running the node back up again will re-create the <code>xor.key</code> file correctly.</summary>

    2023-10-26T18:07:06Z init message: Verifying blocks…
    2023-10-26T18:07:06Z Verifying last 6 blocks at level 3
    2023-10-26T18:07:06Z Verification progress: 0%
    2023-10-26T18:07:06Z ERROR: ReadBlockFromDisk: Deserialize or I/O error - ReadCompactSize(): size too large: iostream error at FlatFilePos(nFile=5, nPos=62189381)
    2023-10-26T18:07:06Z Verification error: ReadBlockFromDisk failed at 160000, hash=0000003ca3c99aff040f2563c2ad8f8ec88bd0fd6b8f0895cfaf1ef90353a62c
    2023-10-26T18:07:06Z : Corrupted block database detected.
    Please restart with -reindex or -reindex-chainstate to recover.
    : Corrupted block database detected.
    Please restart with -reindex or -reindex-chainstate to recover.
    2023-10-26T18:07:06Z Aborted block database rebuild. Exiting.
    2023-10-26T18:07:06Z Shutdown: In progress...
    2023-10-26T18:07:06Z scheduler thread exit
    2023-10-26T18:07:06Z Flushed fee estimates to fee_estimates.dat.
    2023-10-26T18:07:06Z Shutdown: done
    

    2023-10-26T18:12:03Z Using xor key for *.dat files: '0000000000000000'

    </details>

    Now, considering the possibility of the XOR key file getting corrupted (for example, accidentally opening it with an app that offers to 'fix' a corruption) or being deleted, especially on a fresh run when a random XOR key is generated (which I've also tested), wouldn't it be better to save the key in the .conf or settings?

    Before having that thought, I was considering proposing to give the option to the user to specify the filename, but that would add complexity, and I'm not sure if it's worth it.

  55. DrahtBot requested review from sipa on Oct 26, 2023
  56. DrahtBot requested review from jamesob on Oct 26, 2023
  57. DrahtBot requested review from willcl-ark on Oct 26, 2023
  58. DrahtBot requested review from dergoegge on Oct 26, 2023
  59. DrahtBot requested review from darosior on Oct 26, 2023
  60. DrahtBot requested review from sedited on Oct 26, 2023
  61. maflcko commented at 8:23 AM on October 27, 2023: member

    wouldn't it be better to save the key in the .conf or settings?

    The key is not a configuration or setting that is supposed to be modified by a user or that can be changed at all. Once it is persisted to storage, it is set in stone for all (future) dat files.

  62. DrahtBot added the label Needs rebase on Oct 30, 2023
  63. maflcko force-pushed on Oct 30, 2023
  64. DrahtBot removed the label Needs rebase on Oct 30, 2023
  65. pablomartin4btc commented at 4:48 PM on October 30, 2023: member

    re ACK fa6b180beb20d64962c2b5440eeacb31ed889a81

  66. maflcko force-pushed on Nov 22, 2023
  67. lrs955 commented at 12:31 PM on November 23, 2023: none

    why not save the xor key inside the leveldb block database?

    wouldn't it be better to save the key in the .conf or settings?

    The key is not a configuration or setting that is supposed to be modified by a user or that can be changed at all. Once it is persisted to storage, it is set in stone for all (future) dat files.

  68. maflcko commented at 12:34 PM on November 23, 2023: member

    why not save the xor key inside the leveldb block database?

    Just seems more complicated with no benefit?

  69. lrs955 commented at 6:17 PM on November 23, 2023: none

    why not save the xor key inside the leveldb block database?

    Just seems more complicated with no benefit?

    I understand. Maybe im wrong but isn't also the xor pattern of the chainstate saved in the database itself? Different leveldb database but still in a key a database.

  70. DrahtBot added the label CI failed on Dec 13, 2023
  71. DrahtBot removed the label CI failed on Dec 14, 2023
  72. DrahtBot added the label Needs rebase on Dec 14, 2023
  73. maflcko force-pushed on Mar 22, 2024
  74. DrahtBot removed the label Needs rebase on Mar 22, 2024
  75. willcl-ark commented at 2:15 PM on March 22, 2024: member

    While you're re-touching, I think it could be worth adding an entry to doc/files.md too, especially as losing/not backing-up this file results in requiring a full reindex?

  76. maflcko commented at 3:03 PM on March 22, 2024: member

    especially as losing/not backing-up this file results in requiring a full reindex?

    I don't think this is true. The xor key can trivially be restored by xor-ing the first 8 bytes of the first block file with the first 8 bytes of the first block file of a datadir created with the xor disabled. This works, because the first block written should be the genesis block, always.

    In python:

    >>> bytes(a ^ b for a,b in zip(open('blk00000.dat', 'rb').read()[:8], open('clean-blk00000.dat', 'rb').read()[:8])).hex()
    '228b70bf9c1abb3f'
    >>> open('xor.key', 'rb').read().hex()  # double-check
    '228b70bf9c1abb3f'
    
  77. maflcko force-pushed on Mar 22, 2024
  78. maflcko commented at 4:12 PM on March 22, 2024: member

    doc/files.md

    Done

  79. in src/node/blockstorage.cpp:1164 in faaf3cf535 outdated
    1169 | +    if (!fs::is_empty(opts.blocks_dir) || opts.xor_key == false) std::fill(xor_key.begin(), xor_key.end(), std::byte{});
    1170 | +    const fs::path xor_key_path{opts.blocks_dir / "xor.dat"};
    1171 | +    if (fs::exists(xor_key_path)) {
    1172 | +        // A pre-existing xor key file has priority.
    1173 | +        AutoFile xor_key_file{fsbridge::fopen(xor_key_path, "rb")};
    1174 | +        xor_key_file >> xor_key;
    


    willcl-ark commented at 9:25 AM on May 1, 2024:

    Jjust noting here that if the user specifies -blocksxor=01234567 and a file-based key already exists in the datadir, the key from the file is silently used.

    This is the correct behaviour IMO, but wonder if we should log that the user-set option has been overridden?

    As @maflcko pointed out to me previously, even if a user mistakenly thought they were using a custom xor key set as a CL option and removed the key file, they could still restore it. So I don't see any dangers with this current behaviour.


    maflcko commented at 9:52 AM on May 1, 2024:

    -blocksxor=01234567

    The option is boolean, so I guess it could throw here. In any case, the setting won't have an effect on an existing blocksdir, even on -reindex. Maybe the manpage can be adjusted to clarify this?


    hodlinator commented at 10:24 PM on July 16, 2024:

    (In response to #28052 (review))

    Tested bitcoind -blocksxor=01234567, which does not throw. Evaluates to true. Discussion seems to have stalled since #12713 https://github.com/bitcoin/bitcoin/blob/6f9db1ebcab4064065ccd787161bf2b87e03cc1f/src/common/args.cpp#L43-L63


    maflcko commented at 5:53 AM on July 17, 2024:

    See #16545

  80. willcl-ark approved
  81. willcl-ark commented at 9:38 AM on May 1, 2024: member

    ACK faaf3cf535999c2c9a84337414c8b35435384862

    Nice change with the same rationale as the previous mempool XOR changes (preventing anti-virus falsely flagging/modifying block files).

    One non-blocking comment left as a result of manual testing.

  82. DrahtBot requested review from pablomartin4btc on May 1, 2024
  83. in test/functional/feature_reindex.py:42 in faaf3cf535 outdated
      38 | @@ -39,9 +39,19 @@ def out_of_order(self):
      39 |          # we're generating them rather than getting them from peers), so to
      40 |          # test out-of-order handling, swap blocks 1 and 2 on disk.
      41 |          blk0 = self.nodes[0].blocks_path / "blk00000.dat"
      42 | +        with open(self.nodes[0].blocks_path / "xor.dat", "rb") as xor_f:
    


    sedited commented at 3:05 PM on May 11, 2024:

    Just a comment: This test implicitly checks if the blockfiles are XORed. Would a simple additional check on the undo data make sense?


    maflcko commented at 1:46 PM on July 5, 2024:

    Yes, ideally in a separate, new test.

  84. in src/node/blockstorage.cpp:1188 in faaf3cf535 outdated
    1183 | +            strprintf("The blocksdir XOR-key can not be disabled when a random key was already stored! "
    1184 | +                      "Stored key: '%s', stored path: '%s'.",
    1185 | +                      HexStr(xor_key), fs::PathToString(xor_key_path)),
    1186 | +        };
    1187 | +    }
    1188 | +    LogInfo("Using xor key for *.dat files: '%s'\n", HexStr(xor_key));
    


    sedited commented at 7:24 PM on May 11, 2024:

    Nit: This prints as:

    Using xor key for *.dat files: '0000000000000000'`
    

    But the log lines informing the user on data obfuscation in the other DBs use:

    Using obfuscation key for /home/drgrid/.bitcoin/blocks/index: 0000000000000000
    Using obfuscation key for /home/drgrid/.bitcoin/chainstate: a3b154cf1d9714d7
    

    I think it would be nice to be consistent here, both by listing the full directory and using the same text.


    maflcko commented at 2:07 PM on July 5, 2024:

    I'd say DB obfuscation is different from *.dat obfuscation, but I've made the messages a bit more similar. Thanks!

  85. in src/node/blockstorage.cpp:1169 in faaf3cf535 outdated
    1164 | +    std::array<std::byte, 8> xor_key{};
    1165 | +
    1166 | +    // Initialize random fresh key, ...
    1167 | +    FastRandomContext{}.fillrand(xor_key);
    1168 | +    // ... but allow legacy or user-disabled key.
    1169 | +    if (!fs::is_empty(opts.blocks_dir) || opts.xor_key == false) std::fill(xor_key.begin(), xor_key.end(), std::byte{});
    


    sedited commented at 7:48 PM on May 11, 2024:

    Nit: I found this a bit hard to follow and a bit unfortunate that a new random key would be generated every time whether it were used or not. How about:

    @@ -1166,4 +1165,0 @@ static auto InitBlocksdirXorKey(const BlockManager::Options& opts)
    -    // Initialize random fresh key, ...
    -    FastRandomContext{}.fillrand(xor_key);
    -    // ... but allow legacy or user-disabled key.
    -    if (!fs::is_empty(opts.blocks_dir) || opts.xor_key == false) std::fill(xor_key.begin(), xor_key.end(), std::byte{});
    @@ -1171 +1167,8 @@ static auto InitBlocksdirXorKey(const BlockManager::Options& opts)
    -    if (fs::exists(xor_key_path)) {
    +    bool key_exists = fs::exists(xor_key_path);
    +
    +    if (!key_exists && opts.xor_key && fs::is_empty(opts.blocks_dir)) {
    +        // Initialize random fresh key, ...
    +        FastRandomContext{}.fillrand(xor_key);
    +    }
    +
    +    if (key_exists) {
    

    maflcko commented at 2:06 PM on July 5, 2024:

    Good feedback. I've inverted the if condition (and branch). Hope it is clearer now?


    sedited commented at 3:22 PM on July 26, 2024:

    Thanks, this is clearer now.

  86. sedited approved
  87. sedited commented at 7:50 PM on May 11, 2024: contributor

    ACK faaf3cf535999c2c9a84337414c8b35435384862

  88. DrahtBot added the label Needs rebase on May 20, 2024
  89. maflcko force-pushed on Jul 5, 2024
  90. DrahtBot removed the label Needs rebase on Jul 5, 2024
  91. in src/kernel/blockmanager_opts.h:17 in fae8e0a982 outdated
      13 | @@ -14,12 +14,15 @@ class CChainParams;
      14 |  
      15 |  namespace kernel {
      16 |  
      17 | +static constexpr bool DEFAULT_XOR_KEY_BLOCKSDIR{true};
    


    hodlinator commented at 9:15 PM on July 16, 2024:

    Including "KEY" makes me think the variable would itself contain the default XOR pattern.

    static constexpr bool DEFAULT_XOR_BLOCKSDIR{true};
    

    Same goes for bool xor_key below.. would call it bool xored_on_disk or something.


    maflcko commented at 6:28 AM on July 17, 2024:

    Thanks, taken!


    hodlinator commented at 7:26 AM on July 17, 2024:

    Good to see the removal of == true as well in InitBlocksdirXorKey(). :+1:

  92. in src/init.cpp:1557 in fae8e0a982 outdated
    1550 | @@ -1544,7 +1551,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1551 |          }
    1552 |          LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    1553 |  
    1554 | -        node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown), chainman_opts, blockman_opts);
    1555 | +        try {
    1556 | +            node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown), chainman_opts, blockman_opts);
    1557 | +        } catch (std::exception& e) {
    1558 | +            return InitError(strprintf(Untranslated("Internal error: %s"), e.what()));
    


    hodlinator commented at 9:17 PM on July 16, 2024:

    Error messages should be as specific as possible to aid troubleshooting.

                return InitError(strprintf(Untranslated("Failed to initialize ChainstateManager: %s"), e.what()));
    

    maflcko commented at 6:27 AM on July 17, 2024:

    Thanks, taken!

  93. in src/node/blockstorage.cpp:1183 in fae8e0a982 outdated
    1178 | +        // A pre-existing xor key file has priority.
    1179 | +        AutoFile xor_key_file{fsbridge::fopen(xor_key_path, "rb")};
    1180 | +        xor_key_file >> xor_key;
    1181 | +    } else {
    1182 | +        // Create initial or missing xor key file
    1183 | +        AutoFile xor_key_file{fsbridge::fopen(xor_key_path, "wbx")};
    


    hodlinator commented at 10:13 PM on July 16, 2024:

    (https://cplusplus.com/reference/cstdio/fopen/ stated that "x" was only part of C2011, not C++. But it is included from C++17 according to https://en.cppreference.com/w/cpp/io/c/fopen).


    maflcko commented at 6:27 AM on July 17, 2024:

    Thanks, but actually it doesn't work when running on Windows. Added a new commit with a workaround.

  94. hodlinator commented at 10:31 PM on July 16, 2024: contributor

    Concept ACK fae8e0a9825d107431f3f33e4f70fe54d02ab3e3 (Haven't had time to look at the tests yet).

    Appreciate the robustness of InitBlocksdirXorKey() after some testing of removing the blocks/xor.dat file, re-running bitcoind. hexdumping it, removing the whole blocks/ directory, rerunning, hexdumping again etc.

  95. maflcko force-pushed on Jul 17, 2024
  96. in src/node/blockstorage.cpp:1164 in fa986c918a outdated
    1159 | +{
    1160 | +    // Bytes are serialized without length indicator, so this is also the exact
    1161 | +    // size of the XOR-key file.
    1162 | +    std::array<std::byte, 8> xor_key{};
    1163 | +
    1164 | +    if (fs::is_empty(opts.blocks_dir) && opts.use_xor) {
    


    hodlinator commented at 7:28 AM on July 17, 2024:

    nit: Could put cheapest condition first:

        if (opts.use_xor && fs::is_empty(opts.blocks_dir)) {
    

    maflcko commented at 8:34 AM on July 17, 2024:

    May do if I have to re-touch. This is only called once per process, so shouldn't matter.


    maflcko commented at 8:43 AM on July 17, 2024:

    Thanks, done!

  97. in test/functional/feature_reindex.py:76 in fa986c918a outdated
      74 | +            b_new[b3_start:b4_start] = b[b2_start:b3_start]
      75 | +            b_new = util_xor(b_new, xor_dat)
      76 |              bf.seek(b2_start)
      77 | -            bf.write(b[b3_start:b4_start])
      78 | -            bf.write(b[b2_start:b3_start])
      79 | +            bf.write(b_new[b2_start:b4_start])
    


    hodlinator commented at 8:04 AM on July 17, 2024:

    Smaller change if we make util_xor() take an offset:

    diff --git a/test/functional/feature_reindex.py b/test/functional/feature_reindex.py
    index f079a5e343..9f3f5357ba 100755
    --- a/test/functional/feature_reindex.py
    +++ b/test/functional/feature_reindex.py
    @@ -43,15 +43,15 @@ class ReindexTest(BitcoinTestFramework):
                 NUM_XOR_BYTES = 8 # From InitBlocksdirXorKey::xor_key.size()
                 xor_dat = xor_f.read(NUM_XOR_BYTES)
     
    -        def util_xor(data, key):
    +        def util_xor(data, key, offset):
                 data = bytearray(data)
                 for i in range(len(data)):
    -                data[i] ^= key[i % len(key)]
    +                data[i] ^= key[(i + offset) % len(key)]
                 return bytes(data)
     
             with open(blk0, 'r+b') as bf:
                 # Read at least the first few blocks (including genesis)
    -            b = util_xor(bf.read(2000), xor_dat)
    +            b = util_xor(bf.read(2000), xor_dat, 0)
     
                 # Find the offsets of blocks 2, 3, and 4 (the first 3 blocks beyond genesis)
                 # by searching for the regtest marker bytes (see pchMessageStart).
    @@ -68,12 +68,9 @@ class ReindexTest(BitcoinTestFramework):
                 assert_equal(b3_start - b2_start, b4_start - b3_start)
     
                 # Swap the second and third blocks (don't disturb the genesis block).
    -            b_new = bytearray(b)
    -            b_new[b2_start:b3_start] = b[b3_start:b4_start]
    -            b_new[b3_start:b4_start] = b[b2_start:b3_start]
    -            b_new = util_xor(b_new, xor_dat)
                 bf.seek(b2_start)
    -            bf.write(b_new[b2_start:b4_start])
    +            bf.write(util_xor(b[b3_start:b4_start], xor_dat, b2_start))
    +            bf.write(util_xor(b[b2_start:b3_start], xor_dat, b3_start))
     
             # The reindexing code should detect and accommodate out of order blocks.
             with self.nodes[0].assert_debug_log([
    

    maflcko commented at 8:43 AM on July 17, 2024:

    Thanks, done!

  98. hodlinator approved
  99. hodlinator commented at 8:09 AM on July 17, 2024: contributor

    ACK fa986c918a239cabda198f044b6eb9739c298be9

  100. DrahtBot requested review from willcl-ark on Jul 17, 2024
  101. DrahtBot requested review from sedited on Jul 17, 2024
  102. maflcko force-pushed on Jul 17, 2024
  103. hodlinator approved
  104. hodlinator commented at 9:05 AM on July 17, 2024: contributor

    re-ACK fa9d4aa9a1a8df6343f615572479db9c8e26b19d

  105. DrahtBot added the label Needs rebase on Jul 26, 2024
  106. maflcko force-pushed on Jul 26, 2024
  107. Return XOR AutoFile from BlockManager::Open*File()
    This is a refactor, because the XOR key is empty.
    fa7f7ac040
  108. maflcko force-pushed on Jul 26, 2024
  109. DrahtBot added the label CI failed on Jul 26, 2024
  110. DrahtBot commented at 10:32 AM on July 26, 2024: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Debug: https://github.com/bitcoin/bitcoin/runs/27958379841</sub>

    <details><summary>Hints</summary>

    Make sure to run all tests locally, according to the documentation.

    The failure may happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  111. in src/node/blockstorage.cpp:1155 in fab2287c6e outdated
    1150 | +    // Bytes are serialized without length indicator, so this is also the exact
    1151 | +    // size of the XOR-key file.
    1152 | +    std::array<std::byte, 8> xor_key{};
    1153 | +
    1154 | +    if (opts.use_xor && fs::is_empty(opts.blocks_dir)) {
    1155 | +        // Only use random fresh key when the boolean option is set and when on
    


    sedited commented at 10:37 AM on July 26, 2024:

    Typo nit: s/and when on/and on/


    maflcko commented at 3:31 PM on July 26, 2024:

    Thanks, fixed

  112. maflcko force-pushed on Jul 26, 2024
  113. maflcko commented at 2:19 PM on July 26, 2024: member

    Shuffled the format string to work around the linter bug.

  114. sedited approved
  115. sedited commented at 3:21 PM on July 26, 2024: contributor

    Re-ACK fa51f311ee4f2295c7bd82f46e27dc043a33f955

  116. DrahtBot requested review from hodlinator on Jul 26, 2024
  117. Add -blocksxor boolean option fa359255fe
  118. mingw: Document mode wbx workaround fa895c7283
  119. maflcko force-pushed on Jul 26, 2024
  120. sedited approved
  121. sedited commented at 3:35 PM on July 26, 2024: contributor

    Re-ACK fa895c72832f9555b52d5bb1dba1093f73de3136

    Just a typo fix since last push.

  122. DrahtBot removed the label Needs rebase on Jul 26, 2024
  123. DrahtBot removed the label CI failed on Jul 26, 2024
  124. hodlinator approved
  125. hodlinator commented at 9:23 PM on July 26, 2024: contributor

    ACK fa895c72832f9555b52d5bb1dba1093f73de3136

    git range-diff fa9d4aa9a1a8df6343f615572479db9c8e26b19d~3 fa9d4aa9a1a8df6343f615572479db9c8e26b19d fa895c72832f9555b52d5bb1dba1093f73de3136

    Confirmed only thing that really changed was:

    • Merging with mainly 7aa8994c6fceae5cf8fb7e661371cdb19d2cb482 - " refactor: Add FlatFileSeq member variables in BlockManager "
    • Correcting CAutoFile -> AutoFile in commit message
    • Comment typo in InitBlocksdirXorKey
    • LogInfo format string re-jiggling.

    Passed make check & test_runner.py.


    It would be nice to get to the bottom with why

    LogInfo("Using obfuscation key for %s/*.dat files: '%s'\n", fs::PathToString(opts.blocks_dir), HexStr(xor_key));
    

    was worse than

    LogInfo("Using obfuscation key for blocksdir *.dat files (%s): '%s'\n", fs::PathToString(opts.blocks_dir), HexStr(xor_key));
    

    and fix test/lint/run-lint-format-strings.py in the longer term.

  126. achow101 commented at 9:35 PM on August 5, 2024: member

    ACK fa895c72832f9555b52d5bb1dba1093f73de3136

  127. achow101 merged this on Aug 5, 2024
  128. achow101 closed this on Aug 5, 2024

  129. maflcko deleted the branch on Aug 7, 2024
  130. maflcko commented at 9:16 AM on August 7, 2024: member

    Follow-up ideas for this pull requests are:

  131. hodlinator commented at 1:18 PM on August 7, 2024: contributor

    Is there some label or something that can assist people in discovering this kind of follow-up work on closed/merged PRs?

  132. maflcko commented at 1:22 PM on August 7, 2024: member

    Is there some label or something that can assist people in discovering this kind of follow-up work on closed/merged PRs?

    I've moved it to an issue, see https://github.com/bitcoin/bitcoin/issues/30599

  133. achow101 referenced this in commit ba5fdd1a68 on Aug 12, 2024
  134. glozow referenced this in commit 6474132d1b on Aug 16, 2024
  135. PastaPastaPasta referenced this in commit 414bfe58b2 on Oct 25, 2024
  136. phlip9 referenced this in commit 1c29aff27b on Nov 15, 2024
  137. shesek referenced this in commit 1a70de9074 on Nov 23, 2024
  138. liuchengxu referenced this in commit 95940cfe1f on Dec 2, 2024
  139. bitcoin deleted a comment on Jul 2, 2025
  140. DashCoreAutoGuix referenced this in commit 1f073fac37 on Jul 27, 2025
  141. DashCoreAutoGuix referenced this in commit b6f28f8740 on Jul 28, 2025
  142. DashCoreAutoGuix referenced this in commit 0f19c51f93 on Aug 2, 2025
  143. knst referenced this in commit 7060c3d08d on Oct 22, 2025
  144. ivanlele referenced this in commit e2c90769ca on Mar 11, 2026
  145. Kino1994 referenced this in commit 6abfb5d0bf on Jun 28, 2026
  146. Kino1994 referenced this in commit 3d768d7de7 on Jun 28, 2026
  147. Kino1994 referenced this in commit 5389fec2c0 on Jun 28, 2026
  148. Kino1994 referenced this in commit cb15b541a5 on Jun 28, 2026
  149. BigcoinBGC referenced this in commit 6bdd12ec3a on Jun 30, 2026
  150. BigcoinBGC referenced this in commit 3862a04179 on Jun 30, 2026
  151. BigcoinBGC referenced this in commit f27a1937b9 on Jun 30, 2026
  152. BigcoinBGC referenced this in commit 3130422f99 on Jun 30, 2026
  153. bitcoin locked this on Jul 30, 2026

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: 2026-08-01 03:52 UTC

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