mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-03 00:36:48 +00:00
Add specific checks for COA and OA (#7275)
This commit is contained in:
@@ -1381,7 +1381,8 @@ class ConfidentialTransfer_test : public beast::unit_test::Suite
|
||||
Env env{*this, features};
|
||||
Account const alice("alice");
|
||||
Account const bob("bob");
|
||||
MPTTester mptAlice(env, alice, {.holders = {bob}});
|
||||
Account const carol("carol");
|
||||
MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
|
||||
|
||||
mptAlice.create({
|
||||
.ownerCount = 1,
|
||||
@@ -1395,6 +1396,7 @@ class ConfidentialTransfer_test : public beast::unit_test::Suite
|
||||
|
||||
mptAlice.generateKeyPair(alice);
|
||||
mptAlice.generateKeyPair(bob);
|
||||
mptAlice.generateKeyPair(carol);
|
||||
|
||||
mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice)});
|
||||
|
||||
@@ -1413,6 +1415,26 @@ class ConfidentialTransfer_test : public beast::unit_test::Suite
|
||||
.issuerEncryptedAmt = getTrivialCiphertext(),
|
||||
.err = tecBAD_PROOF,
|
||||
});
|
||||
|
||||
std::uint64_t const amount = 10;
|
||||
Buffer const blindingFactor = generateBlindingFactor();
|
||||
Buffer const holderCiphertext = mptAlice.encryptAmount(bob, amount, blindingFactor);
|
||||
|
||||
// Holder ciphertext is valid for the amount and
|
||||
// blinding factor, but the issuer ciphertext is encrypted under a
|
||||
// different public key than the registered issuer key.
|
||||
Buffer const wrongIssuerCiphertext =
|
||||
mptAlice.encryptAmount(carol, amount, blindingFactor);
|
||||
|
||||
mptAlice.convert({
|
||||
.account = bob,
|
||||
.amt = amount,
|
||||
.holderPubKey = mptAlice.getPubKey(bob),
|
||||
.holderEncryptedAmt = holderCiphertext,
|
||||
.issuerEncryptedAmt = wrongIssuerCiphertext,
|
||||
.blindingFactor = blindingFactor,
|
||||
.err = tecBAD_PROOF,
|
||||
});
|
||||
}
|
||||
|
||||
// trying to convert more than what bob has
|
||||
@@ -4664,7 +4686,10 @@ class ConfidentialTransfer_test : public beast::unit_test::Suite
|
||||
.amt = 110,
|
||||
});
|
||||
BEAST_EXPECT(mptAlice.getBalance(bob) == preBobPublicBalance);
|
||||
BEAST_EXPECT(mptAlice.getIssuanceOutstandingBalance() == preOutstandingAmount - 110);
|
||||
auto const postOutstandingAmount = mptAlice.getIssuanceOutstandingBalance();
|
||||
BEAST_EXPECT(
|
||||
preOutstandingAmount && postOutstandingAmount &&
|
||||
*postOutstandingAmount == *preOutstandingAmount - 110);
|
||||
BEAST_EXPECT(
|
||||
mptAlice.getIssuanceConfidentialBalance() == preConfidentialOutstandingAmount - 110);
|
||||
BEAST_EXPECT(!env.le(keylet::mptoken(mptAlice.issuanceID(), alice.id())));
|
||||
@@ -8971,7 +8996,8 @@ class ConfidentialTransfer_test : public beast::unit_test::Suite
|
||||
env.require(MptBalance(mpt, dave, 0));
|
||||
BEAST_EXPECT(mpt.getDecryptedBalance(dave, MPTTester::HolderEncryptedSpending) == 0);
|
||||
BEAST_EXPECT(mpt.getDecryptedBalance(dave, MPTTester::HolderEncryptedInbox) == 0);
|
||||
BEAST_EXPECT(mpt.getIssuanceOutstandingBalance() == 250);
|
||||
auto const outstandingBalance = mpt.getIssuanceOutstandingBalance();
|
||||
BEAST_EXPECT(outstandingBalance && *outstandingBalance == 250);
|
||||
BEAST_EXPECT(mpt.getIssuanceConfidentialBalance() == 175);
|
||||
}
|
||||
|
||||
@@ -10628,6 +10654,7 @@ class ConfidentialTransfer_test : public beast::unit_test::Suite
|
||||
testSendPreflight(features);
|
||||
testSendPreclaim(features);
|
||||
testSendRangeProof(features);
|
||||
|
||||
// testSendZeroAmount(features);
|
||||
testSendDepositPreauth(features);
|
||||
testSendCredentialValidation(features);
|
||||
|
||||
@@ -1183,14 +1183,30 @@ MPTTester::convert(MPTConvert const& arg)
|
||||
Throw<std::runtime_error>("Failed to get Pre-convert balance");
|
||||
}
|
||||
|
||||
auto const prevOutstanding = getIssuanceOutstandingBalance();
|
||||
|
||||
if (submit(arg, jv) == tesSUCCESS)
|
||||
{
|
||||
auto const postConfidentialOutstanding = getIssuanceConfidentialBalance();
|
||||
auto const postOutstanding = getIssuanceOutstandingBalance();
|
||||
env_.require(MptBalance(*this, *arg.account, holderAmt - *arg.amt));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return prevOutstanding && postOutstanding && *prevOutstanding == *postOutstanding;
|
||||
}));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return prevConfidentialOutstanding + *arg.amt == postConfidentialOutstanding;
|
||||
}));
|
||||
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return getEncryptedBalance(*arg.account, HolderEncryptedInbox).has_value();
|
||||
}));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return getEncryptedBalance(*arg.account, HolderEncryptedSpending).has_value();
|
||||
}));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return getEncryptedBalance(*arg.account, IssuerEncryptedBalance).has_value();
|
||||
}));
|
||||
|
||||
auto const postInboxBalance = getDecryptedBalance(*arg.account, HolderEncryptedInbox);
|
||||
auto const postIssuerBalance = getDecryptedBalance(*arg.account, IssuerEncryptedBalance);
|
||||
auto const postSpendingBalance = getDecryptedBalance(*arg.account, HolderEncryptedSpending);
|
||||
@@ -1206,6 +1222,10 @@ MPTTester::convert(MPTConvert const& arg)
|
||||
if (!postAuditorBalance)
|
||||
Throw<std::runtime_error>("Failed to get post-convert auditor balance");
|
||||
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return getEncryptedBalance(*arg.account, AuditorEncryptedBalance).has_value();
|
||||
}));
|
||||
|
||||
// auditor's encrypted balance is updated correctly
|
||||
env_.require(RequireAny(
|
||||
[&]() -> bool { return *prevAuditorBalance + *arg.amt == *postAuditorBalance; }));
|
||||
@@ -1559,7 +1579,7 @@ MPTTester::send(MPTConfidentialSend const& arg)
|
||||
env_.require(MptBalance(*this, *arg.dest, destPubAmt));
|
||||
|
||||
// OA and COA unchanged
|
||||
env_.require(RequireAny([&]() -> bool { return prevOA == postOA; }));
|
||||
env_.require(RequireAny([&]() -> bool { return prevOA && postOA && *prevOA == *postOA; }));
|
||||
env_.require(RequireAny([&]() -> bool { return prevCOA == postCOA; }));
|
||||
|
||||
// Verify sender changes
|
||||
@@ -1933,8 +1953,9 @@ MPTTester::confidentialClaw(MPTConfidentialClawback const& arg)
|
||||
// Verify COA and OA are reduced correctly
|
||||
env_.require(RequireAny(
|
||||
[&]() -> bool { return prevCOA >= *arg.amt && postCOA == prevCOA - *arg.amt; }));
|
||||
env_.require(RequireAny(
|
||||
[&]() -> bool { return prevOA >= *arg.amt && postOA == prevOA - *arg.amt; }));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return prevOA && postOA && *prevOA >= *arg.amt && *postOA == *prevOA - *arg.amt;
|
||||
}));
|
||||
|
||||
// Verify holder's confidential balances are zeroed out
|
||||
env_.require(RequireAny(
|
||||
@@ -2109,6 +2130,9 @@ MPTTester::mergeInbox(MPTMergeInbox const& arg)
|
||||
}
|
||||
|
||||
jv[sfTransactionType] = jss::ConfidentialMPTMergeInbox;
|
||||
auto const holderPubAmt = getBalance(*arg.account);
|
||||
auto const prevCOA = getIssuanceConfidentialBalance();
|
||||
auto const prevOA = getIssuanceOutstandingBalance();
|
||||
auto const prevInboxBalance = getDecryptedBalance(*arg.account, HolderEncryptedInbox);
|
||||
auto const prevSpendingBalance = getDecryptedBalance(*arg.account, HolderEncryptedSpending);
|
||||
auto const prevIssuerBalance = getDecryptedBalance(*arg.account, IssuerEncryptedBalance);
|
||||
@@ -2118,6 +2142,8 @@ MPTTester::mergeInbox(MPTMergeInbox const& arg)
|
||||
|
||||
if (submit(arg, jv) == tesSUCCESS)
|
||||
{
|
||||
auto const postCOA = getIssuanceConfidentialBalance();
|
||||
auto const postOA = getIssuanceOutstandingBalance();
|
||||
auto const postInboxBalance = getDecryptedBalance(*arg.account, HolderEncryptedInbox);
|
||||
auto const postSpendingBalance = getDecryptedBalance(*arg.account, HolderEncryptedSpending);
|
||||
auto const postIssuerBalance = getDecryptedBalance(*arg.account, IssuerEncryptedBalance);
|
||||
@@ -2125,6 +2151,10 @@ MPTTester::mergeInbox(MPTMergeInbox const& arg)
|
||||
if (!postInboxBalance || !postSpendingBalance || !postIssuerBalance)
|
||||
Throw<std::runtime_error>("Failed to get post-mergeInbox balances");
|
||||
|
||||
env_.require(MptBalance(*this, *arg.account, holderPubAmt));
|
||||
env_.require(RequireAny([&]() -> bool { return prevOA && postOA && *prevOA == *postOA; }));
|
||||
env_.require(RequireAny([&]() -> bool { return prevCOA == postCOA; }));
|
||||
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return *postSpendingBalance == *prevInboxBalance + *prevSpendingBalance &&
|
||||
*postInboxBalance == 0;
|
||||
@@ -2139,16 +2169,16 @@ MPTTester::mergeInbox(MPTMergeInbox const& arg)
|
||||
}
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
std::optional<std::int64_t>
|
||||
MPTTester::getIssuanceOutstandingBalance() const
|
||||
{
|
||||
if (!id_)
|
||||
Throw<std::runtime_error>("Issuance ID does not exist");
|
||||
return std::nullopt;
|
||||
|
||||
auto const sle = env_.current()->read(keylet::mptIssuance(*id_));
|
||||
|
||||
if (!sle || !sle->isFieldPresent(sfOutstandingAmount))
|
||||
Throw<std::runtime_error>("Issuance object does not contain outstanding amount");
|
||||
if (!sle)
|
||||
return std::nullopt;
|
||||
|
||||
return (*sle)[sfOutstandingAmount];
|
||||
}
|
||||
@@ -2276,10 +2306,16 @@ MPTTester::convertBack(MPTConvertBack const& arg)
|
||||
Throw<std::runtime_error>("Failed to get Pre-convertBack balance");
|
||||
}
|
||||
|
||||
auto const prevOutstanding = getIssuanceOutstandingBalance();
|
||||
|
||||
if (submit(arg, jv) == tesSUCCESS)
|
||||
{
|
||||
auto const postConfidentialOutstanding = getIssuanceConfidentialBalance();
|
||||
auto const postOutstanding = getIssuanceOutstandingBalance();
|
||||
env_.require(MptBalance(*this, *arg.account, holderAmt + *arg.amt));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return prevOutstanding && postOutstanding && *prevOutstanding == *postOutstanding;
|
||||
}));
|
||||
env_.require(RequireAny([&]() -> bool {
|
||||
return prevConfidentialOutstanding - *arg.amt == postConfidentialOutstanding;
|
||||
}));
|
||||
|
||||
@@ -554,7 +554,7 @@ public:
|
||||
[[nodiscard]] std::optional<uint64_t>
|
||||
getDecryptedBalance(Account const& account, EncryptedBalanceType balanceType) const;
|
||||
|
||||
[[nodiscard]] std::int64_t
|
||||
[[nodiscard]] std::optional<std::int64_t>
|
||||
getIssuanceOutstandingBalance() const;
|
||||
|
||||
[[nodiscard]] std::optional<Buffer>
|
||||
|
||||
Reference in New Issue
Block a user