Branch data Line data Source code
1 : : // Copyright (c) 2022 The Bitcoin Core developers 2 : : // Distributed under the MIT software license, see the accompanying 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : : 5 : : #include <node/utxo_snapshot.h> 6 : : 7 : : #include <logging.h> 8 : : #include <streams.h> 9 : : #include <sync.h> 10 : : #include <tinyformat.h> 11 : : #include <txdb.h> 12 : : #include <uint256.h> 13 : : #include <util/fs.h> 14 : : #include <validation.h> 15 : : 16 : : #include <cassert> 17 [ + - ]: 2 : #include <cstdio> 18 [ + - ]: 2 : #include <optional> 19 : : #include <string> 20 : : 21 : : namespace node { 22 : : 23 : 0 : bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate) 24 : : { 25 : 0 : AssertLockHeld(::cs_main); 26 [ # # ]: 0 : assert(snapshot_chainstate.m_from_snapshot_blockhash); 27 : : 28 : 0 : const std::optional<fs::path> chaindir = snapshot_chainstate.CoinsDB().StoragePath(); 29 [ # # ]: 0 : assert(chaindir); // Sanity check that chainstate isn't in-memory. 30 [ # # # # : 0 : const fs::path write_to = *chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME; # # # # ] 31 : : 32 [ # # ]: 0 : FILE* file{fsbridge::fopen(write_to, "wb")}; 33 [ # # ]: 0 : AutoFile afile{file}; 34 [ # # # # ]: 0 : if (afile.IsNull()) { 35 [ # # # # : 0 : LogPrintf("[snapshot] failed to open base blockhash file for writing: %s\n", # # # # ] 36 : : fs::PathToString(write_to)); 37 : 0 : return false; 38 : : } 39 [ # # # # ]: 0 : afile << *snapshot_chainstate.m_from_snapshot_blockhash; 40 : : 41 [ # # # # ]: 0 : if (afile.fclose() != 0) { 42 [ # # # # : 0 : LogPrintf("[snapshot] failed to close base blockhash file %s after writing\n", # # # # ] 43 : : fs::PathToString(write_to)); 44 : 0 : return false; 45 : : } 46 : 0 : return true; 47 : 0 : } 48 : : 49 : 0 : std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir) 50 : : { 51 [ # # ]: 2 : if (!fs::exists(chaindir)) { 52 [ # # # # : 0 : LogPrintf("[snapshot] cannot read base blockhash: no chainstate dir " # # # # ] 53 : : "exists at path %s\n", fs::PathToString(chaindir)); 54 : 0 : return std::nullopt; 55 : : } 56 [ # # # # ]: 0 : const fs::path read_from = chaindir / node::SNAPSHOT_BLOCKHASH_FILENAME; 57 [ # # ]: 0 : const std::string read_from_str = fs::PathToString(read_from); 58 : : 59 [ # # # # ]: 0 : if (!fs::exists(read_from)) { 60 [ # # # # : 0 : LogPrintf("[snapshot] snapshot chainstate dir is malformed! no base blockhash file " # # # # ] 61 : : "exists at path %s. Try deleting %s and calling loadtxoutset again?\n", 62 : : fs::PathToString(chaindir), read_from_str); 63 : 0 : return std::nullopt; 64 : : } 65 : : 66 [ # # ]: 0 : uint256 base_blockhash; 67 [ # # ]: 0 : FILE* file{fsbridge::fopen(read_from, "rb")}; 68 [ # # ]: 0 : AutoFile afile{file}; 69 [ # # # # ]: 0 : if (afile.IsNull()) { 70 [ # # # # : 0 : LogPrintf("[snapshot] failed to open base blockhash file for reading: %s\n", # # ] 71 : : read_from_str); 72 : 0 : return std::nullopt; 73 : : } 74 [ # # ]: 2 : afile >> base_blockhash; 75 : : 76 [ # # # # : 0 : if (std::fgetc(afile.Get()) != EOF) { # # ] 77 [ # # # # : 0 : LogPrintf("[snapshot] warning: unexpected trailing data in %s\n", read_from_str); # # ] 78 [ # # # # ]: 0 : } else if (std::ferror(afile.Get())) { 79 [ # # # # : 0 : LogPrintf("[snapshot] warning: i/o error reading %s\n", read_from_str); # # ] 80 : 0 : } 81 [ # # ]: 0 : return base_blockhash; 82 : 0 : } 83 : : 84 : 1 : std::optional<fs::path> FindSnapshotChainstateDir(const fs::path& data_dir) 85 : : { 86 : : fs::path possible_dir = 87 [ + - + - : 1 : data_dir / fs::u8path(strprintf("chainstate%s", SNAPSHOT_CHAINSTATE_SUFFIX)); - + ] 88 : : 89 [ + - - + ]: 1 : if (fs::exists(possible_dir)) { 90 [ # # ]: 0 : return possible_dir; 91 : : } 92 : 1 : return std::nullopt; 93 : 1 : } 94 : : 95 : : } // namespace node