| 392 | CAddress(CService ipIn, ServiceFlags nServicesIn, uint32_t nTimeIn) : CService{ipIn}, nTime{nTimeIn}, nServices{nServicesIn} {}; |
| 393 | |
| 394 | SERIALIZE_METHODS(CAddress, obj) |
| 395 | { |
| 396 | // CAddress has a distinct network serialization and a disk serialization, but it should never |
| 397 | // be hashed (except through CHashWriter in addrdb.cpp, which sets SER_DISK), and it's |
| 398 | // ambiguous what that would mean. Make sure no code relying on that is introduced: |
| 399 | assert(!(s.GetType() & SER_GETHASH)); |
| 400 | bool use_v2; |
| 401 | if (s.GetType() & SER_DISK) { |
| 402 | // In the disk serialization format, the encoding (v1 or v2) is determined by a flag version |
| 403 | // that's part of the serialization itself. ADDRV2_FORMAT in the stream version only determines |
| 404 | // whether V2 is chosen/permitted at all. |
| 405 | uint32_t stored_format_version = DISK_VERSION_INIT; |
| 406 | if (s.GetVersion() & ADDRV2_FORMAT) stored_format_version |= DISK_VERSION_ADDRV2; |
| 407 | READWRITE(stored_format_version); |
| 408 | stored_format_version &= ~DISK_VERSION_IGNORE_MASK; // ignore low bits |
| 409 | if (stored_format_version == 0) { |
| 410 | use_v2 = false; |
| 411 | } else if (stored_format_version == DISK_VERSION_ADDRV2 && (s.GetVersion() & ADDRV2_FORMAT)) { |
| 412 | // Only support v2 deserialization if ADDRV2_FORMAT is set. |
| 413 | use_v2 = true; |
| 414 | } else { |
| 415 | throw std::ios_base::failure("Unsupported CAddress disk format version"); |
| 416 | } |
| 417 | } else { |
| 418 | // In the network serialization format, the encoding (v1 or v2) is determined directly by |
| 419 | // the value of ADDRV2_FORMAT in the stream version, as no explicitly encoded version |
| 420 | // exists in the stream. |
| 421 | assert(s.GetType() & SER_NETWORK); |
| 422 | use_v2 = s.GetVersion() & ADDRV2_FORMAT; |
| 423 | } |
| 424 | |
| 425 | SER_READ(obj, obj.nTime = TIME_INIT); |
| 426 | READWRITE(obj.nTime); |
| 427 | // nServices is serialized as CompactSize in V2; as uint64_t in V1. |
| 428 | if (use_v2) { |
| 429 | uint64_t services_tmp; |
| 430 | SER_WRITE(obj, services_tmp = obj.nServices); |
| 431 | READWRITE(Using<CompactSizeFormatter<false>>(services_tmp)); |
| 432 | SER_READ(obj, obj.nServices = static_cast<ServiceFlags>(services_tmp)); |
| 433 | } else { |
| 434 | READWRITE(Using<CustomUintFormatter<8>>(obj.nServices)); |
| 435 | } |
| 436 | // Invoke V1/V2 serializer for CService parent object. |
| 437 | OverrideStream<Stream> os(&s, s.GetType(), use_v2 ? ADDRV2_FORMAT : 0); |
| 438 | SerReadWriteMany(os, ser_action, ReadWriteAsHelper<CService>(obj)); |
| 439 | } |
| 440 | |
| 441 | //! Always included in serialization. |
| 442 | uint32_t nTime{TIME_INIT}; |
nothing calls this directly
no test coverage detected