mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add invariant check tests (RIPD-1493):
Add coverage for a few invariant checks. Handle exception in invariant checking code so that an check that throws an exception will still properly return tef/tecINVARIANT_FAILED.
This commit is contained in:
committed by
Nik Bougalis
parent
36423a5f77
commit
c00341a97e
@@ -78,38 +78,49 @@ ApplyContext::checkInvariantsHelper(TER terResult, std::index_sequence<Is...>)
|
||||
if (view_->rules().enabled(featureEnforceInvariants))
|
||||
{
|
||||
auto checkers = getInvariantChecks();
|
||||
|
||||
// call each check's per-entry method
|
||||
visit (
|
||||
[&checkers](
|
||||
uint256 const& index,
|
||||
bool isDelete,
|
||||
std::shared_ptr <SLE const> const& before,
|
||||
std::shared_ptr <SLE const> const& after)
|
||||
{
|
||||
// Sean Parent for_each_argument trick
|
||||
(void)std::array<int, sizeof...(Is)>{
|
||||
{((std::get<Is>(checkers).
|
||||
try
|
||||
{
|
||||
// call each check's per-entry method
|
||||
visit (
|
||||
[&checkers](
|
||||
uint256 const& index,
|
||||
bool isDelete,
|
||||
std::shared_ptr <SLE const> const& before,
|
||||
std::shared_ptr <SLE const> const& after)
|
||||
{
|
||||
// Sean Parent for_each_argument trick
|
||||
(void)std::array<int, sizeof...(Is)>{
|
||||
{((std::get<Is>(checkers).
|
||||
visitEntry(index, isDelete, before, after)), 0)...}
|
||||
};
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
// Sean Parent for_each_argument trick
|
||||
// (a fold expression with `&&` would be really nice here when we move
|
||||
// to C++-17)
|
||||
std::array<bool, sizeof...(Is)> finalizers {{
|
||||
std::get<Is>(checkers).finalize(tx, terResult, journal)...}};
|
||||
// Sean Parent for_each_argument trick (a fold expression with `&&`
|
||||
// would be really nice here when we move to C++-17)
|
||||
std::array<bool, sizeof...(Is)> finalizers {{
|
||||
std::get<Is>(checkers).finalize(tx, terResult, journal)...}};
|
||||
|
||||
// call each check's finalizer to see that it passes
|
||||
if (! std::all_of( finalizers.cbegin(), finalizers.cend(),
|
||||
[](auto const& b) { return b; }))
|
||||
// call each check's finalizer to see that it passes
|
||||
if (! std::all_of( finalizers.cbegin(), finalizers.cend(),
|
||||
[](auto const& b) { return b; }))
|
||||
{
|
||||
terResult = (terResult == tecINVARIANT_FAILED) ?
|
||||
tefINVARIANT_FAILED :
|
||||
tecINVARIANT_FAILED ;
|
||||
JLOG(journal.fatal()) <<
|
||||
"Transaction has failed one or more invariants: " <<
|
||||
to_string(tx.getJson (0));
|
||||
}
|
||||
}
|
||||
catch(std::exception const& ex)
|
||||
{
|
||||
terResult = (terResult == tecINVARIANT_FAILED) ?
|
||||
tefINVARIANT_FAILED :
|
||||
tecINVARIANT_FAILED ;
|
||||
JLOG(journal.fatal()) <<
|
||||
"Transaction has failed one or more invariants: " <<
|
||||
to_string(tx.getJson (0));
|
||||
"Transaction caused an exception in an invariant" <<
|
||||
", ex: " << ex.what() <<
|
||||
", tx: " << to_string(tx.getJson (0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user