Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9316f24
[WIP] Toying with the idea of VL exchange
ximinez Jan 21, 2021
eca1267
Merge branch 'develop' into unlsync
ximinez Nov 12, 2025
4dc8ab4
Merge branch 'develop' into unlsync
ximinez Nov 13, 2025
b21b93c
Merge branch 'develop' into unlsync
ximinez Nov 15, 2025
454e060
Merge branch 'develop' into unlsync
ximinez Nov 19, 2025
5463f3d
Merge branch 'develop' into unlsync
ximinez Nov 21, 2025
6a8071a
Merge branch 'develop' into unlsync
ximinez Nov 25, 2025
a749c81
Merge branch 'develop' into unlsync
ximinez Nov 28, 2025
95c03ee
Merge branch 'develop' into unlsync
ximinez Dec 1, 2025
81f1f5c
Merge branch 'develop' into unlsync
ximinez Dec 3, 2025
db9aa06
Merge branch 'develop' into unlsync
ximinez Dec 6, 2025
ca19741
Merge branch 'develop' into unlsync
ximinez Dec 13, 2025
1523729
Merge branch 'develop' into unlsync
ximinez Dec 19, 2025
2ab1c05
Merge branch 'develop' into unlsync
ximinez Dec 22, 2025
c428538
Merge branch 'develop' into unlsync
ximinez Jan 6, 2026
4c9e8a6
Merge branch 'develop' into unlsync
ximinez Jan 8, 2026
53920ed
Merge branch 'develop' into unlsync
ximinez Jan 8, 2026
dfa281e
Merge branch 'develop' into unlsync
ximinez Jan 11, 2026
d11f577
Merge branch 'develop' into unlsync
ximinez Jan 12, 2026
a59bc90
Merge branch 'develop' into unlsync
ximinez Jan 13, 2026
dd273b9
Merge branch 'develop' into unlsync
ximinez Jan 15, 2026
2901e12
Merge commit '92046785d1fea5f9efe5a770d636792ea6cab78b' into unlsync
ximinez Jan 28, 2026
371d5ca
Merge commit '5f638f55536def0d88b970d1018a465a238e55f4' into unlsync
ximinez Jan 28, 2026
fdd295e
Merge branch 'develop' into unlsync
ximinez Jan 28, 2026
4152d2e
Fix formatting
ximinez Jan 29, 2026
6d99efb
Merge branch 'develop' into unlsync
ximinez Feb 4, 2026
6786d73
Merge branch 'develop' into unlsync
ximinez Feb 19, 2026
86bcb1f
Merge branch 'develop' into unlsync
ximinez Feb 19, 2026
3734f72
Merge commit '25cca465538a56cce501477f9e5e2c1c7ea2d84c' into unlsync
ximinez Feb 20, 2026
d4c7bdc
Update formatting
ximinez Feb 20, 2026
dc89961
Merge commit '2c1fad1023' into unlsync
ximinez Feb 21, 2026
ee1e680
Merge remote-tracking branch 'upstream/develop' into unlsync
ximinez Feb 21, 2026
9de9247
Merge branch 'develop' into unlsync
ximinez Feb 24, 2026
2ef0944
Merge branch 'develop' into unlsync
ximinez Mar 4, 2026
0f9d52f
Merge branch 'develop' into unlsync
ximinez Mar 4, 2026
e44343d
Merge branch 'develop' into unlsync
ximinez Mar 6, 2026
daa6e49
Merge branch 'develop' into unlsync
ximinez Mar 10, 2026
2e404c4
Merge remote-tracking branch 'ximinez/develop' into unlsync
ximinez Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/xrpld/app/misc/ValidatorList.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ class ValidatorList
static std::vector<ValidatorBlobInfo>
parseBlobs(protocol::TMValidatorListCollection const& body);

static void
static std::optional<std::string>
sendValidatorList(
Peer& peer,
std::uint64_t peerSequence,
Expand All @@ -351,6 +351,14 @@ class ValidatorList
HashRouter& hashRouter,
beast::Journal j);

std::tuple<std::string, std::uint32_t, std::map<std::size_t, ValidatorBlobInfo>, uint256>
sendLatestValidatorLists(
Peer& peer,
std::uint64_t peerSequence,
PublicKey const& publisherKey,
HashRouter& hashRouter,
beast::Journal j) const;

[[nodiscard]] static std::pair<std::size_t, std::size_t>
buildValidatorListMessages(
std::size_t messageVersion,
Expand Down Expand Up @@ -788,7 +796,7 @@ class ValidatorList
HashRouter& hashRouter,
beast::Journal j);

static void
static std::optional<std::string>
sendValidatorList(
Peer& peer,
std::uint64_t peerSequence,
Expand Down
60 changes: 55 additions & 5 deletions src/xrpld/app/misc/detail/ValidatorList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,55 @@ ValidatorList::buildValidatorListMessages(
return {0, 0};
}

std::tuple<std::string, std::uint32_t, std::map<std::size_t, ValidatorBlobInfo>, uint256>
ValidatorList::sendLatestValidatorLists(
Peer& peer,
std::uint64_t peerSequence,
PublicKey const& publisherKey,
HashRouter& hashRouter,
beast::Journal j) const
{
std::vector<ValidatorList::MessageWithHash> messages;
std::map<std::size_t, ValidatorBlobInfo> blobInfos;

if (publisherLists_.count(publisherKey) == 0)
return {};
ValidatorList::PublisherListCollection const& lists = publisherLists_.at(publisherKey);

auto const maxSequence = lists.current.sequence;
ASSERT(
lists.current.sequence == maxSequence || lists.remaining.count(maxSequence) == 1,
"ripple::ValidatorList::sendLatestValidatorLists : valid sequence");

if (peerSequence < maxSequence)
{
buildBlobInfos(blobInfos, lists);
sendValidatorList(
peer,
peerSequence,
publisherKey,
maxSequence,
lists.rawVersion,
lists.rawManifest,
blobInfos,
messages,
hashRouter,
j);

// Suppress the messages so they'll be ignored next time.
uint256 lasthash;
for (auto const& m : messages)
{
lasthash = m.hash;
hashRouter.addSuppressionPeer(lasthash, peer.id());
}
return std::make_tuple(lists.rawManifest, lists.rawVersion, blobInfos, lasthash);
}
return {};
}

// static
void
std::optional<std::string>
ValidatorList::sendValidatorList(
Peer& peer,
std::uint64_t peerSequence,
Expand All @@ -700,7 +747,7 @@ ValidatorList::sendValidatorList(
messageVersion = 1;
}
if (messageVersion == 0u)
return;
return {};
auto const [newPeerSequence, numVLs] = buildValidatorListMessages(
messageVersion, peerSequence, maxSequence, rawVersion, rawManifest, blobInfos, messages);
if (newPeerSequence != 0u)
Expand Down Expand Up @@ -736,6 +783,7 @@ ValidatorList::sendValidatorList(
<< " validator list(s) for " << strHex(publisherKey)
<< " with sequence range " << peerSequence << ", "
<< newPeerSequence << " to " << peer.fingerprint();
return "ValidatorListCollection";
}
else
{
Expand All @@ -746,13 +794,15 @@ ValidatorList::sendValidatorList(
JLOG(j.debug()) << "Sent validator list for " << strHex(publisherKey)
<< " with sequence " << newPeerSequence << " to "
<< peer.fingerprint();
return "ValidatorList";
}
}
}
return {};
}

// static
void
std::optional<std::string>
ValidatorList::sendValidatorList(
Peer& peer,
std::uint64_t peerSequence,
Expand All @@ -765,7 +815,7 @@ ValidatorList::sendValidatorList(
beast::Journal j)
{
std::vector<ValidatorList::MessageWithHash> messages;
sendValidatorList(
return sendValidatorList(
peer,
peerSequence,
publisherKey,
Expand Down Expand Up @@ -833,7 +883,7 @@ ValidatorList::broadcastBlobs(
std::map<std::size_t, ValidatorBlobInfo> blobInfos;

XRPL_ASSERT(
lists.current.sequence == maxSequence || lists.remaining.count(maxSequence) == 1,
lists.current.sequence <= maxSequence || lists.remaining.count(maxSequence) == 1,
"xrpl::ValidatorList::broadcastBlobs : valid sequence");
// Can't use overlay.foreach here because we need to modify
// the peer, and foreach provides a const&
Expand Down
70 changes: 68 additions & 2 deletions src/xrpld/overlay/detail/PeerImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,46 @@ PeerImp::domain() const

// Protocol logic

void
logVLBlob(beast::Journal j, ValidatorBlobInfo const& blob, std::size_t count)
{
auto const stream = j.trace();
JLOG(stream) << "Blob " << count << " Signature: " << blob.signature;
JLOG(stream) << "Blob " << count << " blob: " << base64_decode(blob.blob);
JLOG(stream) << "Blob " << count
<< " manifest: " << (blob.manifest ? base64_decode(*blob.manifest) : "NONE");
}

void
logVLBlob(
beast::Journal j,
std::pair<std::size_t, ValidatorBlobInfo> const& blob,
std::size_t count)
{
logVLBlob(j, blob.second, count);
}

template <class TBlobs>
void
logVL(
beast::Journal j,
std::string const& manifest,
std::uint32_t version,
TBlobs const& blobs,
uint256 const& hash)
{
auto const stream = j.trace();
JLOG(stream) << "Manifest: " << manifest;
JLOG(stream) << "Version: " << version;
JLOG(stream) << "Hash: " << hash;
std::size_t count = 1;
for (auto const& blob : blobs)
{
logVLBlob(j, blob, count);
++count;
}
}

void
PeerImp::doProtocolStart()
{
Expand Down Expand Up @@ -2157,6 +2197,8 @@ PeerImp::onValidatorListMessage(
return;
}

logVL(p_journal_, manifest, version, blobs, hash);

auto const applyResult = app_.getValidators().applyListsAndBroadcast(
manifest,
version,
Expand Down Expand Up @@ -2197,7 +2239,8 @@ PeerImp::onValidatorListMessage(
"xrpl::PeerImp::onValidatorListMessage : lower sequence");
}
#endif
publisherListSequences_[pubKey] = applyResult.sequence;
if (publisherListSequences_[pubKey] < applyResult.sequence)
publisherListSequences_[pubKey] = applyResult.sequence;
}
break;
case ListDisposition::same_sequence:
Expand All @@ -2215,8 +2258,31 @@ PeerImp::onValidatorListMessage(
}
#endif // !NDEBUG

[[fallthrough]];
case ListDisposition::stale: {
auto const [pubKey, currentPeerSeq] = [&]() {
std::lock_guard<std::mutex> sl(recentLock_);
ASSERT(
applyResult.sequence && applyResult.publisherKey,
"ripple::PeerImp::onValidatorListMessage : (stale) nonzero "
"sequence");
auto const& pubKey = *applyResult.publisherKey;
auto const& current = publisherListSequences_[pubKey];
ASSERT(
current <= applyResult.sequence,
"ripple::PeerImp::onValidatorListMessage : (stale) valid "
"sequence");
return std::make_pair(pubKey, current ? current : applyResult.sequence);
}();
if (currentPeerSeq <= applyResult.sequence)
{
auto const [sentmanifest, sentversion, sentblobs, senthash] =
app_.validators().sendLatestValidatorLists(
*this, currentPeerSeq, pubKey, app_.getHashRouter(), p_journal_);
logVL(p_journal_, sentmanifest, sentversion, sentblobs, senthash);
}
}
break;
case ListDisposition::stale:
case ListDisposition::untrusted:
case ListDisposition::invalid:
case ListDisposition::unsupported_version:
Expand Down