Add invariant checks for pseudo-account

This commit is contained in:
Bronek Kozicki
2025-03-28 17:04:38 +00:00
parent 696cf2b563
commit aff08b7543
4 changed files with 108 additions and 3 deletions

View File

@@ -59,6 +59,17 @@ private:
XRP(10'000), USD(10'000), IOUAmount{10'000'000, 0})); XRP(10'000), USD(10'000), IOUAmount{10'000'000, 0}));
}); });
// XRP to IOU, without featureSingleAssetVault
testAMM(
[&](AMM& ammAlice, Env&) {
BEAST_EXPECT(ammAlice.expectBalances(
XRP(10'000), USD(10'000), IOUAmount{10'000'000, 0}));
},
{},
0,
{},
{supported_amendments() - featureSingleAssetVault});
// IOU to IOU // IOU to IOU
testAMM( testAMM(
[&](AMM& ammAlice, Env&) { [&](AMM& ammAlice, Env&) {

View File

@@ -829,6 +829,74 @@ class Invariants_test : public beast::unit_test::suite
}, },
XRPAmount{}, XRPAmount{},
STTx{ttPAYMENT, [](STObject& tx) {}}); STTx{ttPAYMENT, [](STObject& tx) {}});
doInvariantCheck(
{{"pseudo-account created by a wrong transaction type"}},
[](Account const&, Account const&, ApplyContext& ac) {
Account const A3{"A3"};
Keylet const acctKeylet = keylet::account(A3);
auto const sleNew = std::make_shared<SLE>(acctKeylet);
sleNew->setFieldU32(sfSequence, 0);
sleNew->setFieldH256(sfAMMID, uint256(1));
sleNew->setFieldU32(
sfFlags,
lsfDisableMaster | lsfDefaultRipple | lsfDefaultRipple);
ac.view().insert(sleNew);
return true;
},
XRPAmount{},
STTx{ttPAYMENT, [](STObject& tx) {}});
doInvariantCheck(
{{"account created with wrong starting sequence number"}},
[](Account const&, Account const&, ApplyContext& ac) {
Account const A3{"A3"};
Keylet const acctKeylet = keylet::account(A3);
auto const sleNew = std::make_shared<SLE>(acctKeylet);
sleNew->setFieldU32(sfSequence, ac.view().seq());
sleNew->setFieldH256(sfAMMID, uint256(1));
sleNew->setFieldU32(
sfFlags,
lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth);
ac.view().insert(sleNew);
return true;
},
XRPAmount{},
STTx{ttAMM_CREATE, [](STObject& tx) {}});
doInvariantCheck(
{{"pseudo-account created with wrong flags"}},
[](Account const&, Account const&, ApplyContext& ac) {
Account const A3{"A3"};
Keylet const acctKeylet = keylet::account(A3);
auto const sleNew = std::make_shared<SLE>(acctKeylet);
sleNew->setFieldU32(sfSequence, 0);
sleNew->setFieldH256(sfAMMID, uint256(1));
sleNew->setFieldU32(
sfFlags, lsfDisableMaster | lsfDefaultRipple);
ac.view().insert(sleNew);
return true;
},
XRPAmount{},
STTx{ttVAULT_CREATE, [](STObject& tx) {}});
doInvariantCheck(
{{"pseudo-account created with wrong flags"}},
[](Account const&, Account const&, ApplyContext& ac) {
Account const A3{"A3"};
Keylet const acctKeylet = keylet::account(A3);
auto const sleNew = std::make_shared<SLE>(acctKeylet);
sleNew->setFieldU32(sfSequence, 0);
sleNew->setFieldH256(sfAMMID, uint256(1));
sleNew->setFieldU32(
sfFlags,
lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth |
lsfRequireDestTag);
ac.view().insert(sleNew);
return true;
},
XRPAmount{},
STTx{ttAMM_CREATE, [](STObject& tx) {}});
} }
void void

View File

@@ -886,6 +886,7 @@ ValidNewAccountRoot::visitEntry(
accountSeq_ = (*after)[sfSequence]; accountSeq_ = (*after)[sfSequence];
pseudoAccount_ = pseudoAccount_ =
after->isFieldPresent(sfAMMID) || after->isFieldPresent(sfVaultID); after->isFieldPresent(sfAMMID) || after->isFieldPresent(sfVaultID);
flags_ = after->getFlags();
} }
} }
@@ -914,9 +915,19 @@ ValidNewAccountRoot::finalize(
tx.getTxnType() == ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION) && tx.getTxnType() == ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION) &&
result == tesSUCCESS) result == tesSUCCESS)
{ {
std::uint32_t const startingSeq = // bool const pseudoAccount =
(pseudoAccount_ && (pseudoAccount_ && view.rules().enabled(featureSingleAssetVault));
view.rules().enabled(featureSingleAssetVault)) //
if (pseudoAccount && tx.getTxnType() != ttAMM_CREATE &&
tx.getTxnType() != ttVAULT_CREATE)
{
JLOG(j.fatal()) << "Invariant failed: pseudo-account created by a "
"wrong transaction type";
return false;
}
std::uint32_t const startingSeq = //
pseudoAccount //
? 0 // ? 0 //
: view.rules().enabled(featureDeletableAccounts) // : view.rules().enabled(featureDeletableAccounts) //
? view.seq() // ? view.seq() //
@@ -928,6 +939,20 @@ ValidNewAccountRoot::finalize(
"wrong starting sequence number"; "wrong starting sequence number";
return false; return false;
} }
if (pseudoAccount)
{
std::uint32_t const expected =
(lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth);
if (flags_ != expected)
{
JLOG(j.fatal())
<< "Invariant failed: pseudo-account created with "
"wrong flags";
return false;
}
}
return true; return true;
} }

View File

@@ -439,6 +439,7 @@ class ValidNewAccountRoot
std::uint32_t accountsCreated_ = 0; std::uint32_t accountsCreated_ = 0;
std::uint32_t accountSeq_ = 0; std::uint32_t accountSeq_ = 0;
bool pseudoAccount_ = false; bool pseudoAccount_ = false;
std::uint32_t flags_ = 0;
public: public:
void void