Create ngContext (#579)

Fixes #582
This commit is contained in:
cyan317
2023-04-05 12:46:59 +01:00
committed by GitHub
parent 5d06a79f13
commit 654168efec
51 changed files with 294 additions and 288 deletions

View File

@@ -88,11 +88,9 @@ public:
* @return JSON result or @ref RPC::Status on error
*/
[[nodiscard]] ReturnType
process(
boost::json::value const& value,
boost::asio::yield_context& ptrYield) const
process(boost::json::value const& value, Context const& ctx) const
{
return pimpl_->process(value, &ptrYield);
return pimpl_->process(value, ctx);
}
private:
@@ -101,9 +99,10 @@ private:
virtual ~Concept() = default;
[[nodiscard]] virtual ReturnType
process(
boost::json::value const& value,
boost::asio::yield_context* ptrYield = nullptr) const = 0;
process(boost::json::value const& value, Context const& ctx) const = 0;
[[nodiscard]] virtual ReturnType
process(boost::json::value const& value) const = 0;
[[nodiscard]] virtual std::unique_ptr<Concept>
clone() const = 0;
@@ -120,11 +119,16 @@ private:
}
[[nodiscard]] ReturnType
process(
boost::json::value const& value,
boost::asio::yield_context* ptrYield = nullptr) const override
process(boost::json::value const& value) const override
{
return processor(handler, value, ptrYield);
return processor(handler, value);
}
[[nodiscard]] ReturnType
process(boost::json::value const& value, Context const& ctx)
const override
{
return processor(handler, value, &ctx);
}
[[nodiscard]] std::unique_ptr<Concept>

View File

@@ -21,7 +21,6 @@
#include <rpc/common/Types.h>
#include <boost/asio/spawn.hpp>
#include <boost/json/value_from.hpp>
#include <boost/json/value_to.hpp>
@@ -50,17 +49,17 @@ concept Requirement = requires(T a) {
*/
// clang-format off
template <typename T>
concept CoroutineProcess = requires(T a, typename T::Input in, typename T::Output out, boost::asio::yield_context& y) {
concept ContextProcess = requires(T a, typename T::Input in, typename T::Output out, Context const& y) {
{ a.process(in, y) } -> std::same_as<HandlerReturnType<decltype(out)>>; };
template <typename T>
concept NonCoroutineProcess = requires(T a, typename T::Input in, typename T::Output out) {
concept NonContextProcess = requires(T a, typename T::Input in, typename T::Output out) {
{ a.process(in) } -> std::same_as<HandlerReturnType<decltype(out)>>; };
template <typename T>
concept HandlerWithInput = requires(T a, typename T::Input in, typename T::Output out) {
{ a.spec() } -> std::same_as<RpcSpecConstRef>; }
and (CoroutineProcess<T> or NonCoroutineProcess<T>)
and (ContextProcess<T> or NonContextProcess<T>)
and boost::json::has_value_to<typename T::Input>::value;
template <typename T>

View File

@@ -22,8 +22,10 @@
#include <rpc/Errors.h>
#include <util/Expected.h>
#include <boost/asio/spawn.hpp>
#include <boost/json/value.hpp>
class WsBase;
namespace RPCng {
/**
@@ -57,6 +59,14 @@ struct VoidOutput
{
};
struct Context
{
// TODO: we shall change yield_context to const yield_context after we
// update backend interfaces to use const& yield
const std::reference_wrapper<boost::asio::yield_context> yield;
const std::shared_ptr<WsBase> session;
};
inline void
tag_invoke(
boost::json::value_from_tag,

View File

@@ -34,7 +34,7 @@ struct DefaultProcessor final
operator()(
HandlerType const& handler,
boost::json::value const& value,
boost::asio::yield_context* ptrYield = nullptr) const
Context const* ctx = nullptr) const
{
using boost::json::value_from;
using boost::json::value_to;
@@ -46,7 +46,7 @@ struct DefaultProcessor final
return Error{ret.error()}; // forward Status
auto const inData = value_to<typename HandlerType::Input>(value);
if constexpr (NonCoroutineProcess<HandlerType>)
if constexpr (NonContextProcess<HandlerType>)
{
auto const ret = handler.process(inData);
// real handler is given expected Input, not json
@@ -57,7 +57,7 @@ struct DefaultProcessor final
}
else
{
auto const ret = handler.process(inData, *ptrYield);
auto const ret = handler.process(inData, *ctx);
// real handler is given expected Input, not json
if (!ret)
return Error{ret.error()}; // forward Status

View File

@@ -57,12 +57,12 @@ AccountChannelsHandler::addChannel(
AccountChannelsHandler::Result
AccountChannelsHandler::process(
AccountChannelsHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -76,7 +76,7 @@ AccountChannelsHandler::process(
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
ripple::keylet::account(*accountID).key, lgrInfo.seq, yield);
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield);
if (!accountLedgerObject)
return Error{RPC::Status{
RPC::RippledError::rpcACT_NOT_FOUND, "accountNotFound"}};
@@ -103,7 +103,7 @@ AccountChannelsHandler::process(
lgrInfo.seq,
input.limit,
input.marker,
yield,
ctx.yield,
addToResponse);
response.account = input.account;

View File

@@ -100,7 +100,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
private:
void

View File

@@ -23,12 +23,12 @@ namespace RPCng {
AccountCurrenciesHandler::Result
AccountCurrenciesHandler::process(
AccountCurrenciesHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -41,7 +41,7 @@ AccountCurrenciesHandler::process(
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
ripple::keylet::account(*accountID).key, lgrInfo.seq, yield);
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield);
if (!accountLedgerObject)
return Error{RPC::Status{
RPC::RippledError::rpcACT_NOT_FOUND, "accountNotFound"}};
@@ -75,7 +75,7 @@ AccountCurrenciesHandler::process(
lgrInfo.seq,
std::numeric_limits<std::uint32_t>::max(),
{},
yield,
ctx.yield,
addToResponse);
response.ledgerHash = ripple::strHex(lgrInfo.hash);

View File

@@ -72,7 +72,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -21,9 +21,8 @@
namespace RPCng {
AccountInfoHandler::Result
AccountInfoHandler::process(
AccountInfoHandler::Input input,
boost::asio::yield_context& yield) const
AccountInfoHandler::process(AccountInfoHandler::Input input, Context const& ctx)
const
{
if (!input.account && !input.ident)
return Error{RPC::Status{RPC::RippledError::rpcACT_MALFORMED}};
@@ -31,7 +30,7 @@ AccountInfoHandler::process(
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -45,7 +44,7 @@ AccountInfoHandler::process(
auto const accountID = RPC::accountFromStringStrict(accountStr);
auto const accountKeylet = ripple::keylet::account(*accountID);
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
accountKeylet.key, lgrInfo.seq, yield);
accountKeylet.key, lgrInfo.seq, ctx.yield);
if (!accountLedgerObject)
return Error{RPC::Status{
RPC::RippledError::rpcACT_NOT_FOUND, "accountNotFound"}};
@@ -65,7 +64,7 @@ AccountInfoHandler::process(
// This code will need to be revisited if in the future we
// support multiple SignerLists on one account.
auto const signers = sharedPtrBackend_->fetchLedgerObject(
signersKey.key, lgrInfo.seq, yield);
signersKey.key, lgrInfo.seq, ctx.yield);
std::vector<ripple::STLedgerEntry> signerList;
if (signers)
{

View File

@@ -96,7 +96,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -95,12 +95,12 @@ AccountLinesHandler::addLine(
AccountLinesHandler::Result
AccountLinesHandler::process(
AccountLinesHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -111,7 +111,7 @@ AccountLinesHandler::process(
auto const lgrInfo = std::get<ripple::LedgerInfo>(lgrInfoOrStatus);
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
ripple::keylet::account(*accountID).key, lgrInfo.seq, yield);
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield);
if (not accountLedgerObject)
return Error{RPC::Status{
@@ -156,7 +156,7 @@ AccountLinesHandler::process(
lgrInfo.seq,
input.limit,
input.marker,
yield,
ctx.yield,
addToResponse);
response.account = input.account;

View File

@@ -104,7 +104,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
private:
void

View File

@@ -44,12 +44,12 @@ AccountOffersHandler::addOffer(
AccountOffersHandler::Result
AccountOffersHandler::process(
AccountOffersHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -62,7 +62,7 @@ AccountOffersHandler::process(
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
ripple::keylet::account(*accountID).key, lgrInfo.seq, yield);
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield);
if (!accountLedgerObject)
return Error{RPC::Status{
RPC::RippledError::rpcACT_NOT_FOUND, "accountNotFound"}};
@@ -87,7 +87,7 @@ AccountOffersHandler::process(
lgrInfo.seq,
input.limit,
input.marker,
yield,
ctx.yield,
addToResponse);
if (auto const status = std::get_if<RPC::Status>(&next))

View File

@@ -86,7 +86,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
private:
void

View File

@@ -25,9 +25,8 @@ clio::Logger gLog{"RPC-AccountTxHandler"};
namespace RPCng {
AccountTxHandler::Result
AccountTxHandler::process(
AccountTxHandler::Input input,
boost::asio::yield_context& yield) const
AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx)
const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto [minIndex, maxIndex] = *range;
@@ -67,7 +66,7 @@ AccountTxHandler::process(
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -94,7 +93,7 @@ AccountTxHandler::process(
auto const limit = input.limit.value_or(limitDefault);
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const [blobs, retCursor] = sharedPtrBackend_->fetchAccountTransactions(
*accountID, limit, input.forward, cursor, yield);
*accountID, limit, input.forward, cursor, ctx.yield);
Output response;
if (retCursor)

View File

@@ -105,7 +105,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -23,7 +23,7 @@
namespace RPCng {
BookOffersHandler::Result
BookOffersHandler::process(Input input, boost::asio::yield_context& yield) const
BookOffersHandler::process(Input input, Context const& ctx) const
{
auto bookMaybe = RPC::parseBook(
input.paysCurrency, input.paysID, input.getsCurrency, input.getsID);
@@ -34,7 +34,7 @@ BookOffersHandler::process(Input input, boost::asio::yield_context& yield) const
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -48,7 +48,7 @@ BookOffersHandler::process(Input input, boost::asio::yield_context& yield) const
// TODO: Add perfomance metrics if needed in future
auto [offers, _] = sharedPtrBackend_->fetchBookOffers(
bookKey, lgrInfo.seq, input.limit, yield);
bookKey, lgrInfo.seq, input.limit, ctx.yield);
BookOffersHandler::Output output;
output.ledgerHash = ripple::strHex(lgrInfo.hash);
@@ -59,7 +59,7 @@ BookOffersHandler::process(Input input, boost::asio::yield_context& yield) const
input.taker ? *(input.taker) : beast::zero,
*sharedPtrBackend_,
lgrInfo.seq,
yield);
ctx.yield);
return output;
}

View File

@@ -102,7 +102,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -24,13 +24,13 @@ namespace RPCng {
GatewayBalancesHandler::Result
GatewayBalancesHandler::process(
GatewayBalancesHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
// check ledger
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -41,7 +41,7 @@ GatewayBalancesHandler::process(
auto const lgrInfo = std::get<ripple::LedgerInfo>(lgrInfoOrStatus);
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
ripple::keylet::account(*accountID).key, lgrInfo.seq, yield);
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield);
if (!accountLedgerObject)
return Error{RPC::Status{
RPC::RippledError::rpcACT_NOT_FOUND, "accountNotFound"}};
@@ -120,7 +120,7 @@ GatewayBalancesHandler::process(
lgrInfo.seq,
std::numeric_limits<std::uint32_t>::max(),
{},
yield,
ctx.yield,
addToResponse);
if (auto status = std::get_if<RPC::Status>(&ret))

View File

@@ -113,7 +113,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -23,9 +23,8 @@
namespace RPCng {
LedgerEntryHandler::Result
LedgerEntryHandler::process(
LedgerEntryHandler::Input input,
boost::asio::yield_context& yield) const
LedgerEntryHandler::process(LedgerEntryHandler::Input input, Context const& ctx)
const
{
ripple::uint256 key;
if (input.index)
@@ -106,7 +105,7 @@ LedgerEntryHandler::process(
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -116,7 +115,7 @@ LedgerEntryHandler::process(
auto const lgrInfo = std::get<ripple::LedgerInfo>(lgrInfoOrStatus);
auto const ledgerObject =
sharedPtrBackend_->fetchLedgerObject(key, lgrInfo.seq, yield);
sharedPtrBackend_->fetchLedgerObject(key, lgrInfo.seq, ctx.yield);
if (!ledgerObject || ledgerObject->size() == 0)
return Error{RPC::Status{"entryNotFound"}};

View File

@@ -189,7 +189,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
private:
// dir_root and owner can not be both empty or filled at the same time

View File

@@ -30,10 +30,10 @@ namespace RPCng {
NFTBuyOffersHandler::Result
NFTBuyOffersHandler::process(
NFTBuyOffersHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const tokenID = uint256{input.nftID.c_str()};
auto const directory = keylet::nft_buys(tokenID);
return iterateOfferDirectory(input, tokenID, directory, yield);
return iterateOfferDirectory(input, tokenID, directory, ctx.yield);
}
} // namespace RPCng

View File

@@ -35,6 +35,6 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
} // namespace RPCng

View File

@@ -29,15 +29,13 @@ using namespace ::RPC;
namespace RPCng {
NFTInfoHandler::Result
NFTInfoHandler::process(
NFTInfoHandler::Input input,
boost::asio::yield_context& yield) const
NFTInfoHandler::process(NFTInfoHandler::Input input, Context const& ctx) const
{
auto const tokenID = ripple::uint256{input.nftID.c_str()};
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -46,7 +44,7 @@ NFTInfoHandler::process(
auto const lgrInfo = std::get<LedgerInfo>(lgrInfoOrStatus);
auto const maybeNft =
sharedPtrBackend_->fetchNFT(tokenID, lgrInfo.seq, yield);
sharedPtrBackend_->fetchNFT(tokenID, lgrInfo.seq, ctx.yield);
if (not maybeNft.has_value())
return Error{
Status{RippledError::rpcOBJECT_NOT_FOUND, "NFT not found"}};

View File

@@ -81,7 +81,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -30,11 +30,11 @@ namespace RPCng {
NFTSellOffersHandler::Result
NFTSellOffersHandler::process(
NFTSellOffersHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const tokenID = uint256{input.nftID.c_str()};
auto const directory = keylet::nft_sells(tokenID);
return iterateOfferDirectory(input, tokenID, directory, yield);
return iterateOfferDirectory(input, tokenID, directory, ctx.yield);
}
} // namespace RPCng

View File

@@ -35,6 +35,6 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
} // namespace RPCng

View File

@@ -28,12 +28,12 @@ namespace RPCng {
NoRippleCheckHandler::Result
NoRippleCheckHandler::process(
NoRippleCheckHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -45,7 +45,7 @@ NoRippleCheckHandler::process(
auto const accountID = RPC::accountFromStringStrict(input.account);
auto const keylet = ripple::keylet::account(*accountID).key;
auto const accountObj =
sharedPtrBackend_->fetchLedgerObject(keylet, lgrInfo.seq, yield);
sharedPtrBackend_->fetchLedgerObject(keylet, lgrInfo.seq, ctx.yield);
if (!accountObj)
return Error{RPC::Status{
RPC::RippledError::rpcACT_NOT_FOUND, "accountNotFound"}};
@@ -58,7 +58,7 @@ NoRippleCheckHandler::process(
sle.getFieldU32(ripple::sfFlags) & ripple::lsfDefaultRipple;
auto const fees = input.transactions
? sharedPtrBackend_->fetchFees(lgrInfo.seq, yield)
? sharedPtrBackend_->fetchFees(lgrInfo.seq, ctx.yield)
: std::nullopt;
auto output = NoRippleCheckHandler::Output();
@@ -101,7 +101,7 @@ NoRippleCheckHandler::process(
lgrInfo.seq,
std::numeric_limits<std::uint32_t>::max(),
{},
yield,
ctx.yield,
[&](ripple::SLE&& ownedItem) {
// don't push to result if limit is reached
if (limit != 0 && ownedItem.getType() == ripple::ltRIPPLE_STATE)

View File

@@ -84,7 +84,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -24,12 +24,12 @@ namespace RPCng {
TransactionEntryHandler::Result
TransactionEntryHandler::process(
TransactionEntryHandler::Input input,
boost::asio::yield_context& yield) const
Context const& ctx) const
{
auto const range = sharedPtrBackend_->fetchLedgerRange();
auto const lgrInfoOrStatus = RPC::getLedgerInfoFromHashOrSeq(
*sharedPtrBackend_,
yield,
ctx.yield,
input.ledgerHash,
input.ledgerIndex,
range->maxSequence);
@@ -39,7 +39,7 @@ TransactionEntryHandler::process(
auto const lgrInfo = std::get<ripple::LedgerInfo>(lgrInfoOrStatus);
auto const dbRet = sharedPtrBackend_->fetchTransaction(
ripple::uint256{input.txHash.c_str()}, yield);
ripple::uint256{input.txHash.c_str()}, ctx.yield);
// Note: transaction_entry is meant to only search a specified ledger for
// the specified transaction. tx searches the entire range of history. For
// rippled, having two separate commands made sense, as tx would use SQLite

View File

@@ -71,7 +71,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void

View File

@@ -23,7 +23,7 @@
namespace RPCng {
TxHandler::Result
TxHandler::process(Input input, boost::asio::yield_context& yield) const
TxHandler::process(Input input, Context const& ctx) const
{
constexpr static auto maxLedgerRange = 1000u;
auto const rangeSupplied = input.minLedger && input.maxLedger;
@@ -39,7 +39,7 @@ TxHandler::process(Input input, boost::asio::yield_context& yield) const
}
TxHandler::Output output;
auto const dbResponse = sharedPtrBackend_->fetchTransaction(
ripple::uint256{std::string_view(input.transaction)}, yield);
ripple::uint256{std::string_view(input.transaction)}, ctx.yield);
if (!dbResponse)
{
if (rangeSupplied)

View File

@@ -75,7 +75,7 @@ public:
}
Result
process(Input input, boost::asio::yield_context& yield) const;
process(Input input, Context const& ctx) const;
};
void