Skip to content

Commit

Permalink
Report the server version in published validations:
Browse files Browse the repository at this point in the history
Currently there is no mechanism for a validator to report the
version of the software it is currently running. Such reports
can be useful for those who are developing network monitoring
dashboards and server operators in general.

This commit, if merged, defines an encoding scheme to encode
a version string into a 64-bit unsigned integer and adds an
additional optional field to validations.

This commit piggybacks on "HardenedValidations" amendment to
determine whether version information should be propagated
or not.

The general encoding scheme is:

XXXXXXXX-XXXXXXXX-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY

X: 16 bits identifying the particular implementation
Y: 48 bits of data specific to the implementation

The rippled-specific format (implementation ID is: 0x18 0x3B) is:

00011000-00111011-MMMMMMMM-mmmmmmmm-pppppppp-TTNNNNNN-00000000-00000000

    M: 8-bit major version (0-255)
    m: 8-bit minor version (0-255)
    p: 8-bit patch version (0-255)
    T: 11 if neither an RC nor a beta
       10 if an RC
       01 if a beta
    N: 6-bit rc/beta number (1-63)
  • Loading branch information
nbougalis committed Apr 28, 2020
1 parent f945245 commit 117c724
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/ripple/app/consensus/RCLConsensus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <ripple/nodestore/DatabaseShard.h>
#include <ripple/overlay/Overlay.h>
#include <ripple/overlay/predicates.h>
#include <ripple/protocol/BuildInfo.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/digest.h>

Expand Down Expand Up @@ -790,6 +791,10 @@ RCLConsensus::Adaptor::validate(
v.setFieldH256(sfValidatedHash, vl->info().hash);

v.setFieldU64(sfCookie, valCookie_);

// Report our server version every flag ledger:
if ((ledger.seq() + 1) % 256 == 0)
v.setFieldU64(sfServerVersion, BuildInfo::getEncodedVersion());
}

// Report our load
Expand Down
25 changes: 25 additions & 0 deletions src/ripple/protocol/BuildInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@ getVersionString();
std::string const&
getFullVersionString();

/** Returns the server version packed in a 64-bit integer.
The general format is:
........-........-........-........-........-........-........-........
XXXXXXXX-XXXXXXXX-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY
X: 16 bits identifying the particular implementation
Y: 48 bits of data specific to the implementation
The rippled-specific format (implementation ID is: 0x18 0x3B) is:
00011000-00111011-MMMMMMMM-mmmmmmmm-pppppppp-TTNNNNNN-00000000-00000000
M: 8-bit major version (0-255)
m: 8-bit minor version (0-255)
p: 8-bit patch version (0-255)
T: 11 if neither an RC nor a beta
10 if an RC
01 if a beta
N: 6-bit rc/beta number (1-63)
*/
std::uint64_t
getEncodedVersion();

} // namespace BuildInfo

} // namespace ripple
Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/SField.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ extern SF_U64 const sfLowNode;
extern SF_U64 const sfHighNode;
extern SF_U64 const sfDestinationNode;
extern SF_U64 const sfCookie;
extern SF_U64 const sfServerVersion;

// 128-bit
extern SF_U128 const sfEmailHash;
Expand Down
74 changes: 73 additions & 1 deletion src/ripple/protocol/impl/BuildInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
//==============================================================================

#include <ripple/basics/contract.h>
#include <ripple/beast/core/LexicalCast.h>
#include <ripple/beast/core/SemanticVersion.h>
#include <ripple/protocol/BuildInfo.h>

#include <boost/preprocessor/stringize.hpp>
#include <algorithm>

namespace ripple {

Expand Down Expand Up @@ -76,6 +77,77 @@ getFullVersionString()
return value;
}

std::uint64_t
getEncodedVersion()
{
static std::uint64_t const cookie = []() {
std::uint64_t c = 0x183B000000000000;

beast::SemanticVersion v;

if (v.parse(versionString))
{
if (v.majorVersion >= 0 && v.majorVersion <= 255)
c |= static_cast<std::uint64_t>(v.majorVersion) << 40;

if (v.minorVersion >= 0 && v.minorVersion <= 255)
c |= static_cast<std::uint64_t>(v.minorVersion) << 32;

if (v.patchVersion >= 0 && v.patchVersion <= 255)
c |= static_cast<std::uint64_t>(v.patchVersion) << 24;

if (!v.isPreRelease())
c |= static_cast<std::uint64_t>(0xC00000);

if (v.isPreRelease())
{
std::uint8_t x = 0;

for (auto id : v.preReleaseIdentifiers)
{
auto parsePreRelease =
[](std::string_view identifier,
std::string_view prefix,
std::uint8_t key,
std::uint8_t lok,
std::uint8_t hik) -> std::uint8_t {
std::uint8_t ret = 0;

if (prefix != identifier.substr(0, prefix.length()))
return 0;

if (!beast::lexicalCastChecked(
ret,
std::string(
identifier.substr(prefix.length()))))
return 0;

if (std::clamp(ret, lok, hik) != ret)
return 0;

return ret + key;
};

x = parsePreRelease(id, "rc", 0x80, 0, 63);

if (x == 0)
x = parsePreRelease(id, "b", 0x40, 0, 63);

if (x & 0xC0)
{
c |= static_cast<std::uint64_t>(x) << 16;
break;
}
}
}
}

return c;
}();

return cookie;
}

} // namespace BuildInfo

} // namespace ripple
1 change: 1 addition & 0 deletions src/ripple/protocol/impl/SField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ SF_U64 const sfLowNode(access, STI_UINT64, 7, "LowNode");
SF_U64 const sfHighNode(access, STI_UINT64, 8, "HighNode");
SF_U64 const sfDestinationNode(access, STI_UINT64, 9, "DestinationNode");
SF_U64 const sfCookie(access, STI_UINT64, 10, "Cookie");
SF_U64 const sfServerVersion(access, STI_UINT64, 11, "ServerVersion");

// 128-bit
SF_U128 const sfEmailHash(access, STI_HASH128, 1, "EmailHash");
Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/impl/STValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ SOTemplate const STValidation::validationFormat{
{sfConsensusHash, soeOPTIONAL},
{sfCookie, soeDEFAULT},
{sfValidatedHash, soeOPTIONAL},
{sfServerVersion, soeOPTIONAL},
};

uint256
Expand Down

0 comments on commit 117c724

Please sign in to comment.