Compare commits

..

3 Commits

Author SHA1 Message Date
Bart
9922f214e9 Remove unreachable code 2026-06-08 15:20:06 -04:00
Bart
32bb0a6f72 Remove supported protocol features 2026-06-08 15:01:14 -04:00
Bart
d59efa6528 refactor: Remove support for protocol version 2.1 2026-06-08 14:52:06 -04:00
7 changed files with 15 additions and 142 deletions

View File

@@ -11,8 +11,6 @@
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/UintTypes.h>
#include <boost/endian/conversion.hpp>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -47,9 +45,6 @@ STIssue::STIssue(SerialIter& sit, SField const& name) : STBase{name}
{
MPTID mptID;
std::uint32_t sequence = sit.get32();
// Preserve the existing LE memcpy result on every host endian.
// Wire 04 03 02 01 becomes MPTID bytes 01 02 03 04 on both.
sequence = boost::endian::native_to_little(sequence);
static_assert(MPTID::size() == sizeof(sequence) + sizeof(currencyOrAccount));
memcpy(mptID.data(), &sequence, sizeof(sequence));
memcpy(
@@ -105,9 +100,6 @@ STIssue::add(Serializer& s) const
s.addBitString(noAccount());
std::uint32_t sequence = 0;
memcpy(&sequence, issue.getMptID().data(), sizeof(sequence));
// Preserve the existing LE ledger bytes on every host endian.
// MPTID bytes 01 02 03 04 become wire bytes 04 03 02 01 on both.
sequence = boost::endian::native_to_little(sequence);
s.add32(sequence);
});
}

View File

@@ -36,7 +36,6 @@ public:
testcase("Convert protocol version to string");
BEAST_EXPECT(to_string(makeProtocol(1, 3)) == "XRPL/1.3");
BEAST_EXPECT(to_string(makeProtocol(2, 0)) == "XRPL/2.0");
BEAST_EXPECT(to_string(makeProtocol(2, 1)) == "XRPL/2.1");
BEAST_EXPECT(to_string(makeProtocol(10, 10)) == "XRPL/10.10");
{
@@ -59,11 +58,10 @@ public:
testcase("Protocol version negotiation");
BEAST_EXPECT(negotiateProtocolVersion("RTXP/1.2") == std::nullopt);
BEAST_EXPECT(
negotiateProtocolVersion("RTXP/1.2, XRPL/2.0, XRPL/2.1") == makeProtocol(2, 1));
BEAST_EXPECT(negotiateProtocolVersion("RTXP/1.2, XRPL/2.0, XRPL/2.1") == std::nullopt);
BEAST_EXPECT(negotiateProtocolVersion("XRPL/2.2") == makeProtocol(2, 2));
BEAST_EXPECT(
negotiateProtocolVersion("RTXP/1.2, XRPL/2.2, XRPL/2.3, XRPL/999.999") ==
negotiateProtocolVersion("RTXP/1.2, XRPL/2.1, XRPL/2.2, XRPL/2.3, XRPL/999.999") ==
makeProtocol(2, 2));
BEAST_EXPECT(negotiateProtocolVersion("XRPL/999.999, WebSocket/1.0") == std::nullopt);
BEAST_EXPECT(negotiateProtocolVersion("") == std::nullopt);

View File

@@ -3,19 +3,14 @@
#include <test/jtx/amount.h> // IWYU pragma: keep
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STIssue.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/UintTypes.h>
#include <cstdint>
namespace xrpl::test {
class STIssue_test : public beast::unit_test::Suite
@@ -142,69 +137,12 @@ public:
"000000000000000000000000000000000000000000000002");
}
void
testMPTSerialization()
{
testcase("MPT serialization");
using namespace jtx;
Account const alice{"alice"};
struct Vector
{
std::uint32_t sequence;
std::uint32_t legacySequence;
};
// 0x01020304 pins canonical MPTID bytes 01 02 03 04 and
// preserved STIssue wire bytes 04 03 02 01 on BE and LE.
Vector const vectors[] = {
{.sequence = 0x00000001, .legacySequence = 0x01000000},
{.sequence = 0x01020304, .legacySequence = 0x04030201},
{.sequence = 0xa1b2c3d4, .legacySequence = 0xd4c3b2a1},
};
for (auto const& vector : vectors)
{
MPTID const mptID = makeMptID(vector.sequence, alice);
MPTIssue const issue{mptID};
STIssue const stIssue(sfAsset, Asset{issue});
Serializer actual;
stIssue.add(actual);
// STIssue preserves the existing little-endian validator ledger bytes.
Serializer expected;
expected.addBitString(alice.id());
expected.addBitString(noAccount());
{
std::array<unsigned char, 4> bytes;
auto const seq = boost::endian::native_to_little(vector.sequence);
memcpy(bytes.data(), &seq, 4);
expected.addRaw(bytes.data(), bytes.size());
}
BEAST_EXPECTS(strHex(actual) == strHex(expected), strHex(actual));
// Decoding the preserved wire format must recover the canonical MPTID.
SerialIter iter(expected.slice());
STIssue const decoded(iter, sfAsset);
BEAST_EXPECT(decoded.holds<MPTIssue>());
BEAST_EXPECT(decoded.value().get<MPTIssue>().getMptID() == mptID);
// A decoded ledger value must serialize back to the same bytes.
Serializer roundTrip;
decoded.add(roundTrip);
BEAST_EXPECTS(strHex(roundTrip) == strHex(expected), strHex(roundTrip));
}
}
void
run() override
{
// compliments other unit tests to ensure complete coverage
testConstructor();
testCompare();
testMPTSerialization();
}
};

View File

@@ -727,17 +727,8 @@ ValidatorList::sendValidatorList(
HashRouter& hashRouter,
beast::Journal j)
{
std::size_t messageVersion = 0;
if (peer.supportsFeature(ProtocolFeature::ValidatorList2Propagation))
{
messageVersion = 2;
}
else if (peer.supportsFeature(ProtocolFeature::ValidatorListPropagation))
{
messageVersion = 1;
}
if (messageVersion == 0u)
return;
// v1 messages are no longer supported.
std::size_t const messageVersion = 2;
auto const [newPeerSequence, numVLs] = buildValidatorListMessages(
messageVersion, peerSequence, maxSequence, rawVersion, rawManifest, blobInfos, messages);
if (newPeerSequence != 0u)
@@ -766,24 +757,11 @@ ValidatorList::sendValidatorList(
"xrpl::ValidatorList::sendValidatorList : sent or one message");
if (sent)
{
if (messageVersion > 1)
{
JLOG(j.debug()) << "Sent " << messages.size()
<< " validator list collection(s) containing " << numVLs
<< " validator list(s) for " << strHex(publisherKey)
<< " with sequence range " << peerSequence << ", "
<< newPeerSequence << " to " << peer.fingerprint();
}
else
{
XRPL_ASSERT(
numVLs == 1,
"xrpl::ValidatorList::sendValidatorList : one validator "
"list");
JLOG(j.debug()) << "Sent validator list for " << strHex(publisherKey)
<< " with sequence " << newPeerSequence << " to "
<< peer.fingerprint();
}
JLOG(j.debug()) << "Sent " << messages.size()
<< " validator list collection(s) containing " << numVLs
<< " validator list(s) for " << strHex(publisherKey)
<< " with sequence range " << peerSequence << ", " << newPeerSequence
<< " to " << peer.fingerprint();
}
}
}
@@ -858,16 +836,9 @@ ValidatorList::broadcastBlobs(
if (toSkip)
{
// We don't know what messages or message versions we're sending
// until we examine our peer's properties. Build the message(s) on
// demand, but reuse them when possible.
// This will hold a v1 message with only the current VL if we have
// any peers that don't support v2
std::vector<ValidatorList::MessageWithHash> messages1;
// This will hold v2 messages indexed by the peer's
// `publisherListSequence`. For each `publisherListSequence`, we'll
// only send the VLs with higher sequences.
// Build v2 messages on demand and reuse them when possible. Messages
// are indexed by the peer's `publisherListSequence`; for each sequence,
// we only send VLs with higher sequences.
std::map<std::size_t, std::vector<ValidatorList::MessageWithHash>> messages2;
// If any peers are found that are worth considering, this list will
// be built to hold info for all of the valid VLs.
@@ -887,8 +858,6 @@ ValidatorList::broadcastBlobs(
{
if (blobInfos.empty())
buildBlobInfos(blobInfos, lists);
auto const v2 =
peer->supportsFeature(ProtocolFeature::ValidatorList2Propagation);
sendValidatorList(
*peer,
peerSequence,
@@ -897,11 +866,10 @@ ValidatorList::broadcastBlobs(
lists.rawVersion,
lists.rawManifest,
blobInfos,
v2 ? messages2[peerSequence] : messages1,
messages2[peerSequence],
hashRouter,
j);
// Even if the peer doesn't support the messages,
// suppress it so it'll be ignored next time.
// Don't send it next time.
hashRouter.addSuppressionPeer(hash, peer->id());
}
}

View File

@@ -14,8 +14,6 @@ class Charge;
} // namespace Resource
enum class ProtocolFeature {
ValidatorListPropagation,
ValidatorList2Propagation,
LedgerReplay,
};

View File

@@ -545,10 +545,6 @@ PeerImp::supportsFeature(ProtocolFeature f) const
{
switch (f)
{
case ProtocolFeature::ValidatorListPropagation:
return protocol_ >= makeProtocol(2, 1);
case ProtocolFeature::ValidatorList2Propagation:
return protocol_ >= makeProtocol(2, 2);
case ProtocolFeature::LedgerReplay:
return ledgerReplayEnabled_;
}
@@ -892,7 +888,7 @@ PeerImp::doProtocolStart()
onReadMessage(error_code(), 0);
// Send all the validator lists that have been loaded
if (inbound_ && supportsFeature(ProtocolFeature::ValidatorListPropagation))
if (inbound_)
{
app_.getValidators().forEachAvailable(
[&](std::string const& manifest,
@@ -2275,14 +2271,6 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidatorList> const& m)
{
try
{
if (!supportsFeature(ProtocolFeature::ValidatorListPropagation))
{
JLOG(pJournal_.debug()) << "ValidatorList: received validator list from peer using "
<< "protocol version " << to_string(protocol_)
<< " which shouldn't support this feature.";
fee_.update(Resource::kFeeUselessData, "unsupported peer");
return;
}
onValidatorListMessage(
"ValidatorList", m->manifest(), m->version(), ValidatorList::parseBlobs(*m));
}
@@ -2299,14 +2287,6 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidatorListCollection> const& m
{
try
{
if (!supportsFeature(ProtocolFeature::ValidatorList2Propagation))
{
JLOG(pJournal_.debug()) << "ValidatorListCollection: received validator list from peer "
<< "using protocol version " << to_string(protocol_)
<< " which shouldn't support this feature.";
fee_.update(Resource::kFeeUselessData, "unsupported peer");
return;
}
if (m->version() < 2)
{
JLOG(pJournal_.debug())

View File

@@ -26,7 +26,6 @@ namespace xrpl {
*/
constexpr ProtocolVersion const kSupportedProtocolList[]{
{2, 1},
{2, 2},
};