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

@@ -199,6 +199,29 @@ class Check_test : public beast::unit_test::suite
return ret;
}
// Helper function that verifies the expected DeliveredAmount is present.
//
// NOTE: the function _infers_ the transaction to operate on by calling
// env.tx(), which returns the result from the most recent transaction.
void verifyDeliveredAmount (test::jtx::Env& env, STAmount const& amount)
{
// Get the hash for the most recent transaction.
std::string const txHash {env.tx()->getJson (0)[jss::hash].asString()};
// Verify DeliveredAmount and delivered_amount metadata are correct.
env.close();
Json::Value const meta = env.rpc ("tx", txHash)[jss::result][jss::meta];
// Expect there to be a DeliveredAmount field.
if (! BEAST_EXPECT(meta.isMember (sfDeliveredAmount.jsonName)))
return;
// DeliveredAmount and delivered_amount should both be present and
// equal amount.
BEAST_EXPECT (meta[sfDeliveredAmount.jsonName] == amount.getJson (0));
BEAST_EXPECT (meta[jss::delivered_amount] == amount.getJson (0));
}
void testEnabled()
{
testcase ("Enabled");
@@ -607,7 +630,7 @@ class Check_test : public beast::unit_test::suite
// because one unit of alice's reserve is released when the
// check is consumed.
env (check::cash (bob, chkId, check::DeliverMin (checkAmount)));
env.close();
verifyDeliveredAmount (env, drops(checkAmount.mantissa()));
env.require (balance (alice, reserve));
env.require (balance (bob,
startBalance + checkAmount - drops (baseFeeDrops * 3)));
@@ -639,7 +662,7 @@ class Check_test : public beast::unit_test::suite
// bob decides to get what he can from the bounced check.
env (check::cash (bob, chkId, check::DeliverMin (drops(1))));
env.close();
verifyDeliveredAmount (env, drops(checkAmount.mantissa() - 1));
env.require (balance (alice, reserve));
env.require (balance (bob,
startBalance + checkAmount - drops ((baseFeeDrops * 2) + 1)));
@@ -829,7 +852,7 @@ class Check_test : public beast::unit_test::suite
// bob sets a DeliverMin of 7 and gets all that alice has.
env (check::cash (bob, chkId9, check::DeliverMin (USD(7))));
env.close();
verifyDeliveredAmount (env, USD(8));
env.require (balance (alice, USD(0)));
env.require (balance (bob, USD(8)));
BEAST_EXPECT (checksOnAccount (env, alice).size() == 3);
@@ -844,7 +867,7 @@ class Check_test : public beast::unit_test::suite
// Using DeliverMin for the SendMax value of the check (and no
// transfer fees) should work just like setting Amount.
env (check::cash (bob, chkId7, check::DeliverMin (USD(7))));
env.close();
verifyDeliveredAmount (env, USD(7));
env.require (balance (alice, USD(0)));
env.require (balance (bob, USD(8)));
BEAST_EXPECT (checksOnAccount (env, alice).size() == 2);
@@ -859,7 +882,7 @@ class Check_test : public beast::unit_test::suite
// alice has USD(8). If bob uses the check for USD(6) and uses a
// DeliverMin of 4, he should get the SendMax value of the check.
env (check::cash (bob, chkId6, check::DeliverMin (USD(4))));
env.close();
verifyDeliveredAmount (env, USD(6));
env.require (balance (alice, USD(2)));
env.require (balance (bob, USD(6)));
BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
@@ -870,7 +893,7 @@ class Check_test : public beast::unit_test::suite
// bob cashes the last remaining check setting a DeliverMin.
// of exactly alice's remaining USD.
env (check::cash (bob, chkId8, check::DeliverMin (USD(2))));
env.close();
verifyDeliveredAmount (env, USD(2));
env.require (balance (alice, USD(0)));
env.require (balance (bob, USD(8)));
BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
@@ -923,7 +946,7 @@ class Check_test : public beast::unit_test::suite
// Since bob set his limit low, he cashes the check with a
// DeliverMin and hits his trust limit.
env (check::cash (bob, chkId, check::DeliverMin (USD(4))));
env.close();
verifyDeliveredAmount (env, USD(5));
env.require (balance (alice, USD(3)));
env.require (balance (bob, USD(5)));
BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
@@ -1042,7 +1065,7 @@ class Check_test : public beast::unit_test::suite
// bob decides that he'll accept anything USD(75) or up.
// He gets USD(100).
env (check::cash (bob, chkId125, check::DeliverMin (USD(75))));
env.close();
verifyDeliveredAmount (env, USD(100));
env.require (balance (alice, USD(1000 - 125)));
env.require (balance (bob, USD( 0 + 100)));
BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
@@ -1440,7 +1463,7 @@ class Check_test : public beast::unit_test::suite
env (check::cash (bob, chkIdU, USD(20)));
env.close();
env (check::cash (bob, chkIdX, check::DeliverMin (XRP(10))));
env.close();
verifyDeliveredAmount (env, XRP(10));
// Try to cash an expired check.
env (check::cash (bob, chkIdExp, XRP(10)), ter (tecEXPIRED));
@@ -1506,7 +1529,7 @@ class Check_test : public beast::unit_test::suite
env (trust(gw, bob["USD"](0), tfClearFreeze));
env.close();
env (check::cash (bob, chkIdFroz3, check::DeliverMin (USD(1))));
env.close();
verifyDeliveredAmount (env, USD(3));
env.require (balance (alice, USD(14)));
env.require (balance (bob, USD( 6)));
@@ -1745,6 +1768,54 @@ class Check_test : public beast::unit_test::suite
env.close();
}
void testFix1623Enable ()
{
testcase ("Fix1623 enable");
using namespace test::jtx;
auto testEnable = [this] (FeatureBitset const& features, bool hasFields)
{
// Unless fix1623 is enabled a "tx" RPC command should return
// neither "DeliveredAmount" nor "delivered_amount" on a CheckCash
// transaction.
Account const alice {"alice"};
Account const bob {"bob"};
Env env {*this, features};
auto const closeTime =
fix1449Time() + 100 * env.closed()->info().closeTimeResolution;
env.close (closeTime);
env.fund (XRP(1000), alice, bob);
env.close();
uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
env (check::create (alice, bob, XRP(200)));
env.close();
env (check::cash (bob, chkId, check::DeliverMin (XRP(100))));
// Get the hash for the most recent transaction.
std::string const txHash {
env.tx()->getJson (0)[jss::hash].asString()};
// DeliveredAmount and delivered_amount are either present or
// not present in the metadata returned by "tx" based on fix1623.
env.close();
Json::Value const meta =
env.rpc ("tx", txHash)[jss::result][jss::meta];
BEAST_EXPECT(meta.isMember (
sfDeliveredAmount.jsonName) == hasFields);
BEAST_EXPECT(meta.isMember (jss::delivered_amount) == hasFields);
};
// Run both the disabled and enabled cases.
testEnable (supported_amendments() - fix1623, false);
testEnable (supported_amendments(), true);
}
public:
void run ()
{
@@ -1758,6 +1829,7 @@ public:
testCashInvalid();
testCancelValid();
testCancelInvalid();
testFix1623Enable();
}
};