Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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/overlay/FlowControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,16 @@ FlowControl::addMsgAndMaybeTrimQueue(std::shared_ptr<StellarMessage const> msg)

size_t dropped = 0;

uint32_t const limit =
mAppConnector.getLedgerManager().getLastMaxTxSetSizeOps();
auto& lm = mAppConnector.getLedgerManager();
uint32_t limit = lm.getLastMaxTxSetSizeOps();

if (protocolVersionStartsFrom(
lm.getLastClosedLedgerHeader().header.ledgerVersion,
SOROBAN_PROTOCOL_VERSION))
{
limit = saturatingAdd(
limit, lm.getLastClosedSorobanNetworkConfig().ledgerMaxTxCount());
}
auto& om = mOverlayMetrics;
if (type == TRANSACTION)
{
Expand Down
25 changes: 21 additions & 4 deletions src/overlay/TxAdverts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ TxAdverts::startAdvertTimer()
});
}

size_t
TxAdverts::getTxLimit()
{
auto& lm = mApp.getLedgerManager();
size_t classic = lm.getLastMaxTxSetSizeOps();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you mention in your PR description, this assumes that all classic transactions are a single op, but that's probably not true. This has admittedly been working fine, but I wonder if there's a better way (such as dividing this value by the average number of ops per transaction). At the very least it might be worth checking what the average number of ops per classic transaction is these days to better answer the question of whether this needs adjusting.

Copy link
Contributor Author

@drebelsky drebelsky Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick Hubble query results

SELECT AVG(operation_count)
FROM crypto-stellar.crypto_stellar.history_transactions
WHERE batch_run_date >= DATE(2025, 05, 01) AND resource_fee = 0
f0_
2.7467817158433689
SELECT AVG(operation_count)
FROM crypto-stellar.crypto_stellar.history_transactions
WHERE batch_run_date >= DATE(2025, 08, 01) AND resource_fee = 0
f0_
3.3659880974068379

if (protocolVersionStartsFrom(
lm.getLastClosedLedgerHeader().header.ledgerVersion,
SOROBAN_PROTOCOL_VERSION))
{

return classic +
lm.getLastClosedSorobanNetworkConfig().ledgerMaxTxCount();
}
return classic;
}

void
TxAdverts::queueOutgoingAdvert(Hash const& txHash)
{
Expand Down Expand Up @@ -108,7 +124,8 @@ void
TxAdverts::retryIncomingAdvert(std::list<Hash>& list)
{
mTxHashesToRetry.splice(mTxHashesToRetry.end(), list);
while (size() > mApp.getLedgerManager().getLastMaxTxSetSizeOps())
size_t const limit = getTxLimit();
while (size() > limit)
{
popIncomingAdvert();
}
Expand All @@ -123,11 +140,11 @@ TxAdverts::queueIncomingAdvert(TxAdvertVector const& txHashes, uint32_t seq)
}

auto it = txHashes.begin();
size_t const limit = mApp.getLedgerManager().getLastMaxTxSetSizeOps();
size_t const limit = getTxLimit();
if (txHashes.size() > limit)
{
// If txHashes has more than getLastMaxTxSetSizeOps txns, then
// the first (txHashes.size() - getLastMaxTxSetSizeOps) txns will be
// If txHashes has more than limit txns, then
// the first (txHashes.size() - limit) txns will be
// popped in the while loop below. Therefore, we won't even bother
// pushing them.
it += txHashes.size() - limit;
Expand Down
6 changes: 6 additions & 0 deletions src/overlay/TxAdverts.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class TxAdverts
void rememberHash(Hash const& hash, uint32_t ledgerSeq);
void flushAdvert();
void startAdvertTimer();
#ifdef BUILD_TESTS
public:
#endif
// Get the maximum size for transaction hashes to process, considering both
// Soroban and classic limits
size_t getTxLimit();

public:
TxAdverts(Application& app);
Expand Down
10 changes: 8 additions & 2 deletions src/overlay/test/OverlayTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,10 @@ TEST_CASE("outbound queue filtering", "[overlay][flowcontrol]")
}
SECTION("txs, limit reached")
{
uint32_t limit = node->getLedgerManager().getLastMaxTxSetSizeOps();
auto& lm = node->getLedgerManager();
uint32_t limit =
lm.getLastMaxTxSetSizeOps() +
lm.getLastClosedSorobanNetworkConfig().ledgerMaxTxCount();
StellarMessage msg;
msg.type(TRANSACTION);
auto byteSize =
Expand Down Expand Up @@ -1047,7 +1050,10 @@ TEST_CASE("outbound queue filtering", "[overlay][flowcontrol]")
{
// Adverts/demands aren't affected by the byte limit
peer->getFlowControl()->setOutboundQueueLimit(1);
uint32_t limit = node->getLedgerManager().getLastMaxTxSetSizeOps();
auto& lm = node->getLedgerManager();
uint32_t limit =
lm.getLastMaxTxSetSizeOps() +
lm.getLastClosedSorobanNetworkConfig().ledgerMaxTxCount();
for (uint32_t i = 0; i < limit + 10; ++i)
{
StellarMessage adv, dem, txn;
Expand Down
2 changes: 1 addition & 1 deletion src/overlay/test/TxAdvertsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ TEST_CASE("advert queue", "[flood][pullmode][acceptance]")
flushed = true;
});

auto limit = app->getLedgerManager().getLastMaxTxSetSizeOps();
auto limit = pullMode.getTxLimit();
auto getHash = [](auto i) { return sha256(std::to_string(i)); };

SECTION("incoming adverts")
Expand Down