mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-22 12:05:53 +00:00
Reformatting using AStyle
This commit is contained in:
@@ -1,240 +1,241 @@
|
||||
|
||||
SETUP_LOG (PaymentTransactor)
|
||||
|
||||
#define RIPPLE_PATHS_MAX 6
|
||||
#define RIPPLE_PATHS_MAX 6
|
||||
|
||||
TER PaymentTransactor::doApply()
|
||||
TER PaymentTransactor::doApply ()
|
||||
{
|
||||
// Ripple if source or destination is non-native or if there are paths.
|
||||
const uint32 uTxFlags = mTxn.getFlags();
|
||||
const bool bPartialPayment = isSetBit(uTxFlags, tfPartialPayment);
|
||||
const bool bLimitQuality = isSetBit(uTxFlags, tfLimitQuality);
|
||||
const bool bNoRippleDirect = isSetBit(uTxFlags, tfNoRippleDirect);
|
||||
const bool bPaths = mTxn.isFieldPresent(sfPaths);
|
||||
const bool bMax = mTxn.isFieldPresent(sfSendMax);
|
||||
const uint160 uDstAccountID = mTxn.getFieldAccount160(sfDestination);
|
||||
const STAmount saDstAmount = mTxn.getFieldAmount(sfAmount);
|
||||
const STAmount saMaxAmount = bMax
|
||||
? mTxn.getFieldAmount(sfSendMax)
|
||||
: saDstAmount.isNative()
|
||||
? saDstAmount
|
||||
: STAmount(saDstAmount.getCurrency(), mTxnAccountID, saDstAmount.getMantissa(), saDstAmount.getExponent(), saDstAmount.isNegative());
|
||||
const uint160 uSrcCurrency = saMaxAmount.getCurrency();
|
||||
const uint160 uDstCurrency = saDstAmount.getCurrency();
|
||||
const bool bXRPDirect = uSrcCurrency.isZero() && uDstCurrency.isZero();
|
||||
// Ripple if source or destination is non-native or if there are paths.
|
||||
const uint32 uTxFlags = mTxn.getFlags ();
|
||||
const bool bPartialPayment = isSetBit (uTxFlags, tfPartialPayment);
|
||||
const bool bLimitQuality = isSetBit (uTxFlags, tfLimitQuality);
|
||||
const bool bNoRippleDirect = isSetBit (uTxFlags, tfNoRippleDirect);
|
||||
const bool bPaths = mTxn.isFieldPresent (sfPaths);
|
||||
const bool bMax = mTxn.isFieldPresent (sfSendMax);
|
||||
const uint160 uDstAccountID = mTxn.getFieldAccount160 (sfDestination);
|
||||
const STAmount saDstAmount = mTxn.getFieldAmount (sfAmount);
|
||||
const STAmount saMaxAmount = bMax
|
||||
? mTxn.getFieldAmount (sfSendMax)
|
||||
: saDstAmount.isNative ()
|
||||
? saDstAmount
|
||||
: STAmount (saDstAmount.getCurrency (), mTxnAccountID, saDstAmount.getMantissa (), saDstAmount.getExponent (), saDstAmount.isNegative ());
|
||||
const uint160 uSrcCurrency = saMaxAmount.getCurrency ();
|
||||
const uint160 uDstCurrency = saDstAmount.getCurrency ();
|
||||
const bool bXRPDirect = uSrcCurrency.isZero () && uDstCurrency.isZero ();
|
||||
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str(boost::format("Payment> saMaxAmount=%s saDstAmount=%s")
|
||||
% saMaxAmount.getFullText()
|
||||
% saDstAmount.getFullText());
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str (boost::format ("Payment> saMaxAmount=%s saDstAmount=%s")
|
||||
% saMaxAmount.getFullText ()
|
||||
% saDstAmount.getFullText ());
|
||||
|
||||
if (!saDstAmount.isLegalNet() || !saMaxAmount.isLegalNet())
|
||||
return temBAD_AMOUNT;
|
||||
if (!saDstAmount.isLegalNet () || !saMaxAmount.isLegalNet ())
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (uTxFlags & tfPaymentMask)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Invalid flags set.";
|
||||
if (uTxFlags & tfPaymentMask)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Invalid flags set.";
|
||||
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
else if (!uDstAccountID)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Payment destination account not specified.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
else if (!uDstAccountID)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Payment destination account not specified.";
|
||||
|
||||
return temDST_NEEDED;
|
||||
}
|
||||
else if (bMax && !saMaxAmount.isPositive())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: bad max amount: " << saMaxAmount.getFullText();
|
||||
return temDST_NEEDED;
|
||||
}
|
||||
else if (bMax && !saMaxAmount.isPositive ())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: bad max amount: " << saMaxAmount.getFullText ();
|
||||
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (!saDstAmount.isPositive())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: bad dst amount: " << saDstAmount.getFullText();
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (!saDstAmount.isPositive ())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: bad dst amount: " << saDstAmount.getFullText ();
|
||||
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (CURRENCY_BAD == uSrcCurrency || CURRENCY_BAD == uDstCurrency)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Bad currency.";
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (CURRENCY_BAD == uSrcCurrency || CURRENCY_BAD == uDstCurrency)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Bad currency.";
|
||||
|
||||
return temBAD_CURRENCY;
|
||||
}
|
||||
else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str(boost::format("Payment: Malformed transaction: Redundant transaction: src=%s, dst=%s, src_cur=%s, dst_cur=%s")
|
||||
% mTxnAccountID.ToString()
|
||||
% uDstAccountID.ToString()
|
||||
% uSrcCurrency.ToString()
|
||||
% uDstCurrency.ToString());
|
||||
return temBAD_CURRENCY;
|
||||
}
|
||||
else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str (boost::format ("Payment: Malformed transaction: Redundant transaction: src=%s, dst=%s, src_cur=%s, dst_cur=%s")
|
||||
% mTxnAccountID.ToString ()
|
||||
% uDstAccountID.ToString ()
|
||||
% uSrcCurrency.ToString ()
|
||||
% uDstCurrency.ToString ());
|
||||
|
||||
return temREDUNDANT;
|
||||
}
|
||||
else if (bMax && saMaxAmount == saDstAmount && saMaxAmount.getCurrency() == saDstAmount.getCurrency())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Redundant SendMax.";
|
||||
return temREDUNDANT;
|
||||
}
|
||||
else if (bMax && saMaxAmount == saDstAmount && saMaxAmount.getCurrency () == saDstAmount.getCurrency ())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Redundant SendMax.";
|
||||
|
||||
return temREDUNDANT_SEND_MAX;
|
||||
}
|
||||
else if (bXRPDirect && bMax)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: SendMax specified for XRP to XRP.";
|
||||
return temREDUNDANT_SEND_MAX;
|
||||
}
|
||||
else if (bXRPDirect && bMax)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: SendMax specified for XRP to XRP.";
|
||||
|
||||
return temBAD_SEND_XRP_MAX;
|
||||
}
|
||||
else if (bXRPDirect && bPaths)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Paths specified for XRP to XRP.";
|
||||
return temBAD_SEND_XRP_MAX;
|
||||
}
|
||||
else if (bXRPDirect && bPaths)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Paths specified for XRP to XRP.";
|
||||
|
||||
return temBAD_SEND_XRP_PATHS;
|
||||
}
|
||||
else if (bXRPDirect && bPartialPayment)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Partial payment specified for XRP to XRP.";
|
||||
return temBAD_SEND_XRP_PATHS;
|
||||
}
|
||||
else if (bXRPDirect && bPartialPayment)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Partial payment specified for XRP to XRP.";
|
||||
|
||||
return temBAD_SEND_XRP_PARTIAL;
|
||||
}
|
||||
else if (bXRPDirect && bLimitQuality)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Limit quality specified for XRP to XRP.";
|
||||
return temBAD_SEND_XRP_PARTIAL;
|
||||
}
|
||||
else if (bXRPDirect && bLimitQuality)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: Limit quality specified for XRP to XRP.";
|
||||
|
||||
return temBAD_SEND_XRP_LIMIT;
|
||||
}
|
||||
else if (bXRPDirect && bNoRippleDirect)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: No ripple direct specified for XRP to XRP.";
|
||||
return temBAD_SEND_XRP_LIMIT;
|
||||
}
|
||||
else if (bXRPDirect && bNoRippleDirect)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: No ripple direct specified for XRP to XRP.";
|
||||
|
||||
return temBAD_SEND_XRP_NO_DIRECT;
|
||||
}
|
||||
return temBAD_SEND_XRP_NO_DIRECT;
|
||||
}
|
||||
|
||||
SLE::pointer sleDst = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
if (!sleDst)
|
||||
{
|
||||
// Destination account does not exist.
|
||||
SLE::pointer sleDst = mEngine->entryCache (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID));
|
||||
|
||||
if (!saDstAmount.isNative())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Delay transaction: Destination account does not exist.";
|
||||
if (!sleDst)
|
||||
{
|
||||
// Destination account does not exist.
|
||||
|
||||
// Another transaction could create the account and then this transaction would succeed.
|
||||
return tecNO_DST;
|
||||
}
|
||||
else if (isSetBit(mParams, tapOPEN_LEDGER) && bPartialPayment)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Delay transaction: Partial payment not allowed to create account.";
|
||||
// Make retry work smaller, by rejecting this.
|
||||
if (!saDstAmount.isNative ())
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Delay transaction: Destination account does not exist.";
|
||||
|
||||
// Another transaction could create the account and then this transaction would succeed.
|
||||
return telNO_DST_PARTIAL;
|
||||
}
|
||||
else if (saDstAmount.getNValue() < mEngine->getLedger()->getReserve(0)) // Reserve is not scaled by load.
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Delay transaction: Destination account does not exist. Insufficent payment to create account.";
|
||||
// Another transaction could create the account and then this transaction would succeed.
|
||||
return tecNO_DST;
|
||||
}
|
||||
else if (isSetBit (mParams, tapOPEN_LEDGER) && bPartialPayment)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Delay transaction: Partial payment not allowed to create account.";
|
||||
// Make retry work smaller, by rejecting this.
|
||||
|
||||
// Another transaction could create the account and then this transaction would succeed.
|
||||
return tecNO_DST_INSUF_XRP;
|
||||
}
|
||||
// Another transaction could create the account and then this transaction would succeed.
|
||||
return telNO_DST_PARTIAL;
|
||||
}
|
||||
else if (saDstAmount.getNValue () < mEngine->getLedger ()->getReserve (0)) // Reserve is not scaled by load.
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Delay transaction: Destination account does not exist. Insufficent payment to create account.";
|
||||
|
||||
// Create the account.
|
||||
sleDst = mEngine->entryCreate(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
// Another transaction could create the account and then this transaction would succeed.
|
||||
return tecNO_DST_INSUF_XRP;
|
||||
}
|
||||
|
||||
sleDst->setFieldAccount(sfAccount, uDstAccountID);
|
||||
sleDst->setFieldU32(sfSequence, 1);
|
||||
}
|
||||
else if ((sleDst->getFlags() & lsfRequireDestTag) && !mTxn.isFieldPresent(sfDestinationTag))
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: DestinationTag required.";
|
||||
// Create the account.
|
||||
sleDst = mEngine->entryCreate (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID));
|
||||
|
||||
return tefDST_TAG_NEEDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEngine->entryModify(sleDst);
|
||||
}
|
||||
sleDst->setFieldAccount (sfAccount, uDstAccountID);
|
||||
sleDst->setFieldU32 (sfSequence, 1);
|
||||
}
|
||||
else if ((sleDst->getFlags () & lsfRequireDestTag) && !mTxn.isFieldPresent (sfDestinationTag))
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Malformed transaction: DestinationTag required.";
|
||||
|
||||
TER terResult;
|
||||
// XXX Should bMax be sufficient to imply ripple?
|
||||
const bool bRipple = bPaths || bMax || !saDstAmount.isNative();
|
||||
return tefDST_TAG_NEEDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEngine->entryModify (sleDst);
|
||||
}
|
||||
|
||||
if (bRipple)
|
||||
{
|
||||
// Ripple payment
|
||||
TER terResult;
|
||||
// XXX Should bMax be sufficient to imply ripple?
|
||||
const bool bRipple = bPaths || bMax || !saDstAmount.isNative ();
|
||||
|
||||
STPathSet spsPaths = mTxn.getFieldPathSet(sfPaths);
|
||||
std::vector<PathState::pointer> vpsExpanded;
|
||||
STAmount saMaxAmountAct;
|
||||
STAmount saDstAmountAct;
|
||||
if (bRipple)
|
||||
{
|
||||
// Ripple payment
|
||||
|
||||
try
|
||||
{
|
||||
terResult = isSetBit(mParams, tapOPEN_LEDGER) && spsPaths.size() > RIPPLE_PATHS_MAX
|
||||
? telBAD_PATH_COUNT // Too many paths for proposed ledger.
|
||||
: RippleCalc::rippleCalc(
|
||||
mEngine->getNodes(),
|
||||
saMaxAmountAct,
|
||||
saDstAmountAct,
|
||||
vpsExpanded,
|
||||
saMaxAmount,
|
||||
saDstAmount,
|
||||
uDstAccountID,
|
||||
mTxnAccountID,
|
||||
spsPaths,
|
||||
bPartialPayment,
|
||||
bLimitQuality,
|
||||
bNoRippleDirect, // Always compute for finalizing ledger.
|
||||
false, // Not standalone, delete unfundeds.
|
||||
isSetBit(mParams, tapOPEN_LEDGER));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Caught throw: " << e.what();
|
||||
STPathSet spsPaths = mTxn.getFieldPathSet (sfPaths);
|
||||
std::vector<PathState::pointer> vpsExpanded;
|
||||
STAmount saMaxAmountAct;
|
||||
STAmount saDstAmountAct;
|
||||
|
||||
terResult = tefEXCEPTION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direct XRP payment.
|
||||
try
|
||||
{
|
||||
terResult = isSetBit (mParams, tapOPEN_LEDGER) && spsPaths.size () > RIPPLE_PATHS_MAX
|
||||
? telBAD_PATH_COUNT // Too many paths for proposed ledger.
|
||||
: RippleCalc::rippleCalc (
|
||||
mEngine->getNodes (),
|
||||
saMaxAmountAct,
|
||||
saDstAmountAct,
|
||||
vpsExpanded,
|
||||
saMaxAmount,
|
||||
saDstAmount,
|
||||
uDstAccountID,
|
||||
mTxnAccountID,
|
||||
spsPaths,
|
||||
bPartialPayment,
|
||||
bLimitQuality,
|
||||
bNoRippleDirect, // Always compute for finalizing ledger.
|
||||
false, // Not standalone, delete unfundeds.
|
||||
isSetBit (mParams, tapOPEN_LEDGER));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << "Payment: Caught throw: " << e.what ();
|
||||
|
||||
const uint32 uOwnerCount = mTxnAccount->getFieldU32(sfOwnerCount);
|
||||
const uint64 uReserve = mEngine->getLedger()->getReserve(uOwnerCount);
|
||||
terResult = tefEXCEPTION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direct XRP payment.
|
||||
|
||||
// Make sure have enough reserve to send. Allow final spend to use reserve for fee.
|
||||
if (mPriorBalance < saDstAmount + uReserve) // Reserve is not scaled by fee.
|
||||
{
|
||||
// Vote no. However, transaction might succeed, if applied in a different order.
|
||||
WriteLog (lsINFO, PaymentTransactor) << "";
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str(boost::format("Payment: Delay transaction: Insufficient funds: %s / %s (%d)")
|
||||
% mPriorBalance.getText() % (saDstAmount + uReserve).getText() % uReserve);
|
||||
const uint32 uOwnerCount = mTxnAccount->getFieldU32 (sfOwnerCount);
|
||||
const uint64 uReserve = mEngine->getLedger ()->getReserve (uOwnerCount);
|
||||
|
||||
terResult = tecUNFUNDED_PAYMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTxnAccount->setFieldAmount(sfBalance, mSourceBalance - saDstAmount);
|
||||
sleDst->setFieldAmount(sfBalance, sleDst->getFieldAmount(sfBalance) + saDstAmount);
|
||||
// Make sure have enough reserve to send. Allow final spend to use reserve for fee.
|
||||
if (mPriorBalance < saDstAmount + uReserve) // Reserve is not scaled by fee.
|
||||
{
|
||||
// Vote no. However, transaction might succeed, if applied in a different order.
|
||||
WriteLog (lsINFO, PaymentTransactor) << "";
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str (boost::format ("Payment: Delay transaction: Insufficient funds: %s / %s (%d)")
|
||||
% mPriorBalance.getText () % (saDstAmount + uReserve).getText () % uReserve);
|
||||
|
||||
// re-arm the password change fee if we can and need to
|
||||
if ((sleDst->getFlags() & lsfPasswordSpent))
|
||||
sleDst->clearFlag(lsfPasswordSpent);
|
||||
terResult = tecUNFUNDED_PAYMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTxnAccount->setFieldAmount (sfBalance, mSourceBalance - saDstAmount);
|
||||
sleDst->setFieldAmount (sfBalance, sleDst->getFieldAmount (sfBalance) + saDstAmount);
|
||||
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
}
|
||||
// re-arm the password change fee if we can and need to
|
||||
if ((sleDst->getFlags () & lsfPasswordSpent))
|
||||
sleDst->clearFlag (lsfPasswordSpent);
|
||||
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (transResultInfo(terResult, strToken, strHuman))
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str(boost::format("Payment: %s: %s") % strToken % strHuman);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
return terResult;
|
||||
if (transResultInfo (terResult, strToken, strHuman))
|
||||
{
|
||||
WriteLog (lsINFO, PaymentTransactor) << boost::str (boost::format ("Payment: %s: %s") % strToken % strHuman);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (false);
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
Reference in New Issue
Block a user