| 227 | |
| 228 | template <typename Stream> |
| 229 | void AddrManImpl::Unserialize(Stream& s_) |
| 230 | { |
| 231 | LOCK(cs); |
| 232 | |
| 233 | assert(vRandom.empty()); |
| 234 | |
| 235 | Format format; |
| 236 | s_ >> Using<CustomUintFormatter<1>>(format); |
| 237 | |
| 238 | int stream_version = s_.GetVersion(); |
| 239 | if (format >= Format::V3_BIP155) { |
| 240 | // Add ADDRV2_FORMAT to the version so that the CNetAddr and CAddress |
| 241 | // unserialize methods know that an address in addrv2 format is coming. |
| 242 | stream_version |= ADDRV2_FORMAT; |
| 243 | } |
| 244 | |
| 245 | OverrideStream<Stream> s(&s_, s_.GetType(), stream_version); |
| 246 | |
| 247 | uint8_t compat; |
| 248 | s >> compat; |
| 249 | const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE; |
| 250 | if (lowest_compatible > FILE_FORMAT) { |
| 251 | throw InvalidAddrManVersionError(strprintf( |
| 252 | "Unsupported format of addrman database: %u. It is compatible with formats >=%u, " |
| 253 | "but the maximum supported by this version of %s is %u.", |
| 254 | uint8_t{format}, uint8_t{lowest_compatible}, PACKAGE_NAME, uint8_t{FILE_FORMAT})); |
| 255 | } |
| 256 | |
| 257 | s >> nKey; |
| 258 | s >> nNew; |
| 259 | s >> nTried; |
| 260 | int nUBuckets = 0; |
| 261 | s >> nUBuckets; |
| 262 | if (format >= Format::V1_DETERMINISTIC) { |
| 263 | nUBuckets ^= (1 << 30); |
| 264 | } |
| 265 | |
| 266 | if (nNew > ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE || nNew < 0) { |
| 267 | throw std::ios_base::failure( |
| 268 | strprintf("Corrupt AddrMan serialization: nNew=%d, should be in [0, %d]", |
| 269 | nNew, |
| 270 | ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE)); |
| 271 | } |
| 272 | |
| 273 | if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE || nTried < 0) { |
| 274 | throw std::ios_base::failure( |
| 275 | strprintf("Corrupt AddrMan serialization: nTried=%d, should be in [0, %d]", |
| 276 | nTried, |
| 277 | ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE)); |
| 278 | } |
| 279 | |
| 280 | // Deserialize entries from the new table. |
| 281 | for (int n = 0; n < nNew; n++) { |
| 282 | AddrInfo& info = mapInfo[n]; |
| 283 | s >> info; |
| 284 | mapAddr[info] = n; |
| 285 | info.nRandomPos = vRandom.size(); |
| 286 | vRandom.push_back(n); |
nothing calls this directly
no test coverage detected