diff --git a/flow/ProtocolVersion.h b/flow/ProtocolVersion.h index 2f13c30a1e..dcf69423a4 100644 --- a/flow/ProtocolVersion.h +++ b/flow/ProtocolVersion.h @@ -22,7 +22,24 @@ #include #include "flow/Trace.h" +// This version impacts both communications and the deserialization of certain database and IKeyValueStore keys. +// +// The convention is that 'x' and 'y' should match the major and minor version of the software, and 'z' should be 0. +// To make a change without a corresponding increase to the x.y version, increment the 'dev' digit. +// +// The last 2 bytes (4 digits) of the protocol version do not affect compatibility. These two bytes are not currently +// used and should not be changed from 0. +// xyzdev +// vvvv +constexpr uint64_t currentProtocolVersionValue = 0x0FDB00B071010000LL; + +// The first protocol version that cannot be downgraded from. Ordinarily, this will be two release versions larger +// than the current version, meaning that we only support downgrades between consecutive release versions. +constexpr uint64_t minInvalidProtocolVersionValue = 0x0FDB00B073000000LL; + #define PROTOCOL_VERSION_FEATURE(v, x) \ + static_assert((v & 0xF0FFFFLL) == 0 || v < 0x0FDB00B071000000LL, "Unexpected feature protocol version"); \ + static_assert(v <= currentProtocolVersionValue, "Feature protocol version too large"); \ struct x { \ static constexpr uint64_t protocolVersion = v; \ }; \ @@ -151,17 +168,24 @@ struct Traceable : std::true_type { } }; -// These impact both communications and the deserialization of certain database and IKeyValueStore keys. -// -// The convention is that 'x' and 'y' should match the major and minor version of the software, and 'z' should be 0. -// To make a change without a corresponding increase to the x.y version, increment the 'dev' digit. -// -// xyzdev -// vvvv -constexpr ProtocolVersion currentProtocolVersion(0x0FDB00B071010000LL); +constexpr ProtocolVersion currentProtocolVersion(currentProtocolVersionValue); +constexpr ProtocolVersion minInvalidProtocolVersion(minInvalidProtocolVersionValue); + // This assert is intended to help prevent incrementing the leftmost digits accidentally. It will probably need to // change when we reach version 10. static_assert(currentProtocolVersion.version() < 0x0FDB00B100000000LL, "Unexpected protocol version"); -// Downgrades are only supported for one minor version -constexpr ProtocolVersion minInvalidProtocolVersion(0x0FDB00B073000000LL); +// The last two bytes of the protocol version are currently masked out in compatibility checks. We do not use them, +// so prevent them from being inadvertently changed. +// +// We also do not modify the protocol version for patch releases, so prevent modifying the patch version digit. +static_assert((currentProtocolVersion.version() & 0xF0FFFFLL) == 0, "Unexpected protocol version"); + +// Downgrades must support at least one minor version. +static_assert(minInvalidProtocolVersion.version() >= + (currentProtocolVersion.version() & 0xFFFFFFFFFF000000LL) + 0x0000000002000000, + "Downgrades must support one minor version"); + +// The min invalid protocol version should be the smallest possible protocol version associated with a minor release +// version. +static_assert((minInvalidProtocolVersion.version() & 0xFFFFFFLL) == 0, "Unexpected min invalid protocol version"); \ No newline at end of file diff --git a/flow/serialize.h b/flow/serialize.h index 9e0abbdab1..06824feeb3 100644 --- a/flow/serialize.h +++ b/flow/serialize.h @@ -314,7 +314,7 @@ struct _IncludeVersion { throw err; } if (v >= minInvalidProtocolVersion) { - // Downgrades are only supported for one minor version + // The version v is too large to be downgraded from. auto err = incompatible_protocol_version(); TraceEvent(SevError, "FutureProtocolVersion").error(err).detailf("Version", "%llx", v.versionWithFlags()); throw err;