| 210 | |
| 211 | template <typename Stream> |
| 212 | void AddrManImpl::Unserialize(Stream& s_) |
| 213 | { |
| 214 | LOCK(cs); |
| 215 | |
| 216 | assert(vRandom.empty()); |
| 217 | |
| 218 | Format format; |
| 219 | s_ >> Using<CustomUintFormatter<1>>(format); |
| 220 | |
| 221 | const auto ser_params = (format >= Format::V3_BIP155 ? CAddress::V2_DISK : CAddress::V1_DISK); |
| 222 | ParamsStream s{s_, ser_params}; |
| 223 | |
| 224 | uint8_t compat; |
| 225 | s >> compat; |
| 226 | if (compat < INCOMPATIBILITY_BASE) { |
| 227 | throw std::ios_base::failure(strprintf( |
| 228 | "Corrupted addrman database: The compat value (%u) " |
| 229 | "is lower than the expected minimum value %u.", |
| 230 | compat, INCOMPATIBILITY_BASE)); |
| 231 | } |
| 232 | const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE; |
| 233 | if (lowest_compatible > FILE_FORMAT) { |
| 234 | throw InvalidAddrManVersionError(strprintf( |
| 235 | "Unsupported format of addrman database: %u. It is compatible with formats >=%u, " |
| 236 | "but the maximum supported by this version of %s is %u.", |
| 237 | uint8_t{format}, lowest_compatible, CLIENT_NAME, uint8_t{FILE_FORMAT})); |
| 238 | } |
| 239 | |
| 240 | s >> nKey; |
| 241 | s >> nNew; |
| 242 | s >> nTried; |
| 243 | int nUBuckets = 0; |
| 244 | s >> nUBuckets; |
| 245 | if (format >= Format::V1_DETERMINISTIC) { |
| 246 | nUBuckets ^= (1 << 30); |
| 247 | } |
| 248 | |
| 249 | if (nNew > ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE || nNew < 0) { |
| 250 | throw std::ios_base::failure( |
| 251 | strprintf("Corrupt AddrMan serialization: nNew=%d, should be in [0, %d]", |
| 252 | nNew, |
| 253 | ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE)); |
| 254 | } |
| 255 | |
| 256 | if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE || nTried < 0) { |
| 257 | throw std::ios_base::failure( |
| 258 | strprintf("Corrupt AddrMan serialization: nTried=%d, should be in [0, %d]", |
| 259 | nTried, |
| 260 | ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE)); |
| 261 | } |
| 262 | |
| 263 | // Deserialize entries from the new table. |
| 264 | for (int n = 0; n < nNew; n++) { |
| 265 | AddrInfo& info = mapInfo[n]; |
| 266 | s >> info; |
| 267 | mapAddr[info] = n; |
| 268 | info.nRandomPos = vRandom.size(); |
| 269 | vRandom.push_back(n); |
nothing calls this directly
no test coverage detected