mirror of
https://github.com/XRPLF/rippled.git
synced 2026-02-21 22:32:35 +00:00
Compare commits
5 Commits
develop
...
copilot/ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
616b3bf6d8 | ||
|
|
7f34e69550 | ||
|
|
9e7a0ebfd7 | ||
|
|
2083d6cb96 | ||
|
|
53e633dee5 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -74,3 +74,4 @@ DerivedData
|
||||
|
||||
# clangd cache
|
||||
/.cache
|
||||
build_nocmake/
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <test/jtx/xchain_bridge.h>
|
||||
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/rpc/CTID.h>
|
||||
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
@@ -671,6 +672,126 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testLedgerExpandedTransactionsCTID()
|
||||
{
|
||||
testcase("Ledger Expanded Transactions Include CTID");
|
||||
using namespace test::jtx;
|
||||
|
||||
// Use a specific network ID so we can verify it in the CTID
|
||||
constexpr uint32_t NETWORK_ID = 11111;
|
||||
auto cfg = envconfig([&](std::unique_ptr<Config> cfg) {
|
||||
cfg->NETWORK_ID = NETWORK_ID;
|
||||
return cfg;
|
||||
});
|
||||
|
||||
Env env{*this, std::move(cfg)};
|
||||
uint32_t netID = env.app().getNetworkIDService().getNetworkID();
|
||||
BEAST_EXPECT(netID == NETWORK_ID);
|
||||
|
||||
Account const alice{"alice"};
|
||||
env.fund(XRP(10000), alice);
|
||||
env.close();
|
||||
|
||||
// Submit a transaction and close the ledger
|
||||
env(noop(alice));
|
||||
env.close();
|
||||
|
||||
auto const ledgerSeq = env.closed()->header().seq;
|
||||
|
||||
// Request ledger with expanded transactions (API v2, non-binary)
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::ledger_index] = ledgerSeq;
|
||||
jv[jss::transactions] = true;
|
||||
jv[jss::expand] = true;
|
||||
jv[jss::api_version] = 2;
|
||||
auto jrr = env.rpc("json", "ledger", to_string(jv))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::status] == "success");
|
||||
auto const& txns = jrr[jss::ledger][jss::transactions];
|
||||
BEAST_EXPECT(txns.isArray() && txns.size() > 0);
|
||||
for (auto const& tx : txns)
|
||||
{
|
||||
BEAST_EXPECT(tx.isMember(jss::ctid));
|
||||
auto const ctid = tx[jss::ctid].asString();
|
||||
// Verify CTID can be decoded and matches the ledger
|
||||
auto const decoded = RPC::decodeCTID(ctid);
|
||||
if (BEAST_EXPECT(decoded.has_value()))
|
||||
{
|
||||
auto const [seq, idx, net] = *decoded;
|
||||
BEAST_EXPECT(seq == ledgerSeq);
|
||||
BEAST_EXPECT(net == NETWORK_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request ledger with expanded transactions (API v1, non-binary)
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::ledger_index] = ledgerSeq;
|
||||
jv[jss::transactions] = true;
|
||||
jv[jss::expand] = true;
|
||||
auto jrr = env.rpc("json", "ledger", to_string(jv))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::status] == "success");
|
||||
auto const& txns = jrr[jss::ledger][jss::transactions];
|
||||
BEAST_EXPECT(txns.isArray() && txns.size() > 0);
|
||||
for (auto const& tx : txns)
|
||||
{
|
||||
BEAST_EXPECT(tx.isMember(jss::ctid));
|
||||
auto const ctid = tx[jss::ctid].asString();
|
||||
auto const decoded = RPC::decodeCTID(ctid);
|
||||
if (BEAST_EXPECT(decoded.has_value()))
|
||||
{
|
||||
auto const [seq, idx, net] = *decoded;
|
||||
BEAST_EXPECT(seq == ledgerSeq);
|
||||
BEAST_EXPECT(net == NETWORK_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request ledger with expanded transactions (binary)
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::ledger_index] = ledgerSeq;
|
||||
jv[jss::transactions] = true;
|
||||
jv[jss::expand] = true;
|
||||
jv[jss::binary] = true;
|
||||
auto jrr = env.rpc("json", "ledger", to_string(jv))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::status] == "success");
|
||||
auto const& txns = jrr[jss::ledger][jss::transactions];
|
||||
BEAST_EXPECT(txns.isArray() && txns.size() > 0);
|
||||
for (auto const& tx : txns)
|
||||
{
|
||||
BEAST_EXPECT(tx.isMember(jss::ctid));
|
||||
auto const ctid = tx[jss::ctid].asString();
|
||||
auto const decoded = RPC::decodeCTID(ctid);
|
||||
if (BEAST_EXPECT(decoded.has_value()))
|
||||
{
|
||||
auto const [seq, idx, net] = *decoded;
|
||||
BEAST_EXPECT(seq == ledgerSeq);
|
||||
BEAST_EXPECT(net == NETWORK_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request ledger with non-expanded transactions (should NOT have CTID)
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::ledger_index] = ledgerSeq;
|
||||
jv[jss::transactions] = true;
|
||||
jv[jss::expand] = false;
|
||||
auto jrr = env.rpc("json", "ledger", to_string(jv))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::status] == "success");
|
||||
auto const& txns = jrr[jss::ledger][jss::transactions];
|
||||
BEAST_EXPECT(txns.isArray() && txns.size() > 0);
|
||||
for (auto const& tx : txns)
|
||||
{
|
||||
// Non-expanded transactions are just hash strings
|
||||
BEAST_EXPECT(tx.isString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
@@ -685,6 +806,7 @@ public:
|
||||
testNoQueue();
|
||||
testQueue();
|
||||
testLedgerAccountsOption();
|
||||
testLedgerExpandedTransactionsCTID();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
#include <xrpld/app/ledger/LedgerToJson.h>
|
||||
#include <xrpld/app/misc/DeliverMax.h>
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/rpc/CTID.h>
|
||||
#include <xrpld/rpc/Context.h>
|
||||
#include <xrpld/rpc/DeliveredAmount.h>
|
||||
#include <xrpld/rpc/MPTokenIssuanceID.h>
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/core/NetworkIDService.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
@@ -166,6 +168,17 @@ fillJsonTx(
|
||||
}
|
||||
}
|
||||
|
||||
// compute outgoing CTID
|
||||
if (fill.context && stMeta && stMeta->isFieldPresent(sfTransactionIndex))
|
||||
{
|
||||
uint32_t lgrSeq = fill.ledger.seq();
|
||||
uint32_t txnIdx = stMeta->getFieldU32(sfTransactionIndex);
|
||||
uint32_t netID = fill.context->app.getNetworkIDService().getNetworkID();
|
||||
|
||||
if (auto ctid = RPC::encodeCTID(lgrSeq, txnIdx, netID))
|
||||
txJson[jss::ctid] = *ctid;
|
||||
}
|
||||
|
||||
if ((fill.options & LedgerFill::ownerFunds) && txn->getTxnType() == ttOFFER_CREATE)
|
||||
{
|
||||
auto const account = txn->getAccountID(sfAccount);
|
||||
|
||||
Reference in New Issue
Block a user