Skip to content

Commit

Permalink
Added invariant check for deep freeze flag on a trust line
Browse files Browse the repository at this point in the history
  • Loading branch information
vvysokikh1 committed Jan 20, 2025
1 parent 8c40ab9 commit c5aa145
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/test/ledger/Invariants_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,52 @@ class Invariants_test : public beast::unit_test::suite
});
}

void
testNoDeepFreezeTrustLinesWithoutFreeze()
{
using namespace test::jtx;
testcase << "trust lines with deep freeze flag without freeze "
"not allowed";
doInvariantCheck(
{{"a trust line with deep freeze flag without normal freeze was "
"created"}},
[](Account const& A1, Account const& A2, ApplyContext& ac) {
auto const sleNew = std::make_shared<SLE>(
keylet::line(A1, A2, A1["USD"].currency));
std::uint32_t uFlags = 0u;
uFlags |= lsfLowDeepFreeze;
sleNew->setFieldU32(sfFlags, uFlags);
ac.view().insert(sleNew);
return true;
});

doInvariantCheck(
{{"a trust line with deep freeze flag without normal freeze was "
"created"}},
[](Account const& A1, Account const& A2, ApplyContext& ac) {
auto const sleNew = std::make_shared<SLE>(
keylet::line(A1, A2, A1["USD"].currency));
std::uint32_t uFlags = 0u;
uFlags |= lsfHighDeepFreeze;
sleNew->setFieldU32(sfFlags, uFlags);
ac.view().insert(sleNew);
return true;
});

doInvariantCheck(
{{"a trust line with deep freeze flag without normal freeze was "
"created"}},
[](Account const& A1, Account const& A2, ApplyContext& ac) {
auto const sleNew = std::make_shared<SLE>(
keylet::line(A1, A2, A1["USD"].currency));
std::uint32_t uFlags = 0u;
uFlags |= lsfLowDeepFreeze | lsfHighDeepFreeze;
sleNew->setFieldU32(sfFlags, uFlags);
ac.view().insert(sleNew);
return true;
});
}

void
testXRPBalanceCheck()
{
Expand Down Expand Up @@ -1061,6 +1107,7 @@ class Invariants_test : public beast::unit_test::suite
testAccountRootsDeletedClean();
testTypesMatch();
testNoXRPTrustLine();
testNoDeepFreezeTrustLinesWithoutFreeze();
testXRPBalanceCheck();
testTransactionFeeCheck();
testNoBadOffers();
Expand Down
38 changes: 38 additions & 0 deletions src/xrpld/app/tx/detail/InvariantCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,44 @@ NoXRPTrustLines::finalize(

//------------------------------------------------------------------------------

void
NoDeepFreezeTrustLinesWithoutFreeze::visitEntry(
bool,
std::shared_ptr<SLE const> const&,
std::shared_ptr<SLE const> const& after)
{
if (after && after->getType() == ltRIPPLE_STATE)
{
std::uint32_t const uFlags = after->getFieldU32(sfFlags);
bool const lowFreeze = uFlags & lsfLowFreeze;
bool const lowDeepFreeze = uFlags & lsfLowDeepFreeze;

bool const highFreeze = uFlags & lsfHighFreeze;
bool const highDeepFreeze = uFlags & lsfHighDeepFreeze;

deepFreezeWithoutFreeze_ =
(lowDeepFreeze && !lowFreeze) || (highDeepFreeze && !highFreeze);
}
}

bool
NoDeepFreezeTrustLinesWithoutFreeze::finalize(
STTx const&,
TER const,
XRPAmount const,
ReadView const&,
beast::Journal const& j)
{
if (!deepFreezeWithoutFreeze_)
return true;

JLOG(j.fatal()) << "Invariant failed: a trust line with deep freeze flag "
"without normal freeze was created";
return false;
}

//------------------------------------------------------------------------------

void
ValidNewAccountRoot::visitEntry(
bool,
Expand Down
28 changes: 28 additions & 0 deletions src/xrpld/app/tx/detail/InvariantCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,33 @@ class NoXRPTrustLines
beast::Journal const&);
};

/**
* @brief Invariant: Trust lines with deep freeze flag are not allowed if normal
* freeze flag is not set.
*
* We iterate all the trust lines created by this transaction and ensure
* that they don't have deep freeze flag set without normal freeze flag set.
*/
class NoDeepFreezeTrustLinesWithoutFreeze
{
bool deepFreezeWithoutFreeze_ = false;

public:
void
visitEntry(
bool,
std::shared_ptr<SLE const> const&,
std::shared_ptr<SLE const> const&);

bool
finalize(
STTx const&,
TER const,
XRPAmount const,
ReadView const&,
beast::Journal const&);
};

/**
* @brief Invariant: offers should be for non-negative amounts and must not
* be XRP to XRP.
Expand Down Expand Up @@ -518,6 +545,7 @@ using InvariantChecks = std::tuple<
XRPBalanceChecks,
XRPNotCreated,
NoXRPTrustLines,
NoDeepFreezeTrustLinesWithoutFreeze,
NoBadOffers,
NoZeroEscrow,
ValidNewAccountRoot,
Expand Down

0 comments on commit c5aa145

Please sign in to comment.