Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
9d8b7d7
the naive solution seems to work
mvadari Jul 31, 2025
fb4b933
clean up
mvadari Jul 31, 2025
7e16bc5
improve test
mvadari Jul 31, 2025
e377a0d
update changelog
mvadari Jul 31, 2025
f84950a
fix tests
mvadari Jul 31, 2025
b92ca51
add tx_hash and ctid support
mvadari Jul 31, 2025
85e89ed
Merge branch 'develop' into simulate-past
mvadari Jul 31, 2025
7110bf1
fix build issue
mvadari Jul 31, 2025
20cb0ce
add more tests, refactor
mvadari Aug 1, 2025
10a6a44
fix tests
mvadari Aug 1, 2025
c5a31da
first attempt at multi transaction processing (not tested, but doesn'…
mvadari Aug 1, 2025
3877263
test outline (src does not work yet)
mvadari Aug 1, 2025
5fc32a2
get something working
mvadari Aug 2, 2025
cc7585e
get Batch mostly working
mvadari Aug 2, 2025
6506a60
clean up tests
mvadari Aug 2, 2025
3daee17
fix more tests
mvadari Aug 4, 2025
60fe9f4
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Aug 4, 2025
0d3e30e
add more tests
mvadari Aug 5, 2025
07de564
Merge branch 'develop' into simulate-past
mvadari Aug 5, 2025
2c94917
fix gcc build issue
mvadari Aug 5, 2025
c3a3ae7
Merge branch 'develop' into simulate-past
mvadari Aug 6, 2025
f161ab7
Merge branch 'develop' into simulate-past
mvadari Aug 7, 2025
550d7e4
Merge branch 'develop' into simulate-past
mvadari Aug 8, 2025
49e5da8
Merge branch 'develop' into simulate-past
Bronek Aug 11, 2025
d5f363e
Merge branch 'develop' into simulate-past
bthomee Aug 11, 2025
aff497e
Merge branch 'develop' into simulate-past
mvadari Aug 11, 2025
6c05d8e
do some cleanup
mvadari Aug 13, 2025
1842df1
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Aug 13, 2025
2088fcf
more cleanup
mvadari Aug 13, 2025
7a6c583
Merge branch 'develop' into simulate-past
mvadari Aug 15, 2025
4de189e
Merge branch 'develop' into simulate-past
mvadari Aug 18, 2025
2b91667
Merge branch 'develop' into simulate-past
mvadari Aug 19, 2025
47b2aa7
Merge branch 'develop' into simulate-past
mvadari Aug 21, 2025
52f6a3a
Merge branch 'develop' into simulate-past
mvadari Aug 22, 2025
3b12a74
Merge branch 'develop' into simulate-past
mvadari Aug 22, 2025
ae70a1f
Merge branch 'develop' into simulate-past
mvadari Aug 25, 2025
d557be1
[KNOWN BROKEN] merge
mvadari Sep 24, 2025
426fa70
builds but fails tests
mvadari Sep 25, 2025
3e88d14
Merge branch 'develop' into simulate-past
mvadari Sep 25, 2025
493ff9f
Merge branch 'develop' into simulate-past
mvadari Oct 6, 2025
73e29f8
Merge branch 'develop' into simulate-past
mvadari Oct 13, 2025
4f6c2aa
fix synthetic fields
mvadari Oct 13, 2025
0cbe4e6
remove unused variable
mvadari Oct 13, 2025
be70f58
fix ledger_entry tests
mvadari Oct 13, 2025
0d11a84
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Oct 16, 2025
fee96cc
Merge branch 'develop' into simulate-past
mvadari Oct 17, 2025
d9bb2be
Merge branch 'develop' into simulate-past
mvadari Oct 21, 2025
2ee928c
Merge branch 'develop' into simulate-past
mvadari Nov 5, 2025
dab5078
Merge branch 'develop' into simulate-past
mvadari Nov 17, 2025
538f3ef
Merge branch 'develop' into simulate-past
mvadari Dec 10, 2025
00bd84d
fix build + test issues
mvadari Dec 10, 2025
3e863fd
Merge branch 'develop' into simulate-past
mvadari Dec 24, 2025
b05d921
fix merge issue
mvadari Dec 24, 2025
e2a0e92
Merge branch 'develop' into simulate-past
mvadari Jan 21, 2026
ced1253
Merge commit '92046785d1fea5f9efe5a770d636792ea6cab78b' into simulate…
mvadari Jan 28, 2026
410661b
Merge commit '5f638f55536def0d88b970d1018a465a238e55f4' into simulate…
mvadari Jan 28, 2026
39c88ad
Merge branch 'develop' into simulate-past
mvadari Jan 28, 2026
e055aff
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Feb 4, 2026
8c289f0
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Feb 6, 2026
afa69bd
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Feb 10, 2026
883792e
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Feb 12, 2026
b011cdf
Merge remote-tracking branch 'upstream/develop' into simulate-past
mvadari Feb 13, 2026
3f75ab0
fix build issue
mvadari Feb 13, 2026
ae947f3
Merge commit '25cca465538a56cce501477f9e5e2c1c7ea2d84c' into simulate…
mvadari Feb 24, 2026
5c6ebe7
Merge commit '2c1fad1023' into simulate-past
mvadari Feb 24, 2026
44a947e
fix formatting
mvadari Feb 24, 2026
742c282
Merge branch 'develop' into simulate-past
mvadari Feb 24, 2026
406e18f
fix
mvadari Feb 24, 2026
b1f7dbb
Merge branch 'develop' into simulate-past
mvadari Feb 26, 2026
876bed8
fix build issue
mvadari Feb 26, 2026
8f4a532
oops
mvadari Feb 26, 2026
55b8469
fix import
mvadari Feb 26, 2026
e0316e6
fix build
mvadari Feb 26, 2026
c65c49a
Merge branch 'develop' into simulate-past
mvadari Feb 27, 2026
e689976
Merge branch 'develop' into simulate-past
mvadari Feb 27, 2026
2836a7d
Merge branch 'develop' into simulate-past
mvadari Mar 2, 2026
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
6 changes: 6 additions & 0 deletions API-CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ This release contains bug fixes only and no API changes.

This release contains bug fixes only and no API changes.

## Unreleased

### Additions and bugfixes

- `simulate`: There is now additional support for simulating transactions in past ledgers, by providing the `ledger_index` or `ledger_hash`.
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The API changelog entry mentions simulating transactions in past ledgers but doesn't mention the other major features added in this PR: support for tx_hash/ctid parameters, support for multiple transactions via the transactions array parameter, and batch transaction support. These are all significant API changes that should be documented in the changelog.

Suggested change
- `simulate`: There is now additional support for simulating transactions in past ledgers, by providing the `ledger_index` or `ledger_hash`.
- `simulate`: Expanded functionality:
- You can now simulate transactions in past ledgers by providing `ledger_index` or `ledger_hash`.
- You can specify an existing transaction to simulate using `tx_hash` or `ctid` parameters.
- You can simulate multiple transactions in a single request using the `transactions` array parameter (batch transaction support).

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The API changelog entry only mentions simulating transactions in past ledgers but doesn't mention other significant additions like fetching transactions from history via tx_hash and ctid, batch transaction support, or the new transactions array parameter. Consider expanding this entry to comprehensively document all new features for API consumers.

Suggested change
- `simulate`: There is now additional support for simulating transactions in past ledgers, by providing the `ledger_index` or `ledger_hash`.
- `simulate`: Added support for simulating transactions against historical ledgers by providing the `ledger_index` or `ledger_hash`.
- `simulate`: You can now request simulation of an existing historical transaction by specifying its `tx_hash` or `ctid`, without needing to resubmit the full transaction.
- `simulate`: Added batch transaction support via a new top-level `transactions` array parameter, allowing multiple transactions to be simulated in a single request.

Copilot uses AI. Check for mistakes.

## XRP Ledger server version 2.5.0

[Version 2.5.0](https://github.com/XRPLF/rippled/releases/tag/2.5.0) was released on Jun 24, 2025.
Expand Down
2 changes: 1 addition & 1 deletion include/xrpl/protocol/jss.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ JSS(trusted_validator_keys); // out: ValidatorList
JSS(tx); // out: STTx, AccountTx*
JSS(tx_blob); // in/out: Submit,
// in: TransactionSign, AccountTx*
JSS(tx_hash); // in: TransactionEntry
JSS(tx_hash); // in: TransactionEntry, simulate
JSS(tx_json); // in/out: TransactionSign
// out: TransactionEntry
JSS(tx_signing_hash); // out: TransactionSign
Expand Down
9 changes: 9 additions & 0 deletions include/xrpl/tx/apply.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/tx/applySteps.h>
Expand Down Expand Up @@ -115,6 +116,14 @@ enum class ApplyTransactionResult {
Retry
};

std::optional<std::vector<ApplyResult>>
applyBatchTransactions(
ServiceRegistry& registry,
OpenView& batchView,
STTx const& batchTxn,
ApplyFlags flags,
beast::Journal j);
Comment on lines +119 to +125
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The function signature in the header declares Application& app as the first parameter, but the implementation in src/libxrpl/tx/apply.cpp (line 140) uses ServiceRegistry& registry. These must match. Since Application inherits from ServiceRegistry and the implementation uses ServiceRegistry, the header should be updated to use ServiceRegistry& registry for consistency with the implementation.

Copilot uses AI. Check for mistakes.

/** Transaction application helper

Provides more detailed logging and decodes the
Expand Down
7 changes: 2 additions & 5 deletions src/libxrpl/ledger/ApplyStateTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,8 @@ ApplyStateTable::apply(
metadata = meta;
}

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The removal of the isDryRun check before calling to.rawTxInsert() and apply(to) means that simulated transactions will now be inserted into the view's transaction list even during dry runs. This appears intentional to support the simulate RPC's need to track transactions in the view for metadata generation. However, this should be verified as safe - the view should be a temporary copy that is discarded after simulation. Consider adding a comment explaining why this is safe for dry runs in the simulate context.

Suggested change
// Note: We intentionally insert the transaction and apply the pending
// state changes to the provided OpenView even when isDryRun is true.
// In simulate RPC/dry-run contexts, `to` is a temporary view that is
// discarded after the call, so these modifications do not affect any
// persisted ledger state. This allows simulation to generate accurate
// metadata while keeping the base ledger unchanged.

Copilot uses AI. Check for mistakes.
if (!isDryRun)
{
to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
apply(to);
}
to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
apply(to);
Comment on lines +249 to +250
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The removal of the isDryRun check means that transactions will now be inserted into the view even during dry runs. This change appears intentional to support simulating batch transactions, but it fundamentally changes the behavior of dry runs. The rawTxInsert and apply calls will now execute for dry runs, which could have unintended consequences. Ensure this is the desired behavior and that it doesn't break existing functionality that depends on dry runs not modifying the view.

Suggested change
to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
apply(to);
if (!isDryRun)
{
to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
apply(to);
}

Copilot uses AI. Check for mistakes.
Comment on lines +249 to +250
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

Removing the isDryRun check means transactions are now inserted into the view even during dry runs. While this should be safe because simulate uses temporary OpenView copies, this changes the behavior where previously dry runs would not insert transactions into views at all. Consider verifying this behavior change is intentional and document it if necessary, as it may have implications for how views track transaction insertions during simulation.

Suggested change
to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
apply(to);
if (!isDryRun)
{
to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
apply(to);
}

Copilot uses AI. Check for mistakes.
return metadata;
}

Expand Down
54 changes: 38 additions & 16 deletions src/libxrpl/tx/apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,12 @@
});
}

static bool
std::optional<std::vector<ApplyResult>>
applyBatchTransactions(
ServiceRegistry& registry,
OpenView& batchView,
STTx const& batchTxn,
ApplyFlags flags,
beast::Journal j)
{
XRPL_ASSERT(
Expand All @@ -149,41 +150,57 @@
auto const parentBatchId = batchTxn.getTransactionID();
auto const mode = batchTxn.getFlags();

auto applyOneTransaction = [&registry, &j, &parentBatchId, &batchView](STTx&& tx) {
auto applyOneTransaction = [&registry, &j, &parentBatchId, &batchView, &flags](STTx&& tx) {
OpenView perTxBatchView(batch_view, batchView);

auto const ret = apply(registry, perTxBatchView, parentBatchId, tx, tapBATCH, j);
XRPL_ASSERT(
ret.applied == (isTesSuccess(ret.ter) || isTecClaim(ret.ter)),
"Inner transaction should not be applied");
auto const ret =
apply(registry, perTxBatchView, parentBatchId, tx, (flags & tapDRY_RUN) | tapBATCH, j);
if (flags & tapDRY_RUN)
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The condition check uses bitwise OR instead of checking if the tapDRY_RUN flag is set. This should use bitwise AND to check if the flag is present in the flags parameter. The current logic will always evaluate to true when tapDRY_RUN is set since it performs a bitwise OR operation rather than testing for the flag's presence.

Copilot uses AI. Check for mistakes.
{
XRPL_ASSERT(ret.applied == false, "Inner transaction should not be applied in dry run");
}
else
{
XRPL_ASSERT(
ret.applied == (isTesSuccess(ret.ter) || isTecClaim(ret.ter)),
"Inner transaction should not be applied");
}

JLOG(j.debug()) << "BatchTrace[" << parentBatchId << "]: " << tx.getTransactionID() << " "
<< (ret.applied ? "applied" : "failure") << ": " << transToken(ret.ter);

// If the transaction should be applied push its changes to the
// whole-batch view.
if (ret.applied && (isTesSuccess(ret.ter) || isTecClaim(ret.ter)))
if ((ret.applied || flags & tapDRY_RUN) && (isTesSuccess(ret.ter) || isTecClaim(ret.ter)))
perTxBatchView.apply(batchView);

return ret;
};

int applied = 0;
std::vector<ApplyResult> results;

for (STObject rb : batchTxn.getFieldArray(sfRawTransactions))
{
auto const result = applyOneTransaction(STTx{std::move(rb)});
XRPL_ASSERT(
result.applied == (isTesSuccess(result.ter) || isTecClaim(result.ter)),
"Outer Batch failure, inner transaction should not be applied");
if (flags & tapDRY_RUN)
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The condition check uses bitwise OR instead of checking if the tapDRY_RUN flag is set. This should use bitwise AND to check if the flag is present.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is bitwise AND...?

{
XRPL_ASSERT(
result.applied == false, "Inner transaction should not be applied in dry run");
}
else
{
XRPL_ASSERT(
result.applied == (isTesSuccess(result.ter) || isTecClaim(result.ter)),
"Outer Batch failure, inner transaction should not be applied");
}

if (result.applied)
++applied;
if (result.applied || flags & tapDRY_RUN)
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The condition check uses bitwise OR instead of checking if the tapDRY_RUN flag is set. This should use bitwise AND to check if the flag is present.

Suggested change
if (result.applied || flags & tapDRY_RUN)
if (result.applied || (flags & tapDRY_RUN) != 0)

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

For better readability, consider adding explicit parentheses around the bitwise AND operation: (result.applied || (flags & tapDRY_RUN)). While the operator precedence is correct, the explicit parentheses make the intent clearer and prevent potential confusion.

Suggested change
if (result.applied || flags & tapDRY_RUN)
if (result.applied || (flags & tapDRY_RUN))

Copilot uses AI. Check for mistakes.
results.push_back(result);
Comment on lines 138 to +198
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

applyBatchTransactions now always allocates and fills a std::vector<ApplyResult> even when called from normal transaction processing (applyTransaction), where the return value is only used as a boolean. This introduces unnecessary allocations/copies on the hot path for batch execution. Consider only collecting/returning per-inner ApplyResults when flags & tapDRY_RUN (or when an output parameter is provided), and otherwise keep a lightweight bool/counter-based path.

Copilot uses AI. Check for mistakes.

if (!isTesSuccess(result.ter))
{
if (mode & tfAllOrNothing)
return false;
return std::nullopt;

if (mode & tfUntilFailure)
break;
Expand All @@ -192,7 +209,12 @@
break;
}

return applied != 0;
if (results.empty())
{
return std::nullopt;

Check warning on line 214 in src/libxrpl/tx/apply.cpp

View check run for this annotation

Codecov / codecov/patch

src/libxrpl/tx/apply.cpp#L214

Added line #L214 was not covered by tests
}

return results;
}

ApplyTransactionResult
Expand Down Expand Up @@ -224,7 +246,7 @@
{
OpenView wholeBatchView(batch_view, view);

if (applyBatchTransactions(registry, wholeBatchView, txn, j))
if (applyBatchTransactions(registry, wholeBatchView, txn, flags, j))
wholeBatchView.apply(view);
}

Expand Down
Loading
Loading