mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Add DeliverMin transaction field (RIPD-930)
This commit is contained in:
committed by
Vinnie Falco
parent
b7f07aed00
commit
4dc573f195
@@ -1859,6 +1859,10 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClInclude Include="..\..\src\ripple\app\tx\tests\common_transactor.h">
|
<ClInclude Include="..\..\src\ripple\app\tx\tests\common_transactor.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClCompile Include="..\..\src\ripple\app\tx\tests\DeliverMin.test.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\app\tx\tests\MultiSign.test.cpp">
|
<ClCompile Include="..\..\src\ripple\app\tx\tests\MultiSign.test.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
@@ -3435,6 +3439,8 @@
|
|||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\basic_prop.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\basic_prop.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\jtx\delivermin.h">
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\fee.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\fee.h">
|
||||||
@@ -3457,6 +3463,10 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\ripple\test\jtx\impl\delivermin.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\test\jtx\impl\Env.cpp">
|
<ClCompile Include="..\..\src\ripple\test\jtx\impl\Env.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
|
|||||||
@@ -2592,6 +2592,9 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\app\tx\tests\common_transactor.h">
|
<ClInclude Include="..\..\src\ripple\app\tx\tests\common_transactor.h">
|
||||||
<Filter>ripple\app\tx\tests</Filter>
|
<Filter>ripple\app\tx\tests</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClCompile Include="..\..\src\ripple\app\tx\tests\DeliverMin.test.cpp">
|
||||||
|
<Filter>ripple\app\tx\tests</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\app\tx\tests\MultiSign.test.cpp">
|
<ClCompile Include="..\..\src\ripple\app\tx\tests\MultiSign.test.cpp">
|
||||||
<Filter>ripple\app\tx\tests</Filter>
|
<Filter>ripple\app\tx\tests</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -4194,6 +4197,9 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\test\jtx\basic_prop.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\basic_prop.h">
|
||||||
<Filter>ripple\test\jtx</Filter>
|
<Filter>ripple\test\jtx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\jtx\delivermin.h">
|
||||||
|
<Filter>ripple\test\jtx</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
||||||
<Filter>ripple\test\jtx</Filter>
|
<Filter>ripple\test\jtx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -4215,6 +4221,9 @@
|
|||||||
<ClCompile Include="..\..\src\ripple\test\jtx\impl\balance.cpp">
|
<ClCompile Include="..\..\src\ripple\test\jtx\impl\balance.cpp">
|
||||||
<Filter>ripple\test\jtx\impl</Filter>
|
<Filter>ripple\test\jtx\impl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\ripple\test\jtx\impl\delivermin.cpp">
|
||||||
|
<Filter>ripple\test\jtx\impl</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\test\jtx\impl\Env.cpp">
|
<ClCompile Include="..\..\src\ripple\test\jtx\impl\Env.cpp">
|
||||||
<Filter>ripple\test\jtx\impl</Filter>
|
<Filter>ripple\test\jtx\impl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -192,4 +192,11 @@
|
|||||||
#define RIPPLE_USE_OPENSSL 0
|
#define RIPPLE_USE_OPENSSL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Config: RIPPLE_ENABLE_DELIVERMIN
|
||||||
|
Enables processing of delivermin in transactions
|
||||||
|
*/
|
||||||
|
#ifndef RIPPLE_ENABLE_DELIVERMIN
|
||||||
|
#define RIPPLE_ENABLE_DELIVERMIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <ripple/app/paths/RippleCalc.h>
|
#include <ripple/app/paths/RippleCalc.h>
|
||||||
#include <ripple/basics/Log.h>
|
#include <ripple/basics/Log.h>
|
||||||
#include <ripple/protocol/TxFlags.h>
|
#include <ripple/protocol/TxFlags.h>
|
||||||
|
#include <ripple/protocol/JsonFields.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -44,6 +45,12 @@ Payment::preCheck ()
|
|||||||
bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
|
bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
|
||||||
bool const bPaths = mTxn.isFieldPresent (sfPaths);
|
bool const bPaths = mTxn.isFieldPresent (sfPaths);
|
||||||
bool const bMax = mTxn.isFieldPresent (sfSendMax);
|
bool const bMax = mTxn.isFieldPresent (sfSendMax);
|
||||||
|
bool const deliverMin =
|
||||||
|
#if RIPPLE_ENABLE_DELIVERMIN
|
||||||
|
#else
|
||||||
|
(view().flags() & tapENABLE_TESTING) &&
|
||||||
|
#endif
|
||||||
|
mTxn.isFieldPresent(sfDeliverMin);
|
||||||
|
|
||||||
STAmount const saDstAmount (mTxn.getFieldAmount (sfAmount));
|
STAmount const saDstAmount (mTxn.getFieldAmount (sfAmount));
|
||||||
|
|
||||||
@@ -138,6 +145,45 @@ Payment::preCheck ()
|
|||||||
"No ripple direct specified for XRP to XRP.";
|
"No ripple direct specified for XRP to XRP.";
|
||||||
return temBAD_SEND_XRP_NO_DIRECT;
|
return temBAD_SEND_XRP_NO_DIRECT;
|
||||||
}
|
}
|
||||||
|
if (deliverMin)
|
||||||
|
{
|
||||||
|
#if ! RIPPLE_ENABLE_DELIVERMIN
|
||||||
|
if (! (view().flags() & tapENABLE_TESTING))
|
||||||
|
return temMALFORMED;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (! partialPaymentAllowed)
|
||||||
|
{
|
||||||
|
j_.trace << "Malformed transaction: Partial payment not "
|
||||||
|
"specified for " << jss::DeliverMin.c_str() << ".";
|
||||||
|
return temBAD_AMOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const dMin = mTxn.getFieldAmount(sfDeliverMin);
|
||||||
|
if (!isLegalNet(dMin) || dMin <= zero)
|
||||||
|
{
|
||||||
|
j_.trace << "Malformed transaction: Invalid " <<
|
||||||
|
jss::DeliverMin.c_str() << " amount. " <<
|
||||||
|
dMin.getFullText();
|
||||||
|
return temBAD_AMOUNT;
|
||||||
|
}
|
||||||
|
if (dMin.issue() != saDstAmount.issue())
|
||||||
|
{
|
||||||
|
j_.trace << "Malformed transaction: Dst issue differs "
|
||||||
|
"from " << jss::DeliverMin.c_str() << ". " <<
|
||||||
|
dMin.getFullText();
|
||||||
|
return temBAD_AMOUNT;
|
||||||
|
}
|
||||||
|
if (bMax &&
|
||||||
|
(dMin.getCurrency() == maxSourceAmount.getCurrency() &&
|
||||||
|
dMin > maxSourceAmount))
|
||||||
|
{
|
||||||
|
j_.trace << "Malformed transaction: SendMax less than " <<
|
||||||
|
jss::DeliverMin.c_str() << ". " <<
|
||||||
|
dMin.getFullText();
|
||||||
|
return temBAD_AMOUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Transactor::preCheck ();
|
return Transactor::preCheck ();
|
||||||
}
|
}
|
||||||
@@ -152,6 +198,13 @@ Payment::doApply ()
|
|||||||
bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
|
bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
|
||||||
bool const bPaths = mTxn.isFieldPresent (sfPaths);
|
bool const bPaths = mTxn.isFieldPresent (sfPaths);
|
||||||
bool const bMax = mTxn.isFieldPresent (sfSendMax);
|
bool const bMax = mTxn.isFieldPresent (sfSendMax);
|
||||||
|
bool const deliverMin =
|
||||||
|
#if RIPPLE_ENABLE_DELIVERMIN
|
||||||
|
#else
|
||||||
|
(view().flags() & tapENABLE_TESTING) &&
|
||||||
|
#endif
|
||||||
|
mTxn.isFieldPresent(sfDeliverMin);
|
||||||
|
|
||||||
AccountID const uDstAccountID (mTxn.getAccountID (sfDestination));
|
AccountID const uDstAccountID (mTxn.getAccountID (sfDestination));
|
||||||
STAmount const saDstAmount (mTxn.getFieldAmount (sfAmount));
|
STAmount const saDstAmount (mTxn.getFieldAmount (sfAmount));
|
||||||
STAmount maxSourceAmount;
|
STAmount maxSourceAmount;
|
||||||
@@ -291,8 +344,15 @@ Payment::doApply ()
|
|||||||
|
|
||||||
// TODO: is this right? If the amount is the correct amount, was
|
// TODO: is this right? If the amount is the correct amount, was
|
||||||
// the delivered amount previously set?
|
// the delivered amount previously set?
|
||||||
if (rc.result () == tesSUCCESS && rc.actualAmountOut != saDstAmount)
|
if (rc.result () == tesSUCCESS &&
|
||||||
|
rc.actualAmountOut != saDstAmount)
|
||||||
|
{
|
||||||
|
if (deliverMin && rc.actualAmountOut <
|
||||||
|
mTxn.getFieldAmount (sfDeliverMin))
|
||||||
|
rc.setResult (tecPATH_PARTIAL);
|
||||||
|
else
|
||||||
ctx_.deliverAmount (rc.actualAmountOut);
|
ctx_.deliverAmount (rc.actualAmountOut);
|
||||||
|
}
|
||||||
|
|
||||||
terResult = rc.result ();
|
terResult = rc.result ();
|
||||||
}
|
}
|
||||||
|
|||||||
129
src/ripple/app/tx/tests/DeliverMin.test.cpp
Normal file
129
src/ripple/app/tx/tests/DeliverMin.test.cpp
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <BeastConfig.h>
|
||||||
|
#include <ripple/test/jtx.h>
|
||||||
|
#include <beast/unit_test/suite.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
class DeliverMin_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
test_convert_all_of_an_asset()
|
||||||
|
{
|
||||||
|
testcase("Convert all of an asset using DeliverMin");
|
||||||
|
|
||||||
|
using namespace jtx;
|
||||||
|
auto const gw = Account("gateway");
|
||||||
|
auto const USD = gw["USD"];
|
||||||
|
|
||||||
|
{
|
||||||
|
Env env(*this);
|
||||||
|
env.fund(XRP(10000), "alice", "bob", "carol", gw);
|
||||||
|
env.trust(USD(100), "alice", "bob", "carol");
|
||||||
|
env(pay("alice", "bob", USD(10)), delivermin(USD(10)), ter(temBAD_AMOUNT));
|
||||||
|
env(pay("alice", "bob", USD(10)), delivermin(USD(-5)),
|
||||||
|
txflags(tfPartialPayment), ter(temBAD_AMOUNT));
|
||||||
|
env(pay("alice", "bob", USD(10)), delivermin(XRP(5)),
|
||||||
|
txflags(tfPartialPayment), ter(temBAD_AMOUNT));
|
||||||
|
env(pay("alice", "bob", USD(10)),
|
||||||
|
delivermin(Account("carol")["USD"](5)),
|
||||||
|
txflags(tfPartialPayment), ter(temBAD_AMOUNT));
|
||||||
|
env(pay("alice", "bob", USD(10)), delivermin(USD(15)),
|
||||||
|
txflags(tfPartialPayment), ter(tecPATH_DRY));
|
||||||
|
env(pay("alice", "bob", USD(10)),
|
||||||
|
delivermin(USD(10)), txflags(tfPartialPayment),
|
||||||
|
sendmax(USD(9)), ter(temBAD_AMOUNT));
|
||||||
|
env(pay(gw, "carol", USD(50)));
|
||||||
|
env(offer("carol", XRP(5), USD(5)));
|
||||||
|
env(pay("alice", "bob", USD(10)), paths(XRP),
|
||||||
|
delivermin(USD(7)), txflags(tfPartialPayment),
|
||||||
|
sendmax(XRP(20)), ter(tecPATH_PARTIAL));
|
||||||
|
env.require(balance("alice", XRP(9999.99998)));
|
||||||
|
env.require(balance("bob", XRP(10000)));
|
||||||
|
|
||||||
|
// DeliverMin greater than destination amount
|
||||||
|
env(pay("alice", "bob", USD(5)), paths(XRP),
|
||||||
|
delivermin(USD(50)), txflags(tfPartialPayment),
|
||||||
|
sendmax(XRP(5)));
|
||||||
|
env.require(balance("bob", USD(5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Env env(*this);
|
||||||
|
env.fund(XRP(10000), "alice", "bob", gw);
|
||||||
|
env.trust(USD(1000), "alice", "bob");
|
||||||
|
env(pay(gw, "bob", USD(100)));
|
||||||
|
env(offer("bob", XRP(100), USD(100)));
|
||||||
|
env(pay("alice", "alice", USD(10000)), paths(XRP),
|
||||||
|
delivermin(USD(100)), txflags(tfPartialPayment),
|
||||||
|
sendmax(XRP(100)));
|
||||||
|
env.require(balance("alice", USD(100)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Env env(*this);
|
||||||
|
env.fund(XRP(10000), "alice", "bob", "carol", gw);
|
||||||
|
env.trust(USD(1000), "bob", "carol");
|
||||||
|
env(pay(gw, "bob", USD(200)));
|
||||||
|
env(offer("bob", XRP(100), USD(100)));
|
||||||
|
env(offer("bob", XRP(1000), USD(100)));
|
||||||
|
env(offer("bob", XRP(10000), USD(100)));
|
||||||
|
env(pay("alice", "carol", USD(10000)), paths(XRP),
|
||||||
|
delivermin(USD(200)), txflags(tfPartialPayment),
|
||||||
|
sendmax(XRP(1000)), ter(tecPATH_PARTIAL));
|
||||||
|
env(pay("alice", "carol", USD(10000)), paths(XRP),
|
||||||
|
delivermin(USD(200)), txflags(tfPartialPayment),
|
||||||
|
sendmax(XRP(1100)));
|
||||||
|
env.require(balance("bob", USD(0)));
|
||||||
|
env.require(balance("carol", USD(200)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Env env(*this);
|
||||||
|
env.fund(XRP(10000), "alice", "bob", "carol", "dan", gw);
|
||||||
|
env.trust(USD(1000), "bob", "carol", "dan");
|
||||||
|
env(pay(gw, "bob", USD(100)));
|
||||||
|
env(pay(gw, "dan", USD(100)));
|
||||||
|
env(offer("bob", XRP(100), USD(100)));
|
||||||
|
env(offer("bob", XRP(1000), USD(100)));
|
||||||
|
env(offer("dan", XRP(100), USD(100)));
|
||||||
|
env(pay("alice", "carol", USD(10000)), paths(XRP),
|
||||||
|
delivermin(USD(200)), txflags(tfPartialPayment),
|
||||||
|
sendmax(XRP(200)));
|
||||||
|
env.require(balance("bob", USD(0)));
|
||||||
|
env.require(balance("carol", USD(200)));
|
||||||
|
env.require(balance("dan", USD(0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
run()
|
||||||
|
{
|
||||||
|
test_convert_all_of_an_asset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(DeliverMin,app,ripple)
|
||||||
|
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
@@ -39,6 +39,7 @@ JSS ( Account ); // in: TransactionSign; field.
|
|||||||
JSS ( Amount ); // in: TransactionSign; field.
|
JSS ( Amount ); // in: TransactionSign; field.
|
||||||
JSS ( ClearFlag ); // field.
|
JSS ( ClearFlag ); // field.
|
||||||
JSS ( Destination ); // in: TransactionSign; field.
|
JSS ( Destination ); // in: TransactionSign; field.
|
||||||
|
JSS ( DeliverMin ); // in: TransactionSign
|
||||||
JSS ( Fee ); // in/out: TransactionSign; field.
|
JSS ( Fee ); // in/out: TransactionSign; field.
|
||||||
JSS ( Flags ); // in/out: TransactionSign; field.
|
JSS ( Flags ); // in/out: TransactionSign; field.
|
||||||
JSS ( Invalid ); //
|
JSS ( Invalid ); //
|
||||||
|
|||||||
@@ -381,6 +381,7 @@ extern SField const sfLowLimit;
|
|||||||
extern SField const sfHighLimit;
|
extern SField const sfHighLimit;
|
||||||
extern SField const sfFee;
|
extern SField const sfFee;
|
||||||
extern SField const sfSendMax;
|
extern SField const sfSendMax;
|
||||||
|
extern SField const sfDeliverMin;
|
||||||
|
|
||||||
// currency amount (uncommon)
|
// currency amount (uncommon)
|
||||||
extern SField const sfMinimumOffer;
|
extern SField const sfMinimumOffer;
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ SField const sfLowLimit = make::one(&sfLowLimit, STI_AMOUNT, 6, "LowLimit"
|
|||||||
SField const sfHighLimit = make::one(&sfHighLimit, STI_AMOUNT, 7, "HighLimit");
|
SField const sfHighLimit = make::one(&sfHighLimit, STI_AMOUNT, 7, "HighLimit");
|
||||||
SField const sfFee = make::one(&sfFee, STI_AMOUNT, 8, "Fee");
|
SField const sfFee = make::one(&sfFee, STI_AMOUNT, 8, "Fee");
|
||||||
SField const sfSendMax = make::one(&sfSendMax, STI_AMOUNT, 9, "SendMax");
|
SField const sfSendMax = make::one(&sfSendMax, STI_AMOUNT, 9, "SendMax");
|
||||||
|
SField const sfDeliverMin = make::one(&sfDeliverMin, STI_AMOUNT, 10, "DeliverMin");
|
||||||
|
|
||||||
// currency amount (uncommon)
|
// currency amount (uncommon)
|
||||||
SField const sfMinimumOffer = make::one(&sfMinimumOffer, STI_AMOUNT, 16, "MinimumOffer");
|
SField const sfMinimumOffer = make::one(&sfMinimumOffer, STI_AMOUNT, 16, "MinimumOffer");
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ TxFormats::TxFormats ()
|
|||||||
<< SOElement (sfPaths, SOE_DEFAULT)
|
<< SOElement (sfPaths, SOE_DEFAULT)
|
||||||
<< SOElement (sfInvoiceID, SOE_OPTIONAL)
|
<< SOElement (sfInvoiceID, SOE_OPTIONAL)
|
||||||
<< SOElement (sfDestinationTag, SOE_OPTIONAL)
|
<< SOElement (sfDestinationTag, SOE_OPTIONAL)
|
||||||
|
<< SOElement (sfDeliverMin, SOE_OPTIONAL)
|
||||||
;
|
;
|
||||||
|
|
||||||
add ("EnableAmendment", ttAMENDMENT)
|
add ("EnableAmendment", ttAMENDMENT)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <ripple/test/jtx/advance.h>
|
#include <ripple/test/jtx/advance.h>
|
||||||
#include <ripple/test/jtx/amount.h>
|
#include <ripple/test/jtx/amount.h>
|
||||||
#include <ripple/test/jtx/balance.h>
|
#include <ripple/test/jtx/balance.h>
|
||||||
|
#include <ripple/test/jtx/delivermin.h>
|
||||||
#include <ripple/test/jtx/Env.h>
|
#include <ripple/test/jtx/Env.h>
|
||||||
#include <ripple/test/jtx/fee.h>
|
#include <ripple/test/jtx/fee.h>
|
||||||
#include <ripple/test/jtx/flags.h>
|
#include <ripple/test/jtx/flags.h>
|
||||||
|
|||||||
50
src/ripple/test/jtx/delivermin.h
Normal file
50
src/ripple/test/jtx/delivermin.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_TEST_JTX_DELIVERMIN_H_INCLUDED
|
||||||
|
#define RIPPLE_TEST_JTX_DELIVERMIN_H_INCLUDED
|
||||||
|
|
||||||
|
#include <ripple/test/jtx/Env.h>
|
||||||
|
#include <ripple/protocol/STAmount.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
namespace jtx {
|
||||||
|
|
||||||
|
/** Sets the DeliverMin on a JTx. */
|
||||||
|
class delivermin
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
STAmount amount_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
delivermin (STAmount const& amount)
|
||||||
|
: amount_(amount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
operator()(Env const&, JTx& jtx) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // jtx
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -52,6 +52,24 @@ PrettyAmount::operator AnyAmount() const
|
|||||||
return { amount_ };
|
return { amount_ };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static
|
||||||
|
std::string
|
||||||
|
to_places(const T d, std::uint8_t places)
|
||||||
|
{
|
||||||
|
assert(places <= std::numeric_limits<T>::digits10);
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::setprecision(places) << std::fixed << d;
|
||||||
|
|
||||||
|
std::string out = oss.str();
|
||||||
|
out.erase(out.find_last_not_of('0') + 1, std::string::npos);
|
||||||
|
if (out.back() == '.')
|
||||||
|
out.pop_back();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream&
|
std::ostream&
|
||||||
operator<< (std::ostream& os,
|
operator<< (std::ostream& os,
|
||||||
PrettyAmount const& amount)
|
PrettyAmount const& amount)
|
||||||
@@ -72,11 +90,10 @@ operator<< (std::ostream& os,
|
|||||||
}
|
}
|
||||||
auto const d = double(n) /
|
auto const d = double(n) /
|
||||||
dropsPerXRP<int>::value;
|
dropsPerXRP<int>::value;
|
||||||
os.precision(6);
|
|
||||||
if (amount.value().negative())
|
if (amount.value().negative())
|
||||||
os << "-" << d << " XRP";
|
os << "-";
|
||||||
else
|
|
||||||
os << d << " XRP";
|
os << to_places(d, 6) << " XRP";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
36
src/ripple/test/jtx/impl/delivermin.cpp
Normal file
36
src/ripple/test/jtx/impl/delivermin.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <BeastConfig.h>
|
||||||
|
#include <ripple/test/jtx/delivermin.h>
|
||||||
|
#include <ripple/protocol/JsonFields.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
namespace jtx {
|
||||||
|
|
||||||
|
void
|
||||||
|
delivermin::operator()(Env const& env, JTx& jt) const
|
||||||
|
{
|
||||||
|
jt.jv[jss::DeliverMin] = amount_.getJson(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // jtx
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
@@ -47,3 +47,4 @@
|
|||||||
#include <ripple/app/tx/tests/OfferStream.test.cpp>
|
#include <ripple/app/tx/tests/OfferStream.test.cpp>
|
||||||
#include <ripple/app/tx/tests/Offer.test.cpp>
|
#include <ripple/app/tx/tests/Offer.test.cpp>
|
||||||
#include <ripple/app/tx/tests/Taker.test.cpp>
|
#include <ripple/app/tx/tests/Taker.test.cpp>
|
||||||
|
#include <ripple/app/tx/tests/DeliverMin.test.cpp>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <ripple/test/jtx/impl/advance.cpp>
|
#include <ripple/test/jtx/impl/advance.cpp>
|
||||||
#include <ripple/test/jtx/impl/amount.cpp>
|
#include <ripple/test/jtx/impl/amount.cpp>
|
||||||
#include <ripple/test/jtx/impl/balance.cpp>
|
#include <ripple/test/jtx/impl/balance.cpp>
|
||||||
|
#include <ripple/test/jtx/impl/delivermin.cpp>
|
||||||
#include <ripple/test/jtx/impl/Env.cpp>
|
#include <ripple/test/jtx/impl/Env.cpp>
|
||||||
#include <ripple/test/jtx/impl/fee.cpp>
|
#include <ripple/test/jtx/impl/fee.cpp>
|
||||||
#include <ripple/test/jtx/impl/flags.cpp>
|
#include <ripple/test/jtx/impl/flags.cpp>
|
||||||
|
|||||||
Reference in New Issue
Block a user