|
19 | 19 | #include <pow.h> |
20 | 20 | #include <primitives/block.h> |
21 | 21 | #include <primitives/transaction.h> |
| 22 | +#include <random.h> |
22 | 23 | #include <reverse_iterator.h> |
23 | 24 | #include <serialize.h> |
24 | 25 | #include <signet.h> |
@@ -1144,9 +1145,43 @@ FlatFilePos BlockManager::SaveBlockToDisk(const CBlock& block, int nHeight) |
1144 | 1145 | return blockPos; |
1145 | 1146 | } |
1146 | 1147 |
|
| 1148 | +static auto InitBlocksdirXorKey(const BlockManager::Options& opts) |
| 1149 | +{ |
| 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 on the |
| 1156 | + // very first start of the program. |
| 1157 | + FastRandomContext{}.fillrand(xor_key); |
| 1158 | + } |
| 1159 | + |
| 1160 | + const fs::path xor_key_path{opts.blocks_dir / "xor.dat"}; |
| 1161 | + if (fs::exists(xor_key_path)) { |
| 1162 | + // A pre-existing xor key file has priority. |
| 1163 | + AutoFile xor_key_file{fsbridge::fopen(xor_key_path, "rb")}; |
| 1164 | + xor_key_file >> xor_key; |
| 1165 | + } else { |
| 1166 | + // Create initial or missing xor key file |
| 1167 | + AutoFile xor_key_file{fsbridge::fopen(xor_key_path, "wbx")}; |
| 1168 | + xor_key_file << xor_key; |
| 1169 | + } |
| 1170 | + // If the user disabled the key, it must be zero. |
| 1171 | + if (!opts.use_xor && xor_key != decltype(xor_key){}) { |
| 1172 | + throw std::runtime_error{ |
| 1173 | + strprintf("The blocksdir XOR-key can not be disabled when a random key was already stored! " |
| 1174 | + "Stored key: '%s', stored path: '%s'.", |
| 1175 | + HexStr(xor_key), fs::PathToString(xor_key_path)), |
| 1176 | + }; |
| 1177 | + } |
| 1178 | + LogInfo("Using obfuscation key for blocksdir *.dat files (%s): '%s'\n", fs::PathToString(opts.blocks_dir), HexStr(xor_key)); |
| 1179 | + return std::vector<std::byte>{xor_key.begin(), xor_key.end()}; |
| 1180 | +} |
| 1181 | + |
1147 | 1182 | BlockManager::BlockManager(const util::SignalInterrupt& interrupt, Options opts) |
1148 | 1183 | : m_prune_mode{opts.prune_target > 0}, |
1149 | | - m_xor_key{}, |
| 1184 | + m_xor_key{InitBlocksdirXorKey(opts)}, |
1150 | 1185 | m_opts{std::move(opts)}, |
1151 | 1186 | m_block_file_seq{FlatFileSeq{m_opts.blocks_dir, "blk", m_opts.fast_prune ? 0x4000 /* 16kB */ : BLOCKFILE_CHUNK_SIZE}}, |
1152 | 1187 | m_undo_file_seq{FlatFileSeq{m_opts.blocks_dir, "rev", UNDOFILE_CHUNK_SIZE}}, |
|
0 commit comments