/root/bitcoin/src/node/utxo_snapshot.h
| Line | Count | Source | 
| 1 |  | // Copyright (c) 2009-2010 Satoshi Nakamoto | 
| 2 |  | // Copyright (c) 2009-2022 The Bitcoin Core developers | 
| 3 |  | // Distributed under the MIT software license, see the accompanying | 
| 4 |  | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | 
| 5 |  |  | 
| 6 |  | #ifndef BITCOIN_NODE_UTXO_SNAPSHOT_H | 
| 7 |  | #define BITCOIN_NODE_UTXO_SNAPSHOT_H | 
| 8 |  |  | 
| 9 |  | #include <chainparams.h> | 
| 10 |  | #include <kernel/chainparams.h> | 
| 11 |  | #include <kernel/cs_main.h> | 
| 12 |  | #include <serialize.h> | 
| 13 |  | #include <sync.h> | 
| 14 |  | #include <uint256.h> | 
| 15 |  | #include <util/chaintype.h> | 
| 16 |  | #include <util/check.h> | 
| 17 |  | #include <util/fs.h> | 
| 18 |  |  | 
| 19 |  | #include <cstdint> | 
| 20 |  | #include <optional> | 
| 21 |  | #include <string_view> | 
| 22 |  |  | 
| 23 |  | // UTXO set snapshot magic bytes | 
| 24 |  | static constexpr std::array<uint8_t, 5> SNAPSHOT_MAGIC_BYTES = {'u', 't', 'x', 'o', 0xff}; | 
| 25 |  |  | 
| 26 |  | class Chainstate; | 
| 27 |  |  | 
| 28 |  | namespace node { | 
| 29 |  | //! Metadata describing a serialized version of a UTXO set from which an | 
| 30 |  | //! assumeutxo Chainstate can be constructed. | 
| 31 |  | //! All metadata fields come from an untrusted file, so must be validated | 
| 32 |  | //! before being used. Thus, new fields should be added only if needed. | 
| 33 |  | class SnapshotMetadata | 
| 34 |  | { | 
| 35 |  |     inline static const uint16_t VERSION{2}; | 
| 36 |  |     const std::set<uint16_t> m_supported_versions{VERSION}; | 
| 37 |  |     const MessageStartChars m_network_magic; | 
| 38 |  | public: | 
| 39 |  |     //! The hash of the block that reflects the tip of the chain for the | 
| 40 |  |     //! UTXO set contained in this snapshot. | 
| 41 |  |     uint256 m_base_blockhash; | 
| 42 |  |  | 
| 43 |  |  | 
| 44 |  |     //! The number of coins in the UTXO set contained in this snapshot. Used | 
| 45 |  |     //! during snapshot load to estimate progress of UTXO set reconstruction. | 
| 46 |  |     uint64_t m_coins_count = 0; | 
| 47 |  |  | 
| 48 |  |     SnapshotMetadata( | 
| 49 |  |         const MessageStartChars network_magic) : | 
| 50 | 0 |             m_network_magic(network_magic) { } | 
| 51 |  |     SnapshotMetadata( | 
| 52 |  |         const MessageStartChars network_magic, | 
| 53 |  |         const uint256& base_blockhash, | 
| 54 |  |         uint64_t coins_count) : | 
| 55 | 0 |             m_network_magic(network_magic), | 
| 56 | 0 |             m_base_blockhash(base_blockhash), | 
| 57 | 0 |             m_coins_count(coins_count) { } | 
| 58 |  |  | 
| 59 |  |     template <typename Stream> | 
| 60 | 0 |     inline void Serialize(Stream& s) const { | 
| 61 | 0 |         s << SNAPSHOT_MAGIC_BYTES; | 
| 62 | 0 |         s << VERSION; | 
| 63 | 0 |         s << m_network_magic; | 
| 64 | 0 |         s << m_base_blockhash; | 
| 65 | 0 |         s << m_coins_count; | 
| 66 | 0 |     } Unexecuted instantiation: _ZNK4node16SnapshotMetadata9SerializeI10DataStreamEEvRT_Unexecuted instantiation: _ZNK4node16SnapshotMetadata9SerializeI8AutoFileEEvRT_ | 
| 67 |  |  | 
| 68 |  |     template <typename Stream> | 
| 69 | 0 |     inline void Unserialize(Stream& s) { | 
| 70 |  |         // Read the snapshot magic bytes | 
| 71 | 0 |         std::array<uint8_t, SNAPSHOT_MAGIC_BYTES.size()> snapshot_magic; | 
| 72 | 0 |         s >> snapshot_magic; | 
| 73 | 0 |         if (snapshot_magic != SNAPSHOT_MAGIC_BYTES) { | 
| 74 | 0 |             throw std::ios_base::failure("Invalid UTXO set snapshot magic bytes. Please check if this is indeed a snapshot file or if you are using an outdated snapshot format."); | 
| 75 | 0 |         } | 
| 76 |  |  | 
| 77 |  |         // Read the version | 
| 78 | 0 |         uint16_t version; | 
| 79 | 0 |         s >> version; | 
| 80 | 0 |         if (m_supported_versions.find(version) == m_supported_versions.end()) { | 
| 81 | 0 |             throw std::ios_base::failure(strprintf("Version of snapshot %s does not match any of the supported versions.", version)); | 
| 82 | 0 |         } | 
| 83 |  |  | 
| 84 |  |         // Read the network magic (pchMessageStart) | 
| 85 | 0 |         MessageStartChars message; | 
| 86 | 0 |         s >> message; | 
| 87 | 0 |         if (!std::equal(message.begin(), message.end(), m_network_magic.data())) { | 
| 88 | 0 |             auto metadata_network{GetNetworkForMagic(message)}; | 
| 89 | 0 |             if (metadata_network) { | 
| 90 | 0 |                 std::string network_string{ChainTypeToString(metadata_network.value())}; | 
| 91 | 0 |                 auto node_network{GetNetworkForMagic(m_network_magic)}; | 
| 92 | 0 |                 std::string node_network_string{ChainTypeToString(node_network.value())}; | 
| 93 | 0 |                 throw std::ios_base::failure(strprintf("The network of the snapshot (%s) does not match the network of this node (%s).", network_string, node_network_string)); | 
| 94 | 0 |             } else { | 
| 95 | 0 |                 throw std::ios_base::failure("This snapshot has been created for an unrecognized network. This could be a custom signet, a new testnet or possibly caused by data corruption."); | 
| 96 | 0 |             } | 
| 97 | 0 |         } | 
| 98 |  |  | 
| 99 | 0 |         s >> m_base_blockhash; | 
| 100 | 0 |         s >> m_coins_count; | 
| 101 | 0 |     } Unexecuted instantiation: _ZN4node16SnapshotMetadata11UnserializeI10DataStreamEEvRT_Unexecuted instantiation: _ZN4node16SnapshotMetadata11UnserializeI8AutoFileEEvRT_ | 
| 102 |  | }; | 
| 103 |  |  | 
| 104 |  | //! The file in the snapshot chainstate dir which stores the base blockhash. This is | 
| 105 |  | //! needed to reconstruct snapshot chainstates on init. | 
| 106 |  | //! | 
| 107 |  | //! Because we only allow loading a single snapshot at a time, there will only be one | 
| 108 |  | //! chainstate directory with this filename present within it. | 
| 109 |  | const fs::path SNAPSHOT_BLOCKHASH_FILENAME{"base_blockhash"}; | 
| 110 |  |  | 
| 111 |  | //! Write out the blockhash of the snapshot base block that was used to construct | 
| 112 |  | //! this chainstate. This value is read in during subsequent initializations and | 
| 113 |  | //! used to reconstruct snapshot-based chainstates. | 
| 114 |  | bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate) | 
| 115 |  |     EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | 
| 116 |  |  | 
| 117 |  | //! Read the blockhash of the snapshot base block that was used to construct the | 
| 118 |  | //! chainstate. | 
| 119 |  | std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir) | 
| 120 |  |     EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | 
| 121 |  |  | 
| 122 |  | //! Suffix appended to the chainstate (leveldb) dir when created based upon | 
| 123 |  | //! a snapshot. | 
| 124 |  | constexpr std::string_view SNAPSHOT_CHAINSTATE_SUFFIX = "_snapshot"; | 
| 125 |  |  | 
| 126 |  |  | 
| 127 |  | //! Return a path to the snapshot-based chainstate dir, if one exists. | 
| 128 |  | std::optional<fs::path> FindSnapshotChainstateDir(const fs::path& data_dir); | 
| 129 |  |  | 
| 130 |  | } // namespace node | 
| 131 |  |  | 
| 132 |  | #endif // BITCOIN_NODE_UTXO_SNAPSHOT_H |