From 9e65e6cfe8912013e9ebc238032aa09dc8de0cc4 Mon Sep 17 00:00:00 2001 From: JCW Date: Fri, 5 Jun 2026 10:14:07 +0100 Subject: [PATCH] Test --- src/xrpld/app/ledger/ConsensusTransSetSF.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/xrpld/app/ledger/ConsensusTransSetSF.cpp b/src/xrpld/app/ledger/ConsensusTransSetSF.cpp index 7c74c10b1b..a99deaeffd 100644 --- a/src/xrpld/app/ledger/ConsensusTransSetSF.cpp +++ b/src/xrpld/app/ledger/ConsensusTransSetSF.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace xrpl { @@ -39,8 +40,6 @@ ConsensusTransSetSF::gotNode( if (fromFilter) return; - nodeCache_.insert(nodeHash, nodeData); - if ((type == SHAMapNodeType::TnTransactionNm) && (nodeData.size() > 16)) { // this is a transaction, and we didn't have it @@ -56,9 +55,20 @@ ConsensusTransSetSF::gotNode( stx->getTransactionID() == nodeHash.asUInt256(), "xrpl::ConsensusTransSetSF::gotNode : transaction hash " "match"); + + // Rather than caching the (potentially large) transaction blob in + // nodeCache_, store the transaction in the TransactionMaster so + // getNode() can rebuild the leaf on demand. This is done + // synchronously to close the window before the asynchronous + // submission below populates the cache. + std::string reason; + auto tx = std::make_shared(stx, reason, app_); + app_.getMasterTransaction().canonicalize(&tx); + auto const pap = &app_; app_.getJobQueue().addJob( JtTransaction, "TxsToTxn", [pap, stx]() { pap->getOPs().submitTransaction(stx); }); + return; } catch (std::exception const& ex) { @@ -66,6 +76,11 @@ ConsensusTransSetSF::gotNode( << ex.what(); } } + + // Inner nodes have no alternative recovery source, so they must be cached + // for getNode() to satisfy later lookups. Any leaf we could not store in + // the TransactionMaster above also falls through to here. + nodeCache_.insert(nodeHash, nodeData); } std::optional