| 124 | |
| 125 | template <typename Stream> |
| 126 | void AddrManImpl::Serialize(Stream& s_) const |
| 127 | { |
| 128 | LOCK(cs); |
| 129 | |
| 130 | /** |
| 131 | * Serialized format. |
| 132 | * * format version byte (@see `Format`) |
| 133 | * * lowest compatible format version byte. This is used to help old software decide |
| 134 | * whether to parse the file. For example: |
| 135 | * * Bitcoin Core version N knows how to parse up to format=3. If a new format=4 is |
| 136 | * introduced in version N+1 that is compatible with format=3 and it is known that |
| 137 | * version N will be able to parse it, then version N+1 will write |
| 138 | * (format=4, lowest_compatible=3) in the first two bytes of the file, and so |
| 139 | * version N will still try to parse it. |
| 140 | * * Bitcoin Core version N+2 introduces a new incompatible format=5. It will write |
| 141 | * (format=5, lowest_compatible=5) and so any versions that do not know how to parse |
| 142 | * format=5 will not try to read the file. |
| 143 | * * nKey |
| 144 | * * nNew |
| 145 | * * nTried |
| 146 | * * number of "new" buckets XOR 2**30 |
| 147 | * * all new addresses (total count: nNew) |
| 148 | * * all tried addresses (total count: nTried) |
| 149 | * * for each new bucket: |
| 150 | * * number of elements |
| 151 | * * for each element: index in the serialized "all new addresses" |
| 152 | * * asmap checksum |
| 153 | * |
| 154 | * 2**30 is xorred with the number of buckets to make addrman deserializer v0 detect it |
| 155 | * as incompatible. This is necessary because it did not check the version number on |
| 156 | * deserialization. |
| 157 | * |
| 158 | * vvNew, vvTried, mapInfo, mapAddr and vRandom are never encoded explicitly; |
| 159 | * they are instead reconstructed from the other information. |
| 160 | * |
| 161 | * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports |
| 162 | * changes to the ADDRMAN_ parameters without breaking the on-disk structure. |
| 163 | * |
| 164 | * We don't use SERIALIZE_METHODS since the serialization and deserialization code has |
| 165 | * very little in common. |
| 166 | */ |
| 167 | |
| 168 | // Always serialize in the latest version (FILE_FORMAT). |
| 169 | |
| 170 | OverrideStream<Stream> s(&s_, s_.GetType(), s_.GetVersion() | ADDRV2_FORMAT); |
| 171 | |
| 172 | s << static_cast<uint8_t>(FILE_FORMAT); |
| 173 | |
| 174 | // Increment `lowest_compatible` iff a newly introduced format is incompatible with |
| 175 | // the previous one. |
| 176 | static constexpr uint8_t lowest_compatible = Format::V4_MULTIPORT; |
| 177 | s << static_cast<uint8_t>(INCOMPATIBILITY_BASE + lowest_compatible); |
| 178 | |
| 179 | s << nKey; |
| 180 | s << nNew; |
| 181 | s << nTried; |
| 182 | |
| 183 | int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); |
nothing calls this directly
no test coverage detected