48 std::string hash = {};
49 uint32_t ledgerIndex = 0u;
50 std::optional<boost::json::object> meta =
52 std::optional<boost::json::object> tx =
54 std::optional<std::string> metaStr =
56 std::optional<std::string> txStr =
58 std::optional<std::string> ctid =
60 std::optional<xrpl::LedgerHeader> ledgerHeader =
63 uint32_t apiVersion = 0u;
64 bool validated =
true;
93 if (input.ctid && input.transaction)
94 return Error{Status{RippledError::RpcInvalidParams}};
96 if (!input.ctid && !input.transaction)
97 return Error{Status{RippledError::RpcInvalidParams}};
99 static constexpr auto kMaxLedgerRange = 1000u;
100 auto const rangeSupplied = input.minLedger && input.maxLedger;
103 if (*input.minLedger > *input.maxLedger)
104 return Error{Status{RippledError::RpcInvalidLgrRange}};
106 if (*input.maxLedger - *input.minLedger > kMaxLedgerRange)
107 return Error{Status{RippledError::RpcExcessiveLgrRange}};
110 std::optional<uint32_t> currentNetId = std::nullopt;
111 if (
auto const& etlState = etl_->getETLState(); etlState.has_value())
112 currentNetId = etlState->networkID;
114 std::optional<data::TransactionAndMetadata> dbResponse;
119 return Error{Status{RippledError::RpcInvalidParams}};
121 auto const [lgrSeq, txnIdx, netId] = *ctid;
123 if (currentNetId && netId != *currentNetId) {
125 RippledError::RpcWrongNetwork,
127 "Wrong network. You should submit this request to a node running on "
134 dbResponse = fetchTxViaCtid(lgrSeq, txnIdx, ctx.yield);
136 dbResponse = sharedPtrBackend_->fetchTransaction(*input.transaction, ctx.yield);
142 if (rangeSupplied && input.transaction)
144 auto const range = sharedPtrBackend_->fetchLedgerRange();
145 ASSERT(range.has_value(),
"Tx's ledger range must be available");
148 auto const searchedAll = range->maxSequence >= *input.maxLedger &&
149 range->minSequence <= *input.minLedger;
152 boost::json::object extra;
153 extra[
"searched_all"] = searchedAll;
155 return Error{Status{RippledError::RpcTxnNotFound, std::move(extra)}};
158 return Error{Status{RippledError::RpcTxnNotFound}};
161 auto const [txn, meta] =
162 toExpandedJson(*dbResponse, ctx.apiVersion, NFTokenjson::ENABLE, currentNetId);
168 output.txStr = xrpl::strHex(dbResponse->transaction);
169 output.metaStr = xrpl::strHex(dbResponse->metadata);
172 if (txn.contains(JS(hash)))
173 output.hash = txn.at(JS(hash)).as_string();
177 auto const txnIdx = boost::json::value_to<uint64_t>(meta.at(
"TransactionIndex"));
178 if (txnIdx <= 0xFFFFU && dbResponse->ledgerSequence < 0x0FFF'FFFFUL && currentNetId &&
179 *currentNetId <= 0xFFFFU) {
181 dbResponse->ledgerSequence,
182 static_cast<uint16_t
>(txnIdx),
183 static_cast<uint16_t
>(*currentNetId)
187 output.date = dbResponse->date;
188 output.ledgerIndex = dbResponse->ledgerSequence;
191 if (ctx.apiVersion > 1u) {
192 output.ledgerHeader =
193 sharedPtrBackend_->fetchLedgerBySequence(dbResponse->ledgerSequence, ctx.yield);