Changeset View
Changeset View
Standalone View
Standalone View
src/protocol.h
| Show First 20 Lines • Show All 480 Lines • ▼ Show 20 Lines | |||||
| public: | public: | ||||
| CAddress() : CService{} {}; | CAddress() : CService{} {}; | ||||
| CAddress(CService ipIn, ServiceFlags nServicesIn) | CAddress(CService ipIn, ServiceFlags nServicesIn) | ||||
| : CService{ipIn}, nServices{nServicesIn} {}; | : CService{ipIn}, nServices{nServicesIn} {}; | ||||
| CAddress(CService ipIn, ServiceFlags nServicesIn, NodeSeconds time) | CAddress(CService ipIn, ServiceFlags nServicesIn, NodeSeconds time) | ||||
| : CService{ipIn}, nTime{time}, nServices{nServicesIn} {}; | : CService{ipIn}, nTime{time}, nServices{nServicesIn} {}; | ||||
| SERIALIZE_METHODS(CAddress, obj) { | enum class Format { | ||||
| // CAddress has a distinct network serialization and a disk | Disk, | ||||
| // serialization, but it should never be hashed (except through | Network, | ||||
| // CHashWriter in addrdb.cpp, which sets SER_DISK), and it's ambiguous | }; | ||||
| // what that would mean. Make sure no code relying on that is | struct SerParams : CNetAddr::SerParams { | ||||
| // introduced: | const Format fmt; | ||||
| assert(!(s.GetType() & SER_GETHASH)); | }; | ||||
| static constexpr SerParams V1_NETWORK{{CNetAddr::Encoding::V1}, | |||||
| Format::Network}; | |||||
| static constexpr SerParams V2_NETWORK{{CNetAddr::Encoding::V2}, | |||||
| Format::Network}; | |||||
| static constexpr SerParams V1_DISK{{CNetAddr::Encoding::V1}, Format::Disk}; | |||||
| static constexpr SerParams V2_DISK{{CNetAddr::Encoding::V2}, Format::Disk}; | |||||
| SERIALIZE_METHODS_PARAMS(CAddress, obj, SerParams, params) { | |||||
| bool use_v2; | bool use_v2; | ||||
| if (s.GetType() & SER_DISK) { | if (params.fmt == Format::Disk) { | ||||
| // In the disk serialization format, the encoding (v1 or v2) is | // In the disk serialization format, the encoding (v1 or v2) is | ||||
| // determined by a flag version that's part of the serialization | // determined by a flag version that's part of the serialization | ||||
| // itself. ADDRV2_FORMAT in the stream version only determines | // itself. ADDRV2_FORMAT in the stream version only determines | ||||
| // whether V2 is chosen/permitted at all. | // whether V2 is chosen/permitted at all. | ||||
| uint32_t stored_format_version = DISK_VERSION_INIT; | uint32_t stored_format_version = DISK_VERSION_INIT; | ||||
| if (s.GetVersion() & ADDRV2_FORMAT) { | if (params.enc == Encoding::V2) { | ||||
| stored_format_version |= DISK_VERSION_ADDRV2; | stored_format_version |= DISK_VERSION_ADDRV2; | ||||
| } | } | ||||
| READWRITE(stored_format_version); | READWRITE(stored_format_version); | ||||
| stored_format_version &= | stored_format_version &= | ||||
| ~DISK_VERSION_IGNORE_MASK; // ignore low bits | ~DISK_VERSION_IGNORE_MASK; // ignore low bits | ||||
| if (stored_format_version == 0) { | if (stored_format_version == 0) { | ||||
| use_v2 = false; | use_v2 = false; | ||||
| } else if (stored_format_version == DISK_VERSION_ADDRV2 && | } else if (stored_format_version == DISK_VERSION_ADDRV2 && | ||||
| (s.GetVersion() & ADDRV2_FORMAT)) { | params.enc == Encoding::V2) { | ||||
| // Only support v2 deserialization if ADDRV2_FORMAT is set. | // Only support v2 deserialization if V2 is set. | ||||
| use_v2 = true; | use_v2 = true; | ||||
| } else { | } else { | ||||
| throw std::ios_base::failure( | throw std::ios_base::failure( | ||||
| "Unsupported CAddress disk format version"); | "Unsupported CAddress disk format version"); | ||||
| } | } | ||||
| } else { | } else { | ||||
| assert(params.fmt == Format::Network); | |||||
| // In the network serialization format, the encoding (v1 or v2) is | // In the network serialization format, the encoding (v1 or v2) is | ||||
| // determined directly by the value of ADDRV2_FORMAT in the stream | // determined directly by the value of enc in the stream params, as | ||||
| // version, as no explicitly encoded version exists in the stream. | // no explicitly encoded version exists in the stream. | ||||
| assert(s.GetType() & SER_NETWORK); | use_v2 = params.enc == Encoding::V2; | ||||
| use_v2 = s.GetVersion() & ADDRV2_FORMAT; | |||||
| } | } | ||||
| READWRITE(Using<LossyChronoFormatter<uint32_t>>(obj.nTime)); | READWRITE(Using<LossyChronoFormatter<uint32_t>>(obj.nTime)); | ||||
| // nServices is serialized as CompactSize in V2; as uint64_t in V1. | // nServices is serialized as CompactSize in V2; as uint64_t in V1. | ||||
| if (use_v2) { | if (use_v2) { | ||||
| uint64_t services_tmp; | uint64_t services_tmp; | ||||
| SER_WRITE(obj, services_tmp = obj.nServices); | SER_WRITE(obj, services_tmp = obj.nServices); | ||||
| READWRITE(Using<CompactSizeFormatter<false>>(services_tmp)); | READWRITE(Using<CompactSizeFormatter<false>>(services_tmp)); | ||||
| SER_READ(obj, | SER_READ(obj, | ||||
| obj.nServices = static_cast<ServiceFlags>(services_tmp)); | obj.nServices = static_cast<ServiceFlags>(services_tmp)); | ||||
| } else { | } else { | ||||
| READWRITE(Using<CustomUintFormatter<8>>(obj.nServices)); | READWRITE(Using<CustomUintFormatter<8>>(obj.nServices)); | ||||
| } | } | ||||
| // Invoke V1/V2 serializer for CService parent object. | // Invoke V1/V2 serializer for CService parent object. | ||||
| OverrideStream<Stream> os(&s, s.GetType(), use_v2 ? ADDRV2_FORMAT : 0); | const auto ser_params{use_v2 ? CNetAddr::V2 : CNetAddr::V1}; | ||||
| SerReadWriteMany(os, ser_action, AsBase<CService>(obj)); | READWRITE(WithParams(ser_params, AsBase<CService>(obj))); | ||||
| } | } | ||||
| //! Always included in serialization, except in the network format on | //! Always included in serialization, except in the network format on | ||||
| //! INIT_PROTO_VERSION. | //! INIT_PROTO_VERSION. | ||||
| NodeSeconds nTime{TIME_INIT}; | NodeSeconds nTime{TIME_INIT}; | ||||
| //! Serialized as uint64_t in V1, and as CompactSize in V2. | //! Serialized as uint64_t in V1, and as CompactSize in V2. | ||||
| ServiceFlags nServices{NODE_NONE}; | ServiceFlags nServices{NODE_NONE}; | ||||
| ▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines | |||||