diff --git a/include/xrpl/protocol/detail/ledger_entries.macro b/include/xrpl/protocol/detail/ledger_entries.macro index c3a34fb246..8601be1538 100644 --- a/include/xrpl/protocol/detail/ledger_entries.macro +++ b/include/xrpl/protocol/detail/ledger_entries.macro @@ -475,10 +475,10 @@ LEDGER_ENTRY(ltVAULT, 0x0083, Vault, vault, ({ {sfAccount, soeREQUIRED}, {sfData, soeOPTIONAL}, {sfAsset, soeREQUIRED}, - {sfAssetTotal, soeDEFAULT}, - {sfAssetAvailable, soeDEFAULT}, + {sfAssetTotal, soeREQUIRED}, + {sfAssetAvailable, soeREQUIRED}, {sfAssetMaximum, soeDEFAULT}, - {sfLossUnrealized, soeDEFAULT}, + {sfLossUnrealized, soeREQUIRED}, {sfMPTokenIssuanceID, soeREQUIRED}, // sfShare {sfWithdrawalPolicy, soeREQUIRED}, // no ShareTotal ever (use MPTIssuance.sfOutstandingAmount) diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index 25b7243862..b66d1d8ded 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -780,7 +781,7 @@ class Vault_test : public beast::unit_test::suite } void - testTransactionFees() + testWithIOU() { testcase("IOU fees"); Env env{*this}; @@ -802,16 +803,41 @@ class Vault_test : public beast::unit_test::suite env(tx); env.close(); - AccountID const vaultAccount = [&env, key = keylet.key]() { + auto const [vaultAccount, ownerAccount, mptID] = // + [&env, &owner, key = keylet.key, this]() // + -> std::tuple { Json::Value jvParams; jvParams[jss::ledger_index] = jss::validated; jvParams[jss::vault] = strHex(key); - auto const jvVault = - env.rpc("json", "ledger_entry", to_string(jvParams)); - return parseBase58( - jvVault[jss::result][jss::node][jss::Account].asString()) - .value(); + auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams)); + + // Vault pseudo-account + auto const vAcct = + parseBase58( + jvVault[jss::result][jss::node][jss::Account].asString()) + .value(); + + // Owner account + auto const oAcct = + parseBase58( + jvVault[jss::result][jss::node][jss::Owner].asString()) + .value(); + BEAST_EXPECT(oAcct == owner.id()); + + // MPTID of the vault shares + auto const strMpt = jvVault[jss::result][jss::node][jss::Share] + [jss::mpt_issuance_id] + .asString(); + uint192 mpt; + BEAST_EXPECT(mpt.parseHex(strMpt)); + + return {vAcct, oAcct, mpt}; }(); + + BEAST_EXPECT(makeMptID(1, vaultAccount) == mptID); + BEAST_EXPECT( + keylet::vault(ownerAccount, env.seq(owner) - 1).key == keylet.key); + auto const vaultBalance = [&]() -> PrettyAmount { auto const sle = env.le(keylet::line(vaultAccount, issue)); BEAST_EXPECT(sle != nullptr); @@ -866,8 +892,8 @@ public: testCreateFailIOU(); testCreateFailMPT(); testWithMPT(); + testWithIOU(); testWithDomainCheck(); - testTransactionFees(); } }; diff --git a/src/xrpld/app/tx/detail/VaultCreate.cpp b/src/xrpld/app/tx/detail/VaultCreate.cpp index aeb68c6ea3..a5274dfa33 100644 --- a/src/xrpld/app/tx/detail/VaultCreate.cpp +++ b/src/xrpld/app/tx/detail/VaultCreate.cpp @@ -187,6 +187,9 @@ VaultCreate::doApply() vault->at(sfOwner) = ownerId; vault->at(sfAccount) = pseudoId; vault->at(sfAsset) = tx[sfAsset]; + vault->at(sfAssetTotal) = Number(0); + vault->at(sfAssetAvailable) = Number(0); + vault->at(sfLossUnrealized) = Number(0); // Leave default values for AssetTotal and AssetAvailable, both zero. if (auto value = tx[~sfAssetMaximum]) vault->at(sfAssetMaximum) = *value;