Merge remote-tracking branch 'upstream/release/3.3.x' into mathbunnyru/merge-3.3.0-to-develop

* upstream/release/3.3.x: (41 commits)
  chore: Bump version to 3.3.0
  chore: Bump version to 3.3.0-rc7
  fix: Increase manifest protocol message size cap and fix manifests relay
  fix: Cap untrusted manifests per message and drop oversized ones
  chore: Bump version to 3.2.1
  chore: Bump version to 3.2.1-rc1
  fix: Cap untrusted manifests per message and drop oversized ones
  fix: Reject oversized validator manifest before decoding
  fix: Reduce untrusted manifest cache cap to 100
  fix: Bound untrusted manifest cache
  chore: Bump version to 3.3.0-rc6
  feat: Package validator-keys inside rippled
  chore: Bump version to 3.3.0-rc5
  fix: Switch SponsorshipSet to use a delta for sfFeeAmount
  fix: Re-revert "fix: Set request size limits and differential pricing for get-object-by-hash calls"
  chore: Bump version to 3.3.0-rc4
  fix: Revert "fix: Set request size limits and differential pricing for get-object-by-hash calls"
  chore: Bump version to 3.3.0-rc3
  fix: Reduce untrusted manifest cache cap to 100
  fix: Revert "fix: Reject oversized SHAMap nodes in gotStaleData and fetch-pack path"
  ...
This commit is contained in:
Ayaz Salikhov
2026-08-07 16:00:25 +01:00
109 changed files with 4419 additions and 1540 deletions

View File

@@ -58,6 +58,8 @@
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <format>
#include <functional>
#include <map>
#include <memory>
@@ -333,7 +335,7 @@ public:
setPublisherListSequence(PublicKey const&, std::size_t const) override
{
}
[[nodiscard]] uint256 const&
[[nodiscard]] uint256
getClosedLedgerHash() const override
{
static uint256 const kHash{};
@@ -958,7 +960,8 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
auto reply = std::make_shared<protocol::TMProofPathResponse>(
server.msgHandler.processProofPathRequest(request));
BEAST_EXPECT(reply->has_error());
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(reply) == ReplayMsgStatus::BadData);
}
{
// request, wrong hash
@@ -982,7 +985,7 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
auto reply = std::make_shared<protocol::TMProofPathResponse>(
server.msgHandler.processProofPathRequest(request));
BEAST_EXPECT(!reply->has_error());
BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply) == ReplayMsgStatus::Ok);
{
// bad reply: invalid hash/key sizes
@@ -990,37 +993,49 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
// reply with undersized ledgerhash (31 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_ledgerhash(std::string(31, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with oversized ledgerhash (33 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_ledgerhash(std::string(33, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with empty ledgerhash
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_ledgerhash(std::string());
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with undersized key (31 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_key(std::string(31, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with oversized key (33 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_key(std::string(33, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with empty key
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_key(std::string());
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(bad) ==
ReplayMsgStatus::Malformed);
}
}
@@ -1030,13 +1045,18 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
std::string r(reply->ledgerheader());
r.back()--;
reply->set_ledgerheader(r);
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(reply) ==
ReplayMsgStatus::Malformed);
r.back()++;
reply->set_ledgerheader(r);
BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(reply) == ReplayMsgStatus::Ok);
// bad proof path
reply->mutable_path()->RemoveLast();
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
BEAST_EXPECT(
server.msgHandler.processProofPathResponse(reply) ==
ReplayMsgStatus::Malformed);
}
}
}
@@ -1054,14 +1074,16 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
server.msgHandler.processReplayDeltaRequest(request));
BEAST_EXPECT(reply->has_error());
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(reply) == ReplayMsgStatus::BadData);
// request, wrong hash
uint256 hash(1234567);
request->set_ledgerhash(hash.data(), hash.size());
reply = std::make_shared<protocol::TMReplayDeltaResponse>(
server.msgHandler.processReplayDeltaRequest(request));
BEAST_EXPECT(reply->has_error());
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(reply) == ReplayMsgStatus::BadData);
}
{
@@ -1071,7 +1093,8 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
server.msgHandler.processReplayDeltaRequest(request));
BEAST_EXPECT(!reply->has_error());
BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(reply) == ReplayMsgStatus::Ok);
{
// bad reply: invalid hash sizes
@@ -1079,19 +1102,25 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
// reply with undersized ledgerhash (31 bytes)
auto bad = std::make_shared<protocol::TMReplayDeltaResponse>(*reply);
bad->set_ledgerhash(std::string(31, '\x01'));
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(bad));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with oversized ledgerhash (33 bytes)
auto bad = std::make_shared<protocol::TMReplayDeltaResponse>(*reply);
bad->set_ledgerhash(std::string(33, '\x01'));
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(bad));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(bad) ==
ReplayMsgStatus::Malformed);
}
{
// reply with empty ledgerhash
auto bad = std::make_shared<protocol::TMReplayDeltaResponse>(*reply);
bad->set_ledgerhash(std::string());
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(bad));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(bad) ==
ReplayMsgStatus::Malformed);
}
}
@@ -1101,17 +1130,77 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
std::string r(reply->ledgerheader());
r.back()--;
reply->set_ledgerheader(r);
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(reply) ==
ReplayMsgStatus::Malformed);
r.back()++;
reply->set_ledgerheader(r);
BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(reply) == ReplayMsgStatus::Ok);
// bad txns
reply->mutable_transaction()->RemoveLast();
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
BEAST_EXPECT(
server.msgHandler.processReplayDeltaResponse(reply) ==
ReplayMsgStatus::Malformed);
}
}
}
void
testTruncatedHeader()
{
testcase("TruncatedLedgerHeader");
LedgerServer server(*this, {.initLedgers = 1});
auto const l = server.ledgerMaster.getClosedLedger();
auto runNoThrow = [this](auto fn, char const* what) {
try
{
BEAST_EXPECT(fn() == ReplayMsgStatus::Malformed);
}
catch (std::exception const& e)
{
fail(
std::format("processor threw on truncated header ({}): {}", what, e.what()),
__FILE__,
__LINE__);
}
catch (...)
{
fail(
std::format("processor threw unknown exception ({}) on truncated header", what),
__FILE__,
__LINE__);
}
};
{
auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
server.msgHandler.processReplayDeltaRequest(request));
BEAST_EXPECT(!reply->has_error());
reply->set_ledgerheader(std::string(1, '\x00'));
runNoThrow(
[&] { return server.msgHandler.processReplayDeltaResponse(reply); }, "ReplayDelta");
}
{
auto request = std::make_shared<protocol::TMProofPathRequest>();
request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
request->set_key(keylet::skip().key.data(), keylet::skip().key.size());
auto reply = std::make_shared<protocol::TMProofPathResponse>(
server.msgHandler.processProofPathRequest(request));
BEAST_EXPECT(!reply->has_error());
reply->set_ledgerheader(std::string(1, '\x00'));
runNoThrow(
[&] { return server.msgHandler.processProofPathResponse(reply); }, "ProofPath");
}
}
void
testTaskParameter()
{
@@ -1514,6 +1603,7 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
{
testProofPath();
testReplayDelta();
testTruncatedHeader();
testTaskParameter();
testConfig();
testHandshake();