mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-25 13:35:54 +00:00
Add the 'fail_hard' flag for submitting and signing transactions. If fail
hard is set, on a local error, the transaction should be guaranteed not to happen unless it is resubmitted.
This commit is contained in:
@@ -197,12 +197,12 @@ void NetworkOPs::submitTransaction (Job&, SerializedTransaction::pointer iTrans,
|
||||
|
||||
// FIXME: Should submit to job queue
|
||||
theApp->getIOService ().post (boost::bind (&NetworkOPs::processTransaction, this,
|
||||
boost::make_shared<Transaction> (trans, false), false, callback));
|
||||
boost::make_shared<Transaction> (trans, false), false, false, callback));
|
||||
}
|
||||
|
||||
// Sterilize transaction through serialization.
|
||||
// This is fully synchronous and deprecated
|
||||
Transaction::pointer NetworkOPs::submitTransactionSync (Transaction::ref tpTrans, bool bAdmin, bool bSubmit)
|
||||
Transaction::pointer NetworkOPs::submitTransactionSync (Transaction::ref tpTrans, bool bAdmin, bool bFailHard, bool bSubmit)
|
||||
{
|
||||
Serializer s;
|
||||
tpTrans->getSTransaction ()->add (s);
|
||||
@@ -217,7 +217,7 @@ Transaction::pointer NetworkOPs::submitTransactionSync (Transaction::ref tpTrans
|
||||
else if (tpTransNew->getSTransaction ()->isEquivalent (*tpTrans->getSTransaction ()))
|
||||
{
|
||||
if (bSubmit)
|
||||
(void) NetworkOPs::processTransaction (tpTransNew, bAdmin);
|
||||
(void) NetworkOPs::processTransaction (tpTransNew, bAdmin, bFailHard);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -315,7 +315,7 @@ void NetworkOPs::runTransactionQueue ()
|
||||
theApp->getIOService ().post (boost::bind (&NetworkOPs::runTransactionQueue, this));
|
||||
}
|
||||
|
||||
Transaction::pointer NetworkOPs::processTransaction (Transaction::pointer trans, bool bAdmin, stCallback callback)
|
||||
Transaction::pointer NetworkOPs::processTransaction (Transaction::pointer trans, bool bAdmin, bool bFailHard, stCallback callback)
|
||||
{
|
||||
LoadEvent::autoptr ev = theApp->getJobQueue ().getLoadEventAP (jtTXN_PROC, "ProcessTXN");
|
||||
|
||||
@@ -345,7 +345,6 @@ Transaction::pointer NetworkOPs::processTransaction (Transaction::pointer trans,
|
||||
}
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl (theApp->getMasterLock ());
|
||||
Transaction::pointer dbtx = theApp->getMasterTransaction ().fetch (trans->getID (), true);
|
||||
bool didApply;
|
||||
TER r = mLedgerMaster->doTransaction (trans->getSTransaction (),
|
||||
bAdmin ? (tapOPEN_LEDGER | tapNO_CHECK_SIGN | tapADMIN) : (tapOPEN_LEDGER | tapNO_CHECK_SIGN), didApply);
|
||||
@@ -386,11 +385,14 @@ Transaction::pointer NetworkOPs::processTransaction (Transaction::pointer trans,
|
||||
}
|
||||
else if (isTerRetry (r))
|
||||
{
|
||||
// transaction should be held
|
||||
WriteLog (lsDEBUG, NetworkOPs) << "Transaction should be held: " << r;
|
||||
trans->setStatus (HELD);
|
||||
theApp->getMasterTransaction ().canonicalize (trans, true);
|
||||
mLedgerMaster->addHeldTransaction (trans);
|
||||
if (!bFailHard)
|
||||
{
|
||||
// transaction should be held
|
||||
WriteLog (lsDEBUG, NetworkOPs) << "Transaction should be held: " << r;
|
||||
trans->setStatus (HELD);
|
||||
theApp->getMasterTransaction ().canonicalize (trans, true);
|
||||
mLedgerMaster->addHeldTransaction (trans);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -398,7 +400,7 @@ Transaction::pointer NetworkOPs::processTransaction (Transaction::pointer trans,
|
||||
trans->setStatus (INVALID);
|
||||
}
|
||||
|
||||
if (didApply || (mMode != omFULL))
|
||||
if (didApply || ((mMode != omFULL) && !bFailHard))
|
||||
{
|
||||
std::set<uint64> peers;
|
||||
|
||||
|
||||
@@ -133,13 +133,13 @@ public:
|
||||
//
|
||||
typedef FUNCTION_TYPE<void (Transaction::pointer, TER)> stCallback; // must complete immediately
|
||||
void submitTransaction (Job&, SerializedTransaction::pointer, stCallback callback = stCallback ());
|
||||
Transaction::pointer submitTransactionSync (Transaction::ref tpTrans, bool bAdmin, bool bSubmit);
|
||||
Transaction::pointer submitTransactionSync (Transaction::ref tpTrans, bool bAdmin, bool bFailHard, bool bSubmit);
|
||||
|
||||
void runTransactionQueue ();
|
||||
Transaction::pointer processTransaction (Transaction::pointer, bool bAdmin, stCallback);
|
||||
Transaction::pointer processTransaction (Transaction::pointer transaction, bool bAdmin)
|
||||
Transaction::pointer processTransaction (Transaction::pointer, bool bAdmin, bool bFailHard, stCallback);
|
||||
Transaction::pointer processTransaction (Transaction::pointer transaction, bool bAdmin, bool bFailHard)
|
||||
{
|
||||
return processTransaction (transaction, bAdmin, stCallback ());
|
||||
return processTransaction (transaction, bAdmin, bFailHard, stCallback ());
|
||||
}
|
||||
|
||||
Transaction::pointer findTransactionByID (uint256 const& transactionID);
|
||||
|
||||
@@ -62,7 +62,7 @@ RPCHandler::RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub) : mNetOps
|
||||
;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, ScopedLock& mlh)
|
||||
Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, bool bFailHard, ScopedLock& mlh)
|
||||
{
|
||||
mlh.unlock ();
|
||||
|
||||
@@ -343,7 +343,7 @@ Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, Sc
|
||||
try
|
||||
{
|
||||
// FIXME: For performance, should use asynch interface
|
||||
tpTrans = mNetOps->submitTransactionSync (tpTrans, mRole == ADMIN, bSubmit);
|
||||
tpTrans = mNetOps->submitTransactionSync (tpTrans, mRole == ADMIN, bFailHard, bSubmit);
|
||||
|
||||
if (!tpTrans)
|
||||
{
|
||||
@@ -1653,7 +1653,8 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, Scop
|
||||
Json::Value RPCHandler::doSign (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder)
|
||||
{
|
||||
cost = rpcCOST_EXPENSIVE;
|
||||
return transactionSign (jvRequest, false, MasterLockHolder);
|
||||
bool bFailHard = jvRequest.isMember ("fail_hard") && jvRequest["fail_hard"].asBool ();
|
||||
return transactionSign (jvRequest, false, bFailHard, MasterLockHolder);
|
||||
}
|
||||
|
||||
// {
|
||||
@@ -1664,7 +1665,8 @@ Json::Value RPCHandler::doSubmit (Json::Value jvRequest, int& cost, ScopedLock&
|
||||
{
|
||||
if (!jvRequest.isMember ("tx_blob"))
|
||||
{
|
||||
return transactionSign (jvRequest, true, MasterLockHolder);
|
||||
bool bFailHard = jvRequest.isMember ("fail_hard") && jvRequest["fail_hard"].asBool ();
|
||||
return transactionSign (jvRequest, true, bFailHard, MasterLockHolder);
|
||||
}
|
||||
|
||||
Json::Value jvResult;
|
||||
@@ -1711,7 +1713,8 @@ Json::Value RPCHandler::doSubmit (Json::Value jvRequest, int& cost, ScopedLock&
|
||||
|
||||
try
|
||||
{
|
||||
(void) mNetOps->processTransaction (tpTrans, mRole == ADMIN);
|
||||
(void) mNetOps->processTransaction (tpTrans, mRole == ADMIN,
|
||||
jvRequest.isMember ("fail_hard") && jvRequest["fail_hard"].asBool ());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ class RPCHandler
|
||||
// Utilities
|
||||
void addSubmitPath (Json::Value& txJSON);
|
||||
boost::unordered_set<RippleAddress> parseAccountIds (const Json::Value& jvArray);
|
||||
Json::Value transactionSign (Json::Value jvRequest, bool bSubmit, ScopedLock& mlh);
|
||||
Json::Value transactionSign (Json::Value jvRequest, bool bSubmit, bool bFailHard, ScopedLock& mlh);
|
||||
|
||||
Json::Value lookupLedger (Json::Value jvRequest, Ledger::pointer& lpLedger);
|
||||
|
||||
|
||||
@@ -1081,7 +1081,7 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
|
||||
else
|
||||
theApp->getHashRouter ().setFlag (stx->getTransactionID (), SF_SIGGOOD);
|
||||
|
||||
theApp->getOPs ().processTransaction (tx, isSetBit (flags, SF_TRUSTED));
|
||||
theApp->getOPs ().processTransaction (tx, isSetBit (flags, SF_TRUSTED), false);
|
||||
|
||||
#ifndef TRUST_NETWORK
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user