debug txn injector

This commit is contained in:
Richard Holland
2024-01-17 18:07:05 +00:00
parent de522ac4ae
commit 7877ed9704
6 changed files with 95 additions and 0 deletions

View File

@@ -30,6 +30,7 @@
#include <boost/circular_buffer.hpp>
#include <boost/intrusive/set.hpp>
#include <optional>
#include <vector>
namespace ripple {
@@ -56,7 +57,14 @@ class Config;
*/
class TxQ
{
private:
std::mutex debugTxInjectMutex;
std::vector<STTx> debugTxInjectQueue;
public:
void
debugTxInject(STTx const& txn);
/// Fee level for single-signed reference transaction.
static constexpr FeeLevel64 baseLevel{256};

View File

@@ -93,6 +93,14 @@ increase(FeeLevel64 level, std::uint32_t increasePercent)
//////////////////////////////////////////////////////////////////////////
void
TxQ::debugTxInject(STTx const& txn)
{
const std::lock_guard<std::mutex> _(debugTxInjectMutex);
debugTxInjectQueue.push_back(txn);
}
std::size_t
TxQ::FeeMetrics::update(
Application& app,
@@ -1444,6 +1452,35 @@ TxQ::accept(Application& app, OpenView& view)
auto const metricsSnapshot = feeMetrics_.getSnapshot();
// try to inject any debug txns waiting in the debug queue
{
std::unique_lock<std::mutex> trylock (TxQ::debugTxInjectMutex, std::try_to_lock);
if(trylock.owns_lock() && !debugTxInjectQueue.empty())
{
// pop everything
for (STTx const& txn : debugTxInjectQueue)
{
auto txnHash = txn.getTransactionID();
app.getHashRouter().setFlags(txnHash, SF_EMITTED | SF_PRIVATE2);
auto const& emitted =
const_cast<ripple::STTx&>(txn)
.downcast<STObject>();
auto s = std::make_shared<ripple::Serializer>();
emitted.add(*s);
view.rawTxInsert(
txnHash,
std::move(s),
nullptr);
ledgerChanged = true;
}
debugTxInjectQueue.clear();
}
}
// Inject emitted transactions if any
if (view.rules().enabled(featureHooks))
do

View File

@@ -353,6 +353,7 @@ JSS(ident); // in: AccountCurrencies, AccountInfo,
// OwnerInfo
JSS(ignore_default); // in: AccountLines
JSS(inLedger); // out: tx/Transaction
JSS(in_queue);
JSS(inbound); // out: PeerImp
JSS(index); // in: LedgerEntry, DownloadShard
// out: STLedgerEntry,

View File

@@ -141,6 +141,8 @@ doCrawlShards(RPC::JsonContext&);
Json::Value
doStop(RPC::JsonContext&);
Json::Value
doInject(RPC::JsonContext&);
Json::Value
doSubmit(RPC::JsonContext&);
Json::Value
doSubmitMultiSigned(RPC::JsonContext&);

View File

@@ -20,6 +20,7 @@
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/misc/HashRouter.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/app/misc/TxQ.h>
#include <ripple/app/tx/apply.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/ErrorCodes.h>
@@ -39,6 +40,51 @@ getFailHard(RPC::JsonContext const& context)
context.params["fail_hard"].asBool());
}
// {
// tx_blob: serialized tx
// }
// Only for debug use!!!!
Json::Value
doInject(RPC::JsonContext& context)
{
if (!context.params.isMember(jss::tx_blob))
return RPC::make_error(
rpcINVALID_PARAMS, "Need tx_blob");
Json::Value jvResult;
auto ret = strUnHex(context.params[jss::tx_blob].asString());
if (!ret || !ret->size())
return rpcError(rpcINVALID_PARAMS);
SerialIter sitTrans(makeSlice(*ret));
std::shared_ptr<STTx const> stpTrans;
try
{
stpTrans = std::make_shared<STTx const>(std::ref(sitTrans));
}
catch (std::exception& e)
{
jvResult[jss::error] = "invalidTransaction";
jvResult[jss::error_exception] = e.what();
jvResult[jss::in_queue] = false;
return jvResult;
}
context.app.getTxQ().debugTxInject(*stpTrans);
jvResult[jss::tx_json] = stpTrans->getJson(JsonOptions::none);
jvResult[jss::in_queue] = true;
return jvResult;
}
// {
// tx_json: <object>,
// secret: <secret>

View File

@@ -141,6 +141,7 @@ Handler const handlerArray[]{
{"ripple_path_find", byRef(&doRipplePathFind), Role::USER, NO_CONDITION},
{"sign", byRef(&doSign), Role::USER, NO_CONDITION},
{"sign_for", byRef(&doSignFor), Role::USER, NO_CONDITION},
{"inject", byRef(&doInject), Role::USER, NEEDS_CURRENT_LEDGER},
{"submit", byRef(&doSubmit), Role::USER, NEEDS_CURRENT_LEDGER},
{"submit_multisigned",
byRef(&doSubmitMultiSigned),