mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Format first-party source according to .clang-format
This commit is contained in:
committed by
manojsdoshi
parent
65dfc5d19e
commit
50760c6935
@@ -17,14 +17,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <test/jtx.h>
|
||||
#include <test/jtx/Env.h>
|
||||
#include <ripple/beast/utility/Journal.h>
|
||||
#include <ripple/app/tx/apply.h>
|
||||
#include <ripple/app/tx/impl/Transactor.h>
|
||||
#include <ripple/app/tx/impl/ApplyContext.h>
|
||||
#include <ripple/app/tx/impl/Transactor.h>
|
||||
#include <ripple/beast/utility/Journal.h>
|
||||
#include <ripple/protocol/STLedgerEntry.h>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <test/jtx.h>
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -33,46 +33,45 @@ class Invariants_test : public beast::unit_test::suite
|
||||
// this is common setup/method for running a failing invariant check. The
|
||||
// precheck function is used to manipulate the ApplyContext with view
|
||||
// changes that will cause the check to fail.
|
||||
using Precheck = std::function <
|
||||
bool (
|
||||
test::jtx::Account const& a,
|
||||
test::jtx::Account const& b,
|
||||
ApplyContext& ac)>;
|
||||
using Precheck = std::function<bool(
|
||||
test::jtx::Account const& a,
|
||||
test::jtx::Account const& b,
|
||||
ApplyContext& ac)>;
|
||||
|
||||
void
|
||||
doInvariantCheck(
|
||||
std::vector<std::string> const& expect_logs,
|
||||
Precheck const& precheck,
|
||||
XRPAmount fee = XRPAmount{},
|
||||
STTx tx = STTx {ttACCOUNT_SET, [](STObject&){ }},
|
||||
std::initializer_list<TER> ters =
|
||||
{tecINVARIANT_FAILED, tefINVARIANT_FAILED})
|
||||
STTx tx = STTx{ttACCOUNT_SET, [](STObject&) {}},
|
||||
std::initializer_list<TER> ters = {
|
||||
tecINVARIANT_FAILED,
|
||||
tefINVARIANT_FAILED})
|
||||
{
|
||||
using namespace test::jtx;
|
||||
Env env {*this};
|
||||
Env env{*this};
|
||||
|
||||
Account A1 {"A1"};
|
||||
Account A2 {"A2"};
|
||||
env.fund (XRP (1000), A1, A2);
|
||||
Account A1{"A1"};
|
||||
Account A2{"A2"};
|
||||
env.fund(XRP(1000), A1, A2);
|
||||
env.close();
|
||||
|
||||
OpenView ov {*env.current()};
|
||||
test::StreamSink sink {beast::severities::kWarning};
|
||||
beast::Journal jlog {sink};
|
||||
ApplyContext ac {
|
||||
OpenView ov{*env.current()};
|
||||
test::StreamSink sink{beast::severities::kWarning};
|
||||
beast::Journal jlog{sink};
|
||||
ApplyContext ac{
|
||||
env.app(),
|
||||
ov,
|
||||
tx,
|
||||
tesSUCCESS,
|
||||
safe_cast<FeeUnit64>(env.current()->fees().units),
|
||||
tapNONE,
|
||||
jlog
|
||||
};
|
||||
jlog};
|
||||
|
||||
BEAST_EXPECT(precheck(A1, A2, ac));
|
||||
|
||||
// invoke check twice to cover tec and tef cases
|
||||
if (! BEAST_EXPECT(ters.size() == 2))
|
||||
if (!BEAST_EXPECT(ters.size() == 2))
|
||||
return;
|
||||
|
||||
TER terActual = tesSUCCESS;
|
||||
@@ -81,34 +80,35 @@ class Invariants_test : public beast::unit_test::suite
|
||||
terActual = ac.checkInvariants(terActual, fee);
|
||||
BEAST_EXPECT(terExpect == terActual);
|
||||
BEAST_EXPECT(
|
||||
boost::starts_with(sink.messages().str(), "Invariant failed:") ||
|
||||
boost::starts_with(sink.messages().str(),
|
||||
"Transaction caused an exception"));
|
||||
//uncomment if you want to log the invariant failure message
|
||||
//log << " --> " << sink.messages().str() << std::endl;
|
||||
boost::starts_with(
|
||||
sink.messages().str(), "Invariant failed:") ||
|
||||
boost::starts_with(
|
||||
sink.messages().str(), "Transaction caused an exception"));
|
||||
// uncomment if you want to log the invariant failure message
|
||||
// log << " --> " << sink.messages().str() << std::endl;
|
||||
for (auto const& m : expect_logs)
|
||||
{
|
||||
BEAST_EXPECT(sink.messages().str().find(m) != std::string::npos);
|
||||
BEAST_EXPECT(
|
||||
sink.messages().str().find(m) != std::string::npos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testXRPNotCreated ()
|
||||
testXRPNotCreated()
|
||||
{
|
||||
using namespace test::jtx;
|
||||
testcase << "XRP created";
|
||||
doInvariantCheck (
|
||||
{{ "XRP net change was positive: 500" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"XRP net change was positive: 500"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// put a single account in the view and "manufacture" some XRP
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto amt = sle->getFieldAmount (sfBalance);
|
||||
sle->setFieldAmount (sfBalance, amt + STAmount{500});
|
||||
ac.view().update (sle);
|
||||
auto amt = sle->getFieldAmount(sfBalance);
|
||||
sle->setFieldAmount(sfBalance, amt + STAmount{500});
|
||||
ac.view().update(sle);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -120,15 +120,14 @@ class Invariants_test : public beast::unit_test::suite
|
||||
testcase << "account root removed";
|
||||
|
||||
// An account was deleted, but not by an AccountDelete transaction.
|
||||
doInvariantCheck (
|
||||
{{ "an account root was deleted" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"an account root was deleted"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// remove an account from the view
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
ac.view().erase (sle);
|
||||
ac.view().erase(sle);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -137,29 +136,30 @@ class Invariants_test : public beast::unit_test::suite
|
||||
// Note that this is a case where a second invocation of the invariant
|
||||
// checker returns a tecINVARIANT_FAILED, not a tefINVARIANT_FAILED.
|
||||
// After a discussion with the team, we believe that's okay.
|
||||
doInvariantCheck (
|
||||
{{ "account deletion succeeded without deleting an account" }},
|
||||
[](Account const&, Account const&, ApplyContext& ac){return true;},
|
||||
XRPAmount{},
|
||||
STTx {ttACCOUNT_DELETE, [](STObject& tx){ }},
|
||||
{tecINVARIANT_FAILED, tecINVARIANT_FAILED});
|
||||
|
||||
// Successful AccountDelete that deleted more than one account.
|
||||
doInvariantCheck (
|
||||
{{ "account deletion succeeded but deleted multiple accounts" }},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac)
|
||||
{
|
||||
// remove two accounts from the view
|
||||
auto const sleA1 = ac.view().peek (keylet::account(A1.id()));
|
||||
auto const sleA2 = ac.view().peek (keylet::account(A2.id()));
|
||||
if(!sleA1 || !sleA2)
|
||||
return false;
|
||||
ac.view().erase (sleA1);
|
||||
ac.view().erase (sleA2);
|
||||
doInvariantCheck(
|
||||
{{"account deletion succeeded without deleting an account"}},
|
||||
[](Account const&, Account const&, ApplyContext& ac) {
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx {ttACCOUNT_DELETE, [](STObject& tx){ }});
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}},
|
||||
{tecINVARIANT_FAILED, tecINVARIANT_FAILED});
|
||||
|
||||
// Successful AccountDelete that deleted more than one account.
|
||||
doInvariantCheck(
|
||||
{{"account deletion succeeded but deleted multiple accounts"}},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
// remove two accounts from the view
|
||||
auto const sleA1 = ac.view().peek(keylet::account(A1.id()));
|
||||
auto const sleA2 = ac.view().peek(keylet::account(A2.id()));
|
||||
if (!sleA1 || !sleA2)
|
||||
return false;
|
||||
ac.view().erase(sleA1);
|
||||
ac.view().erase(sleA2);
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx{ttACCOUNT_DELETE, [](STObject& tx) {}});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -167,35 +167,33 @@ class Invariants_test : public beast::unit_test::suite
|
||||
{
|
||||
using namespace test::jtx;
|
||||
testcase << "ledger entry types don't match";
|
||||
doInvariantCheck (
|
||||
{{ "ledger entry type mismatch" },
|
||||
{ "XRP net change of -1000000000 doesn't match fee 0" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"ledger entry type mismatch"},
|
||||
{"XRP net change of -1000000000 doesn't match fee 0"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// replace an entry in the table with an SLE of a different type
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto sleNew = std::make_shared<SLE> (ltTICKET, sle->key());
|
||||
ac.rawView().rawReplace (sleNew);
|
||||
auto sleNew = std::make_shared<SLE>(ltTICKET, sle->key());
|
||||
ac.rawView().rawReplace(sleNew);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "invalid ledger entry type added" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"invalid ledger entry type added"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// add an entry in the table with an SLE of an invalid type
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
// make a dummy escrow ledger entry, then change the type to an
|
||||
// unsupported value so that the valid type invariant check
|
||||
// will fail.
|
||||
auto sleNew = std::make_shared<SLE> (
|
||||
auto sleNew = std::make_shared<SLE>(
|
||||
keylet::escrow(A1, (*sle)[sfSequence] + 2));
|
||||
sleNew->type_ = ltNICKNAME;
|
||||
ac.view().insert (sleNew);
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -205,15 +203,14 @@ class Invariants_test : public beast::unit_test::suite
|
||||
{
|
||||
using namespace test::jtx;
|
||||
testcase << "trust lines with XRP not allowed";
|
||||
doInvariantCheck (
|
||||
{{ "an XRP trust line was created" }},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"an XRP trust line was created"}},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
// create simple trust SLE with xrp currency
|
||||
auto index = getRippleStateIndex (A1, A2, xrpIssue().currency);
|
||||
auto const sleNew = std::make_shared<SLE>(
|
||||
ltRIPPLE_STATE, index);
|
||||
ac.view().insert (sleNew);
|
||||
auto index = getRippleStateIndex(A1, A2, xrpIssue().currency);
|
||||
auto const sleNew =
|
||||
std::make_shared<SLE>(ltRIPPLE_STATE, index);
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -224,50 +221,46 @@ class Invariants_test : public beast::unit_test::suite
|
||||
using namespace test::jtx;
|
||||
testcase << "XRP balance checks";
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "Cannot return non-native STAmount as XRPAmount" }},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac)
|
||||
{
|
||||
//non-native balance
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
doInvariantCheck(
|
||||
{{"Cannot return non-native STAmount as XRPAmount"}},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
// non-native balance
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
STAmount nonNative (A2["USD"](51));
|
||||
sle->setFieldAmount (sfBalance, nonNative);
|
||||
ac.view().update (sle);
|
||||
STAmount nonNative(A2["USD"](51));
|
||||
sle->setFieldAmount(sfBalance, nonNative);
|
||||
ac.view().update(sle);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "incorrect account XRP balance" },
|
||||
{ "XRP net change was positive: 99999999000000001" }},
|
||||
[this](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"incorrect account XRP balance"},
|
||||
{"XRP net change was positive: 99999999000000001"}},
|
||||
[this](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// balance exceeds genesis amount
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
// Use `drops(1)` to bypass a call to STAmount::canonicalize
|
||||
// with an invalid value
|
||||
sle->setFieldAmount (sfBalance,
|
||||
INITIAL_XRP + drops(1));
|
||||
sle->setFieldAmount(sfBalance, INITIAL_XRP + drops(1));
|
||||
BEAST_EXPECT(!sle->getFieldAmount(sfBalance).negative());
|
||||
ac.view().update (sle);
|
||||
ac.view().update(sle);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "incorrect account XRP balance" },
|
||||
{ "XRP net change of -1000000001 doesn't match fee 0" }},
|
||||
[this](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"incorrect account XRP balance"},
|
||||
{"XRP net change of -1000000001 doesn't match fee 0"}},
|
||||
[this](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// balance is negative
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
sle->setFieldAmount (sfBalance, STAmount{1, true});
|
||||
sle->setFieldAmount(sfBalance, STAmount{1, true});
|
||||
BEAST_EXPECT(sle->getFieldAmount(sfBalance).negative());
|
||||
ac.view().update (sle);
|
||||
ac.view().update(sle);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -279,89 +272,85 @@ class Invariants_test : public beast::unit_test::suite
|
||||
using namespace std::string_literals;
|
||||
testcase << "Transaction fee checks";
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "fee paid was negative: -1" },
|
||||
{ "XRP net change of 0 doesn't match fee -1" }},
|
||||
doInvariantCheck(
|
||||
{{"fee paid was negative: -1"},
|
||||
{"XRP net change of 0 doesn't match fee -1"}},
|
||||
[](Account const&, Account const&, ApplyContext&) { return true; },
|
||||
XRPAmount{-1});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "fee paid exceeds system limit: "s +
|
||||
to_string(INITIAL_XRP) },
|
||||
{ "XRP net change of 0 doesn't match fee "s +
|
||||
to_string(INITIAL_XRP) }},
|
||||
doInvariantCheck(
|
||||
{{"fee paid exceeds system limit: "s + to_string(INITIAL_XRP)},
|
||||
{"XRP net change of 0 doesn't match fee "s +
|
||||
to_string(INITIAL_XRP)}},
|
||||
[](Account const&, Account const&, ApplyContext&) { return true; },
|
||||
XRPAmount{INITIAL_XRP});
|
||||
|
||||
doInvariantCheck (
|
||||
doInvariantCheck(
|
||||
{{"fee paid is 20 exceeds fee specified in transaction."},
|
||||
{"XRP net change of 0 doesn't match fee 20"}},
|
||||
[](Account const&, Account const&, ApplyContext&) { return true; },
|
||||
XRPAmount{20},
|
||||
STTx { ttACCOUNT_SET,
|
||||
[](STObject& tx){tx.setFieldAmount(sfFee, XRPAmount{10});} });
|
||||
STTx{ttACCOUNT_SET, [](STObject& tx) {
|
||||
tx.setFieldAmount(sfFee, XRPAmount{10});
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
testNoBadOffers()
|
||||
{
|
||||
using namespace test::jtx;
|
||||
testcase << "no bad offers";
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "offer with a bad amount" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"offer with a bad amount"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// offer with negative takerpays
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto const offer_index =
|
||||
getOfferIndex (A1.id(), (*sle)[sfSequence]);
|
||||
auto sleNew = std::make_shared<SLE> (ltOFFER, offer_index);
|
||||
sleNew->setAccountID (sfAccount, A1.id());
|
||||
sleNew->setFieldU32 (sfSequence, (*sle)[sfSequence]);
|
||||
sleNew->setFieldAmount (sfTakerPays, XRP(-1));
|
||||
ac.view().insert (sleNew);
|
||||
getOfferIndex(A1.id(), (*sle)[sfSequence]);
|
||||
auto sleNew = std::make_shared<SLE>(ltOFFER, offer_index);
|
||||
sleNew->setAccountID(sfAccount, A1.id());
|
||||
sleNew->setFieldU32(sfSequence, (*sle)[sfSequence]);
|
||||
sleNew->setFieldAmount(sfTakerPays, XRP(-1));
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "offer with a bad amount" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"offer with a bad amount"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// offer with negative takergets
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto const offer_index =
|
||||
getOfferIndex (A1.id(), (*sle)[sfSequence]);
|
||||
auto sleNew = std::make_shared<SLE> (ltOFFER, offer_index);
|
||||
sleNew->setAccountID (sfAccount, A1.id());
|
||||
sleNew->setFieldU32 (sfSequence, (*sle)[sfSequence]);
|
||||
sleNew->setFieldAmount (sfTakerPays, A1["USD"](10));
|
||||
sleNew->setFieldAmount (sfTakerGets, XRP(-1));
|
||||
ac.view().insert (sleNew);
|
||||
getOfferIndex(A1.id(), (*sle)[sfSequence]);
|
||||
auto sleNew = std::make_shared<SLE>(ltOFFER, offer_index);
|
||||
sleNew->setAccountID(sfAccount, A1.id());
|
||||
sleNew->setFieldU32(sfSequence, (*sle)[sfSequence]);
|
||||
sleNew->setFieldAmount(sfTakerPays, A1["USD"](10));
|
||||
sleNew->setFieldAmount(sfTakerGets, XRP(-1));
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "offer with a bad amount" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"offer with a bad amount"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// offer XRP to XRP
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto const offer_index =
|
||||
getOfferIndex (A1.id(), (*sle)[sfSequence]);
|
||||
auto sleNew = std::make_shared<SLE> (ltOFFER, offer_index);
|
||||
sleNew->setAccountID (sfAccount, A1.id());
|
||||
sleNew->setFieldU32 (sfSequence, (*sle)[sfSequence]);
|
||||
sleNew->setFieldAmount (sfTakerPays, XRP(10));
|
||||
sleNew->setFieldAmount (sfTakerGets, XRP(11));
|
||||
ac.view().insert (sleNew);
|
||||
getOfferIndex(A1.id(), (*sle)[sfSequence]);
|
||||
auto sleNew = std::make_shared<SLE>(ltOFFER, offer_index);
|
||||
sleNew->setAccountID(sfAccount, A1.id());
|
||||
sleNew->setFieldU32(sfSequence, (*sle)[sfSequence]);
|
||||
sleNew->setFieldAmount(sfTakerPays, XRP(10));
|
||||
sleNew->setFieldAmount(sfTakerGets, XRP(11));
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -372,54 +361,50 @@ class Invariants_test : public beast::unit_test::suite
|
||||
using namespace test::jtx;
|
||||
testcase << "no zero escrow";
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "Cannot return non-native STAmount as XRPAmount" }},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"Cannot return non-native STAmount as XRPAmount"}},
|
||||
[](Account const& A1, Account const& A2, ApplyContext& ac) {
|
||||
// escrow with nonnative amount
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto sleNew = std::make_shared<SLE> (
|
||||
auto sleNew = std::make_shared<SLE>(
|
||||
keylet::escrow(A1, (*sle)[sfSequence] + 2));
|
||||
STAmount nonNative (A2["USD"](51));
|
||||
sleNew->setFieldAmount (sfAmount, nonNative);
|
||||
ac.view().insert (sleNew);
|
||||
STAmount nonNative(A2["USD"](51));
|
||||
sleNew->setFieldAmount(sfAmount, nonNative);
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "XRP net change of -1000000 doesn't match fee 0"},
|
||||
{ "escrow specifies invalid amount" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"XRP net change of -1000000 doesn't match fee 0"},
|
||||
{"escrow specifies invalid amount"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// escrow with negative amount
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto sleNew = std::make_shared<SLE> (
|
||||
auto sleNew = std::make_shared<SLE>(
|
||||
keylet::escrow(A1, (*sle)[sfSequence] + 2));
|
||||
sleNew->setFieldAmount (sfAmount, XRP(-1));
|
||||
ac.view().insert (sleNew);
|
||||
sleNew->setFieldAmount(sfAmount, XRP(-1));
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "XRP net change was positive: 100000000000000001" },
|
||||
{ "escrow specifies invalid amount" }},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"XRP net change was positive: 100000000000000001"},
|
||||
{"escrow specifies invalid amount"}},
|
||||
[](Account const& A1, Account const&, ApplyContext& ac) {
|
||||
// escrow with too-large amount
|
||||
auto const sle = ac.view().peek (keylet::account(A1.id()));
|
||||
if(! sle)
|
||||
auto const sle = ac.view().peek(keylet::account(A1.id()));
|
||||
if (!sle)
|
||||
return false;
|
||||
auto sleNew = std::make_shared<SLE> (
|
||||
auto sleNew = std::make_shared<SLE>(
|
||||
keylet::escrow(A1, (*sle)[sfSequence] + 2));
|
||||
// Use `drops(1)` to bypass a call to STAmount::canonicalize
|
||||
// with an invalid value
|
||||
sleNew->setFieldAmount (sfAmount,
|
||||
INITIAL_XRP + drops(1));
|
||||
ac.view().insert (sleNew);
|
||||
sleNew->setFieldAmount(sfAmount, INITIAL_XRP + drops(1));
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -430,71 +415,68 @@ class Invariants_test : public beast::unit_test::suite
|
||||
using namespace test::jtx;
|
||||
testcase << "valid new account root";
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "account root created by a non-Payment" }},
|
||||
[](Account const&, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"account root created by a non-Payment"}},
|
||||
[](Account const&, Account const&, ApplyContext& ac) {
|
||||
// Insert a new account root created by a non-payment into
|
||||
// the view.
|
||||
const Account A3 {"A3"};
|
||||
Keylet const acctKeylet = keylet::account (A3);
|
||||
const Account A3{"A3"};
|
||||
Keylet const acctKeylet = keylet::account(A3);
|
||||
auto const sleNew = std::make_shared<SLE>(acctKeylet);
|
||||
ac.view().insert (sleNew);
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "multiple accounts created in a single transaction" }},
|
||||
[](Account const&, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"multiple accounts created in a single transaction"}},
|
||||
[](Account const&, Account const&, ApplyContext& ac) {
|
||||
// Insert two new account roots into the view.
|
||||
{
|
||||
const Account A3 {"A3"};
|
||||
Keylet const acctKeylet = keylet::account (A3);
|
||||
const Account A3{"A3"};
|
||||
Keylet const acctKeylet = keylet::account(A3);
|
||||
auto const sleA3 = std::make_shared<SLE>(acctKeylet);
|
||||
ac.view().insert (sleA3);
|
||||
ac.view().insert(sleA3);
|
||||
}
|
||||
{
|
||||
const Account A4 {"A4"};
|
||||
Keylet const acctKeylet = keylet::account (A4);
|
||||
const Account A4{"A4"};
|
||||
Keylet const acctKeylet = keylet::account(A4);
|
||||
auto const sleA4 = std::make_shared<SLE>(acctKeylet);
|
||||
ac.view().insert (sleA4);
|
||||
ac.view().insert(sleA4);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
doInvariantCheck (
|
||||
{{ "account created with wrong starting sequence number" }},
|
||||
[](Account const&, Account const&, ApplyContext& ac)
|
||||
{
|
||||
doInvariantCheck(
|
||||
{{"account created with wrong starting sequence number"}},
|
||||
[](Account const&, Account const&, ApplyContext& ac) {
|
||||
// Insert a new account root with the wrong starting sequence.
|
||||
const Account A3 {"A3"};
|
||||
Keylet const acctKeylet = keylet::account (A3);
|
||||
const Account A3{"A3"};
|
||||
Keylet const acctKeylet = keylet::account(A3);
|
||||
auto const sleNew = std::make_shared<SLE>(acctKeylet);
|
||||
sleNew->setFieldU32 (sfSequence, ac.view().seq() + 1);
|
||||
ac.view().insert (sleNew);
|
||||
sleNew->setFieldU32(sfSequence, ac.view().seq() + 1);
|
||||
ac.view().insert(sleNew);
|
||||
return true;
|
||||
},
|
||||
XRPAmount{},
|
||||
STTx {ttPAYMENT, [](STObject& tx){ }});
|
||||
STTx{ttPAYMENT, [](STObject& tx) {}});
|
||||
}
|
||||
|
||||
public:
|
||||
void run () override
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testXRPNotCreated ();
|
||||
testAccountRootsNotRemoved ();
|
||||
testTypesMatch ();
|
||||
testNoXRPTrustLine ();
|
||||
testXRPBalanceCheck ();
|
||||
testXRPNotCreated();
|
||||
testAccountRootsNotRemoved();
|
||||
testTypesMatch();
|
||||
testNoXRPTrustLine();
|
||||
testXRPBalanceCheck();
|
||||
testTransactionFeeCheck();
|
||||
testNoBadOffers ();
|
||||
testNoZeroEscrow ();
|
||||
testValidNewAccountRoot ();
|
||||
testNoBadOffers();
|
||||
testNoZeroEscrow();
|
||||
testValidNewAccountRoot();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE (Invariants, ledger, ripple);
|
||||
|
||||
} // ripple
|
||||
BEAST_DEFINE_TESTSUITE(Invariants, ledger, ripple);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
Reference in New Issue
Block a user