mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
ConvertBack preflight tests (#5991)
This commit is contained in:
@@ -28,6 +28,15 @@ namespace ripple {
|
||||
|
||||
class ConfidentialTransfer_test : public beast::unit_test::suite
|
||||
{
|
||||
// A 66-byte array of random unsigned char values
|
||||
constexpr static unsigned char badCiphertext[ecGamalEncryptedTotalLength] =
|
||||
{0x3E, 0x9A, 0x0F, 0x7C, 0x51, 0xD8, 0x22, 0x8B, 0x6E, 0x14, 0xC9,
|
||||
0xF5, 0x4D, 0x6A, 0x03, 0x81, 0x77, 0x2B, 0xEE, 0x9F, 0x10, 0xC2,
|
||||
0x57, 0x3D, 0x88, 0x65, 0x0C, 0xAB, 0xF1, 0x4E, 0x19, 0x96, 0x2A,
|
||||
0x73, 0xDC, 0x44, 0xB8, 0x5F, 0x01, 0xEA, 0x87, 0x36, 0x60, 0xCE,
|
||||
0x92, 0x25, 0x7D, 0x5B, 0xC0, 0x1E, 0x48, 0xF9, 0x84, 0x33, 0x67,
|
||||
0xAD, 0x0B, 0xE3, 0x91, 0x50, 0xDA, 0x2F, 0x75, 0xC6, 0xBD, 0x42};
|
||||
|
||||
void
|
||||
testConvert(FeatureBitset features)
|
||||
{
|
||||
@@ -134,7 +143,7 @@ class ConfidentialTransfer_test : public beast::unit_test::suite
|
||||
.proof = "123",
|
||||
.holderPubKey = mptAlice.getPubKey(bob),
|
||||
.holderEncryptedAmt = Buffer{},
|
||||
.err = temMALFORMED});
|
||||
.err = temBAD_CIPHERTEXT});
|
||||
|
||||
mptAlice.convert(
|
||||
{.account = bob,
|
||||
@@ -142,23 +151,14 @@ class ConfidentialTransfer_test : public beast::unit_test::suite
|
||||
.proof = "123",
|
||||
.holderPubKey = mptAlice.getPubKey(bob),
|
||||
.issuerEncryptedAmt = Buffer{},
|
||||
.err = temMALFORMED});
|
||||
.err = temBAD_CIPHERTEXT});
|
||||
|
||||
mptAlice.convert(
|
||||
{.account = bob,
|
||||
.amt = maxMPTokenAmount + 1,
|
||||
.proof = "123",
|
||||
.holderPubKey = mptAlice.getPubKey(bob),
|
||||
.err = temMALFORMED});
|
||||
|
||||
// A 66-byte array of random unsigned char values
|
||||
unsigned char badCiphertext[ecGamalEncryptedTotalLength] = {
|
||||
0x3E, 0x9A, 0x0F, 0x7C, 0x51, 0xD8, 0x22, 0x8B, 0x6E, 0x14, 0xC9,
|
||||
0xF5, 0x4D, 0x6A, 0x03, 0x81, 0x77, 0x2B, 0xEE, 0x9F, 0x10, 0xC2,
|
||||
0x57, 0x3D, 0x88, 0x65, 0x0C, 0xAB, 0xF1, 0x4E, 0x19, 0x96, 0x2A,
|
||||
0x73, 0xDC, 0x44, 0xB8, 0x5F, 0x01, 0xEA, 0x87, 0x36, 0x60, 0xCE,
|
||||
0x92, 0x25, 0x7D, 0x5B, 0xC0, 0x1E, 0x48, 0xF9, 0x84, 0x33, 0x67,
|
||||
0xAD, 0x0B, 0xE3, 0x91, 0x50, 0xDA, 0x2F, 0x75, 0xC6, 0xBD, 0x42};
|
||||
.err = temBAD_AMOUNT});
|
||||
|
||||
mptAlice.convert(
|
||||
{.account = bob,
|
||||
@@ -1410,6 +1410,122 @@ class ConfidentialTransfer_test : public beast::unit_test::suite
|
||||
// });
|
||||
}
|
||||
|
||||
void
|
||||
testConvertBackPreflight(FeatureBitset features)
|
||||
{
|
||||
testcase("Convert back preflight");
|
||||
using namespace test::jtx;
|
||||
|
||||
{
|
||||
Env env{*this, features - featureConfidentialTransfer};
|
||||
Account const alice("alice");
|
||||
Account const bob("bob");
|
||||
MPTTester mptAlice(env, alice, {.holders = {bob}});
|
||||
|
||||
mptAlice.create(
|
||||
{.ownerCount = 1,
|
||||
.holderCount = 0,
|
||||
.flags = tfMPTCanTransfer | tfMPTCanLock});
|
||||
|
||||
mptAlice.authorize({.account = bob});
|
||||
env.close();
|
||||
mptAlice.pay(alice, bob, 100);
|
||||
env.close();
|
||||
|
||||
mptAlice.generateKeyPair(alice);
|
||||
mptAlice.generateKeyPair(bob);
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = 30,
|
||||
.proof = "123",
|
||||
.err = temDISABLED});
|
||||
}
|
||||
|
||||
{
|
||||
Env env{*this, features};
|
||||
Account const alice("alice");
|
||||
Account const bob("bob");
|
||||
MPTTester mptAlice(env, alice, {.holders = {bob}});
|
||||
|
||||
mptAlice.create(
|
||||
{.ownerCount = 1,
|
||||
.holderCount = 0,
|
||||
.flags = tfMPTCanTransfer | tfMPTCanLock});
|
||||
|
||||
mptAlice.authorize({.account = bob});
|
||||
env.close();
|
||||
mptAlice.pay(alice, bob, 100);
|
||||
env.close();
|
||||
|
||||
mptAlice.generateKeyPair(alice);
|
||||
|
||||
mptAlice.set(
|
||||
{.account = alice, .pubKey = mptAlice.getPubKey(alice)});
|
||||
|
||||
mptAlice.generateKeyPair(bob);
|
||||
|
||||
mptAlice.convert({
|
||||
.account = bob,
|
||||
.amt = 40,
|
||||
.proof = "123",
|
||||
.holderPubKey = mptAlice.getPubKey(bob),
|
||||
});
|
||||
|
||||
mptAlice.mergeInbox({
|
||||
.account = bob,
|
||||
});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = alice,
|
||||
.amt = 30,
|
||||
.proof = "123",
|
||||
.err = temMALFORMED});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = 0,
|
||||
.proof = "123",
|
||||
.err = temBAD_AMOUNT});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = maxMPTokenAmount + 1,
|
||||
.proof = "123",
|
||||
.err = temBAD_AMOUNT});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = 30,
|
||||
.proof = "123",
|
||||
.holderEncryptedAmt = Buffer{},
|
||||
.err = temBAD_CIPHERTEXT});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = 30,
|
||||
.proof = "123",
|
||||
.issuerEncryptedAmt = Buffer{},
|
||||
.err = temBAD_CIPHERTEXT});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = 30,
|
||||
.proof = "123",
|
||||
.holderEncryptedAmt =
|
||||
Buffer{badCiphertext, ecGamalEncryptedTotalLength},
|
||||
.err = temBAD_CIPHERTEXT});
|
||||
|
||||
mptAlice.convertBack(
|
||||
{.account = bob,
|
||||
.amt = 30,
|
||||
.proof = "123",
|
||||
.issuerEncryptedAmt =
|
||||
Buffer{badCiphertext, ecGamalEncryptedTotalLength},
|
||||
.err = temBAD_CIPHERTEXT});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testWithFeats(FeatureBitset features)
|
||||
{
|
||||
@@ -1431,6 +1547,7 @@ class ConfidentialTransfer_test : public beast::unit_test::suite
|
||||
testDelete(features);
|
||||
|
||||
testConvertBack(features);
|
||||
testConvertBackPreflight(features);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -945,23 +945,33 @@ MPTTester::mergeInbox(MPTMergeInbox const& arg)
|
||||
jv[sfMPTokenIssuanceID] = to_string(*id_);
|
||||
}
|
||||
jv[sfTransactionType] = jss::ConfidentialMergeInbox;
|
||||
uint64_t preInboxBalance =
|
||||
uint64_t prevInboxBalance =
|
||||
getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_INBOX);
|
||||
uint64_t prevSpendingBalance =
|
||||
getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING);
|
||||
|
||||
uint64_t prevIssuerBalance =
|
||||
getDecryptedBalance(*arg.account, ISSUER_ENCRYPTED_BALANCE);
|
||||
if (submit(arg, jv) == tesSUCCESS)
|
||||
{
|
||||
uint64_t postInboxBalance =
|
||||
getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_INBOX);
|
||||
uint64_t postSpendingBalance =
|
||||
getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING);
|
||||
uint64_t postIssuerBalance =
|
||||
getDecryptedBalance(*arg.account, ISSUER_ENCRYPTED_BALANCE);
|
||||
|
||||
env_.require(requireAny([&]() -> bool {
|
||||
return postSpendingBalance ==
|
||||
preInboxBalance + prevSpendingBalance &&
|
||||
prevInboxBalance + prevSpendingBalance &&
|
||||
postInboxBalance == 0;
|
||||
}));
|
||||
|
||||
env_.require(requireAny(
|
||||
[&]() -> bool { return prevIssuerBalance == postIssuerBalance; }));
|
||||
|
||||
env_.require(requireAny([&]() -> bool {
|
||||
return postSpendingBalance + postInboxBalance == postIssuerBalance;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ ConfidentialConvert::preflight(PreflightContext const& ctx)
|
||||
if (ctx.tx[sfHolderEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength ||
|
||||
ctx.tx[sfIssuerEncryptedAmount].length() != ecGamalEncryptedTotalLength)
|
||||
return temMALFORMED;
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
if (ctx.tx[sfMPTAmount] > maxMPTokenAmount)
|
||||
return temMALFORMED;
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (!isValidCiphertext(ctx.tx[sfHolderEncryptedAmount]) ||
|
||||
!isValidCiphertext(ctx.tx[sfIssuerEncryptedAmount]))
|
||||
|
||||
@@ -42,10 +42,10 @@ ConfidentialConvertBack::preflight(PreflightContext const& ctx)
|
||||
if (ctx.tx[sfHolderEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength ||
|
||||
ctx.tx[sfIssuerEncryptedAmount].length() != ecGamalEncryptedTotalLength)
|
||||
return temMALFORMED;
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
if (ctx.tx[sfMPTAmount] == 0 || ctx.tx[sfMPTAmount] > maxMPTokenAmount)
|
||||
return temMALFORMED;
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (!isValidCiphertext(ctx.tx[sfHolderEncryptedAmount]) ||
|
||||
!isValidCiphertext(ctx.tx[sfIssuerEncryptedAmount]))
|
||||
|
||||
Reference in New Issue
Block a user