Add delivered_amount to tx result for CheckCash (RIPD-1623)

This commit is contained in:
Scott Schurr
2018-04-03 08:21:05 -07:00
committed by Nikolaos D. Bougalis
parent 6bd0b850a0
commit 7bc163ee4c
5 changed files with 142 additions and 50 deletions

View File

@@ -282,6 +282,8 @@ CashCheck::doApply ()
// If it is not a check to self (as should be the case), then there's
// work to do...
auto viewJ = ctx_.app.journal ("View");
auto const optDeliverMin = ctx_.tx[~sfDeliverMin];
bool const doFix1623 {ctx_.view().rules().enabled (fix1623)};
if (srcId != account_)
{
STAmount const sendMax {sleCheck->getFieldAmount (sfSendMax)};
@@ -300,17 +302,9 @@ CashCheck::doApply ()
STAmount const srcLiquid {xrpLiquid (psb, srcId, -1, viewJ)};
// Now, how much do they need in order to be successful?
STAmount const xrpDeliver {
[&sendMax, &srcLiquid] (STTx const& tx)
{
// If the check cash specified Amount deliver exactly that.
auto const optDeliverMin = tx[~sfDeliverMin];
if (! optDeliverMin)
return tx.getFieldAmount (sfAmount);
return (std::max (
*optDeliverMin, std::min (sendMax, srcLiquid)));
}(ctx_.tx)};
STAmount const xrpDeliver {optDeliverMin ?
std::max (*optDeliverMin, std::min (sendMax, srcLiquid)) :
ctx_.tx.getFieldAmount (sfAmount)};
if (srcLiquid < xrpDeliver)
{
@@ -321,29 +315,27 @@ CashCheck::doApply ()
<< " < " << xrpDeliver.getFullText();
return tecUNFUNDED_PAYMENT;
}
else
{
// The source account has enough XRP so make the ledger change.
transferXRP (psb, srcId, account_, xrpDeliver, viewJ);
}
if (optDeliverMin && doFix1623)
// Set the DeliveredAmount metadata.
ctx_.deliver (xrpDeliver);
// The source account has enough XRP so make the ledger change.
transferXRP (psb, srcId, account_, xrpDeliver, viewJ);
}
else
{
// Let flow() do the heavy lifting on a check for an IOU.
auto const optDeliverMin = ctx_.tx[~sfDeliverMin];
STAmount const flowDeliver {[&optDeliverMin] (STTx const& tx)
{
// If the check cash specified Amount deliver exactly that.
if (! optDeliverMin)
return static_cast<STAmount>(tx[sfAmount]);
// We can't use the maximum possible currency here because
// there might be a gateway transfer rate to account for.
// Since the transfer rate cannot exceed 200%, we use 1/2
// maxValue for our limit.
return STAmount { optDeliverMin->issue(),
STAmount::cMaxValue / 2, STAmount::cMaxOffset };
}(ctx_.tx)};
//
// Note that for DeliverMin we don't know exactly how much
// currency we want flow to deliver. We can't ask for the
// maximum possible currency because there might be a gateway
// transfer rate to account for. Since the transfer rate cannot
// exceed 200%, we use 1/2 maxValue as our limit.
STAmount const flowDeliver {optDeliverMin ?
STAmount { optDeliverMin->issue(),
STAmount::cMaxValue / 2, STAmount::cMaxOffset } :
static_cast<STAmount>(ctx_.tx[sfAmount])};
// Call the payment engine's flow() to do the actual work.
auto const result = flow (psb, flowDeliver, srcId, account_,
@@ -364,10 +356,16 @@ CashCheck::doApply ()
}
// Make sure that deliverMin was satisfied.
if (optDeliverMin && result.actualAmountOut < *optDeliverMin)
if (optDeliverMin)
{
JLOG(ctx_.journal.warn()) << "flow did not produce DeliverMin.";
return tecPATH_PARTIAL;
if (result.actualAmountOut < *optDeliverMin)
{
JLOG(ctx_.journal.warn()) << "flow did not produce DeliverMin.";
return tecPATH_PARTIAL;
}
if (doFix1623)
// Set the delivered_amount metadata.
ctx_.deliver (result.actualAmountOut);
}
}
}

View File

@@ -78,7 +78,8 @@ class FeatureCollections
"Checks",
"fix1571",
"fix1543",
"ValidationCookies"
"ValidationCookies",
"fix1623"
};
std::vector<uint256> features;
@@ -363,6 +364,7 @@ extern uint256 const featureChecks;
extern uint256 const fix1571;
extern uint256 const fix1543;
extern uint256 const featureValidationCookies;
extern uint256 const fix1623;
} // ripple

View File

@@ -106,11 +106,12 @@ detail::supportedAmendments ()
{ "67A34F2CF55BFC0F93AACD5B281413176FEE195269FA6D95219A2DF738671172 fix1513" },
{ "B9E739B8296B4A1BB29BE990B17D66E21B62A300A909F25AC55C22D6C72E1F9D fix1523" },
{ "1D3463A5891F9E589C5AE839FFAC4A917CE96197098A1EF22304E1BC5B98A454 fix1528" },
{ "F64E1EABBE79D55B3BB82020516CEC2C582A98A6BFE20FBE9BB6A0D233418064 DepositAuth"},
{ "157D2D480E006395B76F948E3E07A45A05FE10230D88A7993C71F97AE4B1F2D1 Checks"},
{ "F64E1EABBE79D55B3BB82020516CEC2C582A98A6BFE20FBE9BB6A0D233418064 DepositAuth" },
{ "157D2D480E006395B76F948E3E07A45A05FE10230D88A7993C71F97AE4B1F2D1 Checks" },
{ "7117E2EC2DBF119CA55181D69819F1999ECEE1A0225A7FD2B9ED47940968479C fix1571" },
{ "CA7C02118BA27599528543DFE77BA6838D1B0F43B447D4D7F53523CE6A0E9AC2 fix1543" },
{ "8413364A1E27704241F7106789570A4B36EE2AFA14F94828E78BE942AB2F24BE ValidationCookies"}
{ "8413364A1E27704241F7106789570A4B36EE2AFA14F94828E78BE942AB2F24BE ValidationCookies" },
{ "58BE9B5968C4DA7C59BA900961828B113E5490699B21877DEF9A31E9D0FE5D5F fix1623" }
};
return supported;
}
@@ -163,5 +164,6 @@ uint256 const featureChecks = *getRegisteredFeature("Checks");
uint256 const fix1571 = *getRegisteredFeature("fix1571");
uint256 const fix1543 = *getRegisteredFeature("fix1543");
uint256 const featureValidationCookies = *getRegisteredFeature("ValidationCookies");
uint256 const fix1623 = *getRegisteredFeature("fix1623");
} // ripple

View File

@@ -18,10 +18,12 @@
//==============================================================================
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/ledger/View.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/AccountID.h>
#include <ripple/protocol/Feature.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/impl/RPCHelpers.h>
#include <boost/algorithm/string/case_conv.hpp>
@@ -400,10 +402,26 @@ addPaymentDeliveredAmount(Json::Value& meta, RPC::Context& context,
if (! transaction)
return;
auto serializedTx = transaction->getSTransaction ();
if (! serializedTx || serializedTx->getTxnType () != ttPAYMENT)
auto const serializedTx = transaction->getSTransaction ();
if (! serializedTx)
return;
{
// Only include this field for Payment and CheckCash transactions.
TxType const tt {serializedTx->getTxnType()};
if ((tt != ttPAYMENT) && (tt != ttCHECK_CASH))
return;
// Only include this field for CheckCash transactions if the fix
// is enabled.
if (tt == ttCHECK_CASH)
{
auto const view = context.app.openLedger().current();
if (!view || !view->rules().enabled (fix1623))
return;
}
}
if (transactionMeta)
{
if (transactionMeta->getResultTER() != tesSUCCESS)
@@ -437,7 +455,7 @@ addPaymentDeliveredAmount(Json::Value& meta, RPC::Context& context,
// then its absence indicates that the amount delivered is listed in the
// Amount field. DeliveredAmount went live January 24, 2014.
using namespace std::chrono_literals;
auto ct =
auto const ct =
context.ledgerMaster.getCloseTimeBySeq (transaction->getLedger ());
if (ct && (*ct > NetClock::time_point{446000000s}))
{