I think this will not deserialize properly anchors.dat from before this PR.
CLIENT_VERSION is something like 219900
ADDRV2_FORMAT is 0x20000000
In anchors.dat before this PR we have CAddress entries which contain version=219900 and addresses serialized in addrv1 format.
With this PR we will set the stream version to ADDRV2_FORMAT during deserialize:
// Notice added comments below
SERIALIZE_METHODS(CAddress, obj)
{
SER_READ(obj, obj.nTime = TIME_INIT);
int nVersion = s.GetVersion(); // nVersion will be assigned ADDRV2_FORMAT (0x20000000)
if (s.GetType() & SER_DISK) {
READWRITE(nVersion); // nVersion will be assigned CLIENT_VERSION (219900)
}
...
if (nVersion & ADDRV2_FORMAT) { // this will be false
uint64_t services_tmp;
SER_WRITE(obj, services_tmp = obj.nServices);
READWRITE(Using<CompactSizeFormatter<false>>(services_tmp));
SER_READ(obj, obj.nServices = static_cast<ServiceFlags>(services_tmp));
} else {
// it will read services as 8 bytes (correct, as that is what is actually stored on disk)
READWRITE(Using<CustomUintFormatter<8>>(obj.nServices));
}
// oops, this will deserialize CService, which will deserialize CNetAddr which will check
// s.GetVersion() which is ADDRV2_FORMAT (0x20000000) and will deserialize the
// address as if it is stored in addrv2 format on disk, but it is actually stored in addrv1,
// so this will deserialize garbage
READWRITEAS(CService, obj);
}