fix: skip inner batch txns during ledger replay

This commit is contained in:
Denis Angell
2026-04-21 06:17:51 +02:00
parent 5ff0ad9ebd
commit c27613e1df
2 changed files with 52 additions and 2 deletions

View File

@@ -23,7 +23,7 @@ namespace test {
struct LedgerReplay_test : public beast::unit_test::suite
{
void
run() override
testReplayLedger()
{
testcase("Replay ledger");
@@ -46,6 +46,50 @@ struct LedgerReplay_test : public beast::unit_test::suite
BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
}
void
testReplayBatchLedger()
{
testcase("Replay ledger with batch transactions");
using namespace jtx;
Env env(*this, testable_amendments());
auto const alice = Account("alice");
auto const bob = Account("bob");
env.fund(XRP(100000), alice, bob);
env.close();
auto const seq = env.seq(alice);
auto const batchFee = batch::calcBatchFee(env, 0, 2);
env(batch::outer(alice, seq, batchFee, tfAllOrNothing),
batch::inner(pay(alice, bob, XRP(1)), seq + 1),
batch::inner(pay(alice, bob, XRP(2)), seq + 2),
batch::sig(alice),
ter(tesSUCCESS));
env.close();
LedgerMaster& ledgerMaster = env.app().getLedgerMaster();
auto const lastClosed = ledgerMaster.getClosedLedger();
auto const lastClosedParent =
ledgerMaster.getLedgerByHash(lastClosed->header().parentHash);
auto const replayed = buildLedger(
LedgerReplay(lastClosedParent, lastClosed),
tapNONE,
env.app(),
env.journal);
BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
}
void
run() override
{
testReplayLedger();
testReplayBatchLedger();
}
};
enum class InboundLedgersBehavior {

View File

@@ -6,6 +6,7 @@
#include <xrpl/ledger/CanonicalTXSet.h>
#include <xrpl/ledger/Ledger.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/tx/apply.h>
namespace xrpl {
@@ -215,7 +216,12 @@ buildLedger(
j,
[&](OpenView& accum, std::shared_ptr<Ledger> const& built) {
for (auto& tx : replayData.orderedTxns())
applyTransaction(app, accum, *tx.second, false, applyFlags, j);
{
if (tx.second->isFlag(tfInnerBatchTxn))
continue;
applyTransaction(
app, accum, *tx.second, false, applyFlags, j);
}
});
}