From 6885af1ddc1947f2abd15d94e76b33b248adea20 Mon Sep 17 00:00:00 2001 From: tequ Date: Thu, 5 Mar 2026 19:19:42 +0900 Subject: [PATCH] fix: typo `SignersListSet` --- src/test/app/SetHookTSH_test.cpp | 2027 ++++-------------------------- 1 file changed, 231 insertions(+), 1796 deletions(-) diff --git a/src/test/app/SetHookTSH_test.cpp b/src/test/app/SetHookTSH_test.cpp index 218c0ffab2..223a200b8d 100644 --- a/src/test/app/SetHookTSH_test.cpp +++ b/src/test/app/SetHookTSH_test.cpp @@ -21,19 +21,14 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include -#include #include -#include -#include #include #include @@ -740,7 +735,15 @@ private: { auto const executions = meta[sfHookExecutions.jsonName]; auto const execution = executions[0u][sfHookExecution.jsonName]; - BEAST_EXPECT(execution[sfFlags.jsonName] == expected); + bool const fixV2 = env.current()->rules().enabled(fixXahauV2); + if (fixV2) + { + BEAST_EXPECT(execution[sfFlags.jsonName] == expected); + } + else + { + BEAST_REQUIRE(!execution[sfFlags.jsonName]); + } } void @@ -873,7 +876,7 @@ private: test::jtx::Env env{ *this, network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features | featureAMM}; + features}; auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -923,7 +926,7 @@ private: test::jtx::Env env{ *this, network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features | featureAMM}; + features}; auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -978,7 +981,7 @@ private: cfg->FEES.reference_fee = XRPAmount(1); return cfg; }), - features | featureAMM); + features); auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -1038,7 +1041,7 @@ private: test::jtx::Env env{ *this, network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features | featureAMM | featureAMMClawback}; + features}; auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -1096,7 +1099,7 @@ private: test::jtx::Env env{ *this, network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features | featureAMM}; + features}; auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -1151,7 +1154,7 @@ private: test::jtx::Env env{ *this, network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features | featureAMM}; + features}; auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -1198,7 +1201,7 @@ private: test::jtx::Env env{ *this, network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features | featureAMM}; + features}; auto const issuer = Account("gw"); auto const account = Account("alice"); @@ -1642,12 +1645,8 @@ private: features}; auto const account = Account("alice"); - auto const issuer = Account::master; - env.fund(XRP(1000), account); - env.close(); - - env(hook(issuer, {{hso(jtx::genesis::AcceptHook)}}, 0), - fee(XRP(1))); + auto const issuer = Account("issuer"); + env.fund(XRP(1000), account, issuer); env.close(); // set tsh collect @@ -1679,8 +1678,8 @@ private: features}; auto const account = Account("alice"); - auto const issuer = Account::master; - env.fund(XRP(1000), account); + auto const issuer = Account("issuer"); + env.fund(XRP(1000), account, issuer); env.close(); // set tsh collect @@ -1703,15 +1702,13 @@ private: } void - testClawbackTSH(FeatureBitset _features) + testClawbackTSH(FeatureBitset features) { testcase("clawback tsh"); using namespace test::jtx; using namespace std::literals; - auto const features = _features | featureMPTokensV1; - // otxn: IOU issuer // tsh issuer // w/s: strong @@ -1828,30 +1825,6 @@ private: } } - void - testCredentialCreateTSH(FeatureBitset features) - { - testcase("credential create tsh"); - - BEAST_EXPECT(!features[featureCredentials]); - } - - void - testCredentialAcceptTSH(FeatureBitset features) - { - testcase("credential accept tsh"); - - BEAST_EXPECT(!features[featureCredentials]); - } - - void - testCredentialDeleteTSH(FeatureBitset features) - { - testcase("credential delete tsh"); - - BEAST_EXPECT(!features[featureCredentials]); - } - // DepositPreauth // | otxn | tsh | preauth | // | A | A | S | @@ -1932,31 +1905,6 @@ private: } } - void - testDIDSetTSH(FeatureBitset features) - { - testcase("did set tsh"); - - BEAST_EXPECT(!features[featureDID]); - } - - void - testDIDDeleteTSH(FeatureBitset features) - { - testcase("did delete tsh"); - - BEAST_EXPECT(!features[featureDID]); - } - - void - testEmitFailureTSH(FeatureBitset features) - { - testcase("emit failure tsh"); - - // pseudo transaction - pass(); - } - // Escrow // | otxn | tsh | cancel | cancel(id) | create | finish | finish(id) // | A | A | S | S | S | S | S @@ -2261,10 +2209,16 @@ private: setTSHHook(env, account, testStrong); // cancel escrow - env(cancel(account, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + Json::Value tx; + if (!env.current()->rules().enabled(fixXahauV1)) + { + tx = cancel(account, account, 0); + } + else + { + tx = cancel(account, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -2309,10 +2263,16 @@ private: setTSHHook(env, dest, testStrong); // cancel escrow - env(cancel(account, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + Json::Value tx; + if (!env.current()->rules().enabled(fixXahauV1)) + { + tx = cancel(account, account, 0); + } + else + { + tx = cancel(account, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -2361,10 +2321,16 @@ private: setTSHHook(env, dest, testStrong); // cancel escrow - env(cancel(dest, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + Json::Value tx; + if (!env.current()->rules().enabled(fixXahauV1)) + { + tx = cancel(dest, account, 0); + } + else + { + tx = cancel(dest, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -2406,14 +2372,23 @@ private: setTSHHook(env, account, testStrong); // cancel escrow - env(cancel(dest, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); + Json::Value tx; + if (!fixV1) + { + tx = cancel(dest, account, 0); + } + else + { + tx = cancel(dest, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered - auto const expected = testStrong ? tshSTRONG : tshSTRONG; + auto const expected = + (fixV1 ? (testStrong ? tshSTRONG : tshSTRONG) + : (testStrong ? tshNONE : tshNONE)); testTSHStrongWeak(env, expected, __LINE__); } @@ -2462,10 +2437,16 @@ private: setTSHHook(env, gw, testStrong); // cancel escrow - env(cancel(account, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + Json::Value tx; + if (!env.current()->rules().enabled(fixXahauV1)) + { + tx = cancel(account, account, 0); + } + else + { + tx = cancel(account, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -2881,10 +2862,16 @@ private: setTSHHook(env, account, testStrong); // finish escrow - env(finish(account, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + Json::Value tx; + if (!env.current()->rules().enabled(fixXahauV1)) + { + tx = finish(account, account, 0); + } + else + { + tx = finish(account, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -2923,14 +2910,23 @@ private: setTSHHook(env, dest, testStrong); // finish escrow - env(finish(account, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); + Json::Value tx; + if (!fixV1) + { + tx = finish(account, account, 0); + } + else + { + tx = finish(account, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered - auto const expected = testStrong ? tshSTRONG : tshSTRONG; + auto const expected = + (fixV1 ? (testStrong ? tshSTRONG : tshSTRONG) + : (testStrong ? tshNONE : tshNONE)); testTSHStrongWeak(env, expected, __LINE__); } @@ -2966,10 +2962,16 @@ private: setTSHHook(env, dest, testStrong); // finish escrow - env(finish(dest, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + Json::Value tx; + if (!env.current()->rules().enabled(fixXahauV1)) + { + tx = finish(dest, account, 0); + } + else + { + tx = finish(dest, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -3008,14 +3010,23 @@ private: setTSHHook(env, account, testStrong); // finish escrow - env(finish(dest, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); + Json::Value tx; + if (!fixV1) + { + tx = finish(dest, account, 0); + } + else + { + tx = finish(dest, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered - auto const expected = testStrong ? tshSTRONG : tshSTRONG; + auto const expected = + (fixV1 ? (testStrong ? tshSTRONG : tshSTRONG) + : (testStrong ? tshNONE : tshNONE)); testTSHStrongWeak(env, expected, __LINE__); } @@ -3061,10 +3072,17 @@ private: setTSHHook(env, gw, testStrong); // finish escrow - env(finish(dest, account), - escrow_id(escrowId), - fee(XRP(1)), - ter(tesSUCCESS)); + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); + Json::Value tx; + if (!fixV1) + { + tx = finish(dest, account, 0); + } + else + { + tx = finish(dest, account); + } + env(tx, escrow_id(escrowId), fee(XRP(1)), ter(tesSUCCESS)); env.close(); // verify tsh hook triggered @@ -3079,15 +3097,6 @@ private: } } - void - testEnableAmendmentTSH(FeatureBitset features) - { - testcase("enable amendment tsh"); - - // pseudo transaction - pass(); - } - // GenesisMint // | otxn | tsh | mint | // | A | A | S | @@ -3370,7 +3379,10 @@ private: env.close(); // verify tsh hook triggered - auto const expected = testStrong ? tshNONE : tshWEAK; + bool const fixV2 = env.current()->rules().enabled(fixXahauV2); + auto const expected = + (fixV2 ? (testStrong ? tshNONE : tshWEAK) + : (testStrong ? tshSTRONG : tshSTRONG)); testTSHStrongWeak(env, expected, __LINE__); } } @@ -3455,1223 +3467,6 @@ private: } } - // from FixNFTokenPageLinks_test.cpp - // A helper function that generates 96 nfts packed into three pages - // of 32 each. Returns a sorted vector of the NFTokenIDs packed into - // the pages. - std::vector - genPackedTokens(test::jtx::Env& env, test::jtx::Account const& owner) - { - using namespace test::jtx; - - std::vector nfts; - nfts.reserve(96); - - // We want to create fully packed NFT pages. This is a little - // tricky since the system currently in place is inclined to - // assign consecutive tokens to only 16 entries per page. - // - // By manipulating the internal form of the taxon we can force - // creation of NFT pages that are completely full. This lambda - // tells us the taxon value we should pass in in order for the - // internal representation to match the passed in value. - auto internalTaxon = [this, &env]( - Account const& acct, - std::uint32_t taxon) -> std::uint32_t { - std::uint32_t tokenSeq = [this, &env, &acct]() { - auto const le = env.le(acct); - if (BEAST_EXPECT(le)) - return le->at(~sfMintedNFTokens).value_or(0u); - return 0u; - }(); - - // If fixNFTokenRemint amendment is on, we must - // add FirstNFTokenSequence. - if (env.current()->rules().enabled(fixNFTokenRemint)) - tokenSeq += env.le(acct) - ->at(~sfFirstNFTokenSequence) - .value_or(env.seq(acct)); - - return toUInt32(nft::cipheredTaxon(tokenSeq, nft::toTaxon(taxon))); - }; - - for (std::uint32_t i = 0; i < 96; ++i) - { - // In order to fill the pages we use the taxon to break them - // into groups of 16 entries. By having the internal - // representation of the taxon go... - // 0, 3, 2, 5, 4, 7... - // in sets of 16 NFTs we can get each page to be fully - // populated. - std::uint32_t const intTaxon = (i / 16) + (i & 0b10000 ? 2 : 0); - uint32_t const extTaxon = internalTaxon(owner, intTaxon); - nfts.push_back( - token::getNextID(env, owner, extTaxon, tfTransferable)); - env(token::mint(owner, extTaxon), txflags(tfTransferable)); - env.close(); - } - - // Sort the NFTs so they are listed in storage order, not - // creation order. - std::sort(nfts.begin(), nfts.end()); - - // Verify that the owner does indeed have exactly three pages - // of NFTs with 32 entries in each page. - { - Json::Value params; - params[jss::account] = owner.human(); - auto resp = env.rpc("json", "account_objects", to_string(params)); - - Json::Value const& acctObjs = - resp[jss::result][jss::account_objects]; - - int pageCount = 0; - for (Json::UInt i = 0; i < acctObjs.size(); ++i) - { - if (BEAST_EXPECT( - acctObjs[i].isMember(sfNFTokens.jsonName) && - acctObjs[i][sfNFTokens.jsonName].isArray())) - { - BEAST_EXPECT(acctObjs[i][sfNFTokens.jsonName].size() == 32); - ++pageCount; - } - } - // If this check fails then the internal NFT directory logic - // has changed. - BEAST_EXPECT(pageCount == 3); - } - return nfts; - }; - - void - testLedgerStateFixTSH(FeatureBitset features) - { - testcase("ledger state fix tsh"); - - using namespace test::jtx; - using namespace std::literals; - - // otxn: account - // tsh account - // w/s: strong - - // otxn: account - // tsh owner - // w/s: weak - for (auto const& [testStrong, testOtxnAccount] : - std::vector>{ - {true, true}, {false, true}, {true, false}, {false, false}}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features - fixNFTokenPageLinks}; - - Account const alice("alice"); - Account const bob("bob"); - Account const carol("carol"); - Account const daria("daria"); - - Account const& hook = testOtxnAccount ? daria : alice; - - env.fund(XRP(1000), alice, bob, carol, daria); - - //********************************************************************** - // Step 1A: Create damaged NFToken directories: - // o One where there is only one page, but without the final - // index. - //********************************************************************** - - // alice generates three packed pages. - std::vector aliceNFTs = genPackedTokens(env, alice); - - // alice burns all the tokens in the first and last pages. - for (int i = 0; i < 32; ++i) - { - env(token::burn(alice, {aliceNFTs[i]})); - env.close(); - } - aliceNFTs.erase(aliceNFTs.begin(), aliceNFTs.begin() + 32); - for (int i = 0; i < 32; ++i) - { - env(token::burn(alice, {aliceNFTs.back()})); - aliceNFTs.pop_back(); - env.close(); - } - - //********************************************************************** - // Step 1B: Create damaged NFToken directories: - // o One with multiple pages and a missing final page. - //********************************************************************** - - // bob generates three packed pages. - std::vector bobNFTs = genPackedTokens(env, bob); - - // bob burns all the tokens in the very last page. - for (int i = 0; i < 32; ++i) - { - env(token::burn(bob, {bobNFTs.back()})); - bobNFTs.pop_back(); - env.close(); - } - - //********************************************************************** - // Step 1C: Create damaged NFToken directories: - // o One with links missing in the middle of the chain. - //********************************************************************** - - // carol generates three packed pages. - std::vector carolNFTs = genPackedTokens(env, carol); - - // carol sells all of the tokens in the very last page to daria. - std::vector dariaNFTs; - dariaNFTs.reserve(32); - for (int i = 0; i < 32; ++i) - { - uint256 const offerIndex = - keylet::nftoffer(carol, env.seq(carol)).key; - env(token::createOffer(carol, carolNFTs.back(), XRP(0)), - txflags(tfSellNFToken)); - env.close(); - - env(token::acceptSellOffer(daria, offerIndex)); - env.close(); - - dariaNFTs.push_back(carolNFTs.back()); - carolNFTs.pop_back(); - } - - // At this point carol's NFT directory has the same problem that - // bob's has: the last page is missing. Now we make things more - // complicated by putting the last page back. carol buys their NFTs - // back from daria. - for (uint256 const& nft : dariaNFTs) - { - uint256 const offerIndex = - keylet::nftoffer(carol, env.seq(carol)).key; - env(token::createOffer(carol, nft, drops(1)), - token::owner(daria)); - env.close(); - - env(token::acceptBuyOffer(daria, offerIndex)); - env.close(); - - carolNFTs.push_back(nft); - } - - //********************************************************************** - // Step 2: Enable the fixNFTokenPageLinks amendment. - //********************************************************************** - env.enableFeature(fixNFTokenPageLinks); - env.close(); - - //********************************************************************** - // Step 3A: Repair the one-page directory (alice's) - //********************************************************************** - - // The server "remembers" daria's failed nftPageLinks transaction - // signature. So we need to advance daria's sequence number before - // daria can submit a similar transaction. - env(noop(daria)); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, hook); - - // set tsh hook - setTSHHook(env, hook, testStrong); - - // daria fixes the links in alice's NFToken directory. - env(ledgerStateFix::nftPageLinks(daria, alice), fee(XRP(100))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testOtxnAccount ? tshSTRONG : (testStrong ? tshNONE : tshWEAK); - testTSHStrongWeak(env, expected, __LINE__); - } - } - - void - testMPTokenIssuanceCreateTSH(FeatureBitset features) - { - testcase("mp token issuance create tsh"); - - BEAST_EXPECT(!features[featureMPTokensV1]); - } - - void - testMPTokenIssuanceDestroyTSH(FeatureBitset features) - { - testcase("mp token issuance destroy tsh"); - - BEAST_EXPECT(!features[featureMPTokensV1]); - } - - void - testMPTokenIssuanceSetTSH(FeatureBitset features) - { - testcase("mp token issuance set tsh"); - - BEAST_EXPECT(!features[featureMPTokensV1]); - } - - void - testMPTokenAuthorizeTSH(FeatureBitset features) - { - testcase("mp token authorize tsh"); - - BEAST_EXPECT(!features[featureMPTokensV1]); - } - - void - testNFTokenMintTSH(FeatureBitset features) - { - testcase("nftoken mint tsh"); - - using namespace test::jtx; - using namespace std::literals; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - env.fund(XRP(1000), account); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // mint nft - env(token::mint(account), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh issuer - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const issuer = Account("bob"); - env.fund(XRP(1000), account, issuer); - env.close(); - - // set NFTokenMinter - env(token::setMinter(issuer, account)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // mint nft - env(token::mint(account), token::issuer(issuer), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // - // after NFTokenMintOffer amendment - // - BEAST_EXPECT(!features[featureNFTokenMintOffer]); - } - - void - testNFTokenBurnTSH(FeatureBitset features) - { - testcase("nftoken burn tsh"); - - using namespace test::jtx; - using namespace std::literals; - - auto const mintFlags = tfTransferable | tfBurnable; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - env.fund(XRP(1000), account); - env.close(); - - auto const nftid = token::getNextID(env, account, 0, mintFlags); - env(token::mint(account), txflags(mintFlags)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // burn nft - env(token::burn(account, nftid), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh owner - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - env.fund(XRP(1000), issuer, owner); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken), - fee(XRP(1))); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, owner); - - // set tsh hook - setTSHHook(env, owner, testStrong); - - // burn nft - env(token::burn(issuer, nftid), token::owner(owner), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE - : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - - // otxn: account - // tsh issuer - // nft flag: not tfStrongTSH - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - env.fund(XRP(1000), issuer, owner); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken), - fee(XRP(1))); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // burn nft - env(token::burn(owner, nftid), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE - : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - - // otxn: account - // tsh issuer - // nft flag: tfStrongTSH - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - env.fund(XRP(1000), issuer, owner); - env.close(); - - auto const nftid = - token::getNextID(env, issuer, 0, mintFlags | tfStrongTSH); - env(token::mint(issuer), txflags(mintFlags | tfStrongTSH)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken), - fee(XRP(1))); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // burn nft - env(token::burn(owner, nftid), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - } - - void - testNFTokenCreateOfferTSH(FeatureBitset features) - { - testcase("nftoken create offer tsh"); - - using namespace test::jtx; - using namespace std::literals; - - auto const mintFlags = tfTransferable; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const owner = Account("bob"); - env.fund(XRP(1000), account, owner); - env.close(); - - auto const nftid = token::getNextID(env, account, 0, mintFlags); - env(token::mint(account), txflags(mintFlags)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // create offer - env(token::createOffer(account, nftid, XRP(1)), - txflags(tfSellNFToken), - fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh owner - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const owner = Account("bob"); - auto const issuer = Account("carol"); - env.fund(XRP(1000), account, owner, issuer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, owner); - - // set tsh hook - setTSHHook(env, owner, testStrong); - - // create buy offer to owner - env(token::createOffer(account, nftid, XRP(1)), - token::owner(owner), - fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = testStrong ? tshNONE : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - - // otxn: account - // nft flag: not tfStrongTSH - // tsh issuer - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const owner = Account("bob"); - auto const issuer = Account("carol"); - env.fund(XRP(1000), account, owner, issuer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // create buy offer to owner - env(token::createOffer(account, nftid, XRP(1)), - token::owner(owner), - fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = testStrong ? tshNONE : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - // otxn: account - // nft flag: tfStrongTSH - // tsh issuer - // w/s: string - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const owner = Account("bob"); - auto const issuer = Account("carol"); - env.fund(XRP(1000), account, owner, issuer); - env.close(); - - auto const nftid = - token::getNextID(env, issuer, 0, mintFlags | tfStrongTSH); - env(token::mint(issuer), txflags(mintFlags | tfStrongTSH)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // create buy offer to owner - env(token::createOffer(account, nftid, XRP(1)), - token::owner(owner), - fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh destination - // w/s: none - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const destination = Account("bob"); - env.fund(XRP(1000), destination, issuer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, destination); - - // set tsh hook - setTSHHook(env, destination, testStrong); - - env(token::createOffer(issuer, nftid, XRP(1)), - token::destination(destination), - txflags(tfSellNFToken)); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshNONE, __LINE__); - } - - // otxn: account - // tsh amount issuer - // w/s: none - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const gw = Account("gw"); - auto const USD = gw["USD"]; - env.fund(XRP(1000), issuer, gw); - env.close(); - - env.trust(USD(10000), issuer); - env.close(); - env(pay(gw, issuer, USD(10000))); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, gw); - - // set tsh hook - setTSHHook(env, gw, testStrong); - - env(token::createOffer(issuer, nftid, USD(1)), - txflags(tfSellNFToken)); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshNONE, __LINE__); - } - } - - void - testNFTokenCancelOfferTSH(FeatureBitset features) - { - testcase("nftoken cancel offer tsh"); - - using namespace test::jtx; - using namespace std::literals; - - auto const mintFlags = tfTransferable; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const gw = Account("gw"); - env.fund(XRP(1000), account, gw); - env.close(); - - auto const nftid = token::getNextID(env, account, 0, mintFlags); - env(token::mint(account), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(account, env.seq(account)).key; - env(token::createOffer(account, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // cancel offer - env(token::cancelOffer(account, {offerIndex}), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: issuer - // tsh owner - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - auto const buyer = Account("carol"); - env.fund(XRP(1000), issuer, owner, buyer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - token::destination(owner), - txflags(tfSellNFToken)); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - auto const offerIndex2 = - keylet::nftoffer(owner, env.seq(owner)).key; - env(token::createOffer(owner, nftid, XRP(1)), - token::destination(buyer), - txflags(tfSellNFToken)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, owner); - - // set tsh hook - setTSHHook(env, owner, testStrong); - - // cancel offer - env(token::cancelOffer(buyer, {offerIndex2}), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE - : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - - // otxn: owner - // tsh destination - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - auto const buyer = Account("carol"); - env.fund(XRP(1000), issuer, owner, buyer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - token::destination(owner), - txflags(tfSellNFToken)); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - auto const offerIndex2 = - keylet::nftoffer(owner, env.seq(owner)).key; - env(token::createOffer(owner, nftid, XRP(1)), - token::destination(buyer), - txflags(tfSellNFToken)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, buyer); - - // set tsh hook - setTSHHook(env, buyer, testStrong); - - // cancel offer - env(token::cancelOffer(owner, {offerIndex2}), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE - : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - - // otxn: account - // tsh nft issuer - // w/s: weak (Regardless of tfStrongTSH) - for (auto const& [testStrong, strongIssuerTSH] : - std::vector>{ - {true, true}, {true, false}, {false, true}, {false, false}}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - env.fund(XRP(1000), issuer, owner); - env.close(); - - auto const nftid = token::getNextID( - env, - issuer, - 0, - mintFlags | (strongIssuerTSH ? tfStrongTSH : 0)); - env(token::mint(issuer), - txflags(mintFlags | (strongIssuerTSH ? tfStrongTSH : 0))); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - token::destination(owner), - txflags(tfSellNFToken)); - env.close(); - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - auto const offerIndex2 = - keylet::nftoffer(owner, env.seq(owner)).key; - env(token::createOffer(owner, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // cancel offer - env(token::cancelOffer(owner, {offerIndex2}), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE - : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - } - - void - testNFTokenAcceptOfferTSH(FeatureBitset features) - { - testcase("nftoken accept offer tsh"); - - using namespace test::jtx; - using namespace std::literals; - - auto const mintFlags = tfTransferable; - - // tsh: account(strong), issuer(weak/strong), owner(strong), - // destination(strong) - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const issuer = Account("bob"); - env.fund(XRP(1000), account, issuer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // accept offer - env(token::acceptSellOffer(account, offerIndex), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: owner - // nft flag: not tfStrongTSH - // tsh issuer - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - auto const buyer = Account("carol"); - env.fund(XRP(1000), issuer, owner, buyer); - env.close(); - - auto const nftid = token::getNextID(env, issuer, 0, mintFlags); - env(token::mint(issuer), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - auto const offerIndex2 = - keylet::nftoffer(buyer, env.seq(buyer)).key; - env(token::createOffer(buyer, nftid, XRP(1)), token::owner(owner)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // accept offer - env(token::acceptBuyOffer(owner, offerIndex2), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - auto const expected = - testStrong || !features[featureIOUIssuerWeakTSH] ? tshNONE - : tshWEAK; - testTSHStrongWeak(env, expected, __LINE__); - } - - // otxn: owner - // nft flag: tfStrongTSH - // tsh issuer - // w/s: weak - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const issuer = Account("alice"); - auto const owner = Account("bob"); - auto const buyer = Account("carol"); - env.fund(XRP(1000), issuer, owner, buyer); - env.close(); - - auto const nftid = - token::getNextID(env, issuer, 0, mintFlags | tfStrongTSH); - env(token::mint(issuer), txflags(mintFlags | tfStrongTSH)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(issuer, env.seq(issuer)).key; - env(token::createOffer(issuer, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - - env(token::acceptSellOffer(owner, offerIndex), fee(XRP(1))); - env.close(); - auto const offerIndex2 = - keylet::nftoffer(buyer, env.seq(buyer)).key; - env(token::createOffer(buyer, nftid, XRP(1)), token::owner(owner)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, issuer); - - // set tsh hook - setTSHHook(env, issuer, testStrong); - - // accept offer - env(token::acceptBuyOffer(owner, offerIndex2), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh owner - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - auto const account = Account("alice"); - auto const destination = Account("bob"); - env.fund(XRP(1000), account, destination); - env.close(); - - auto const nftid = token::getNextID(env, account, 0, mintFlags); - env(token::mint(account), txflags(mintFlags)); - env.close(); - - auto const offerIndex = - keylet::nftoffer(account, env.seq(account)).key; - env(token::createOffer(account, nftid, XRP(1)), - txflags(tfSellNFToken)); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // accept offer - env(token::acceptSellOffer(destination, offerIndex), fee(XRP(1))); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh destination - // w/s: strong - { - // If sfDestination holds an Offer, it meets the sfOwner criteria. - // If it doesn't hold an Offer, it falls under the Otxn Account. - // Because of this, we might not be able to run TSH tests regarding - // sfDestination. - } - } - - void - testNFTokenModifyTSH(FeatureBitset features) - { - testcase("nftoken modify tsh"); - - BEAST_EXPECT(!features[featureDynamicNFT]); - } - // Offer // | otxn | tsh | cancel | create | // | A | A | S | S | @@ -4861,99 +3656,6 @@ private: } } - void - testOracleSetTSH(FeatureBitset features) - { - testcase("oracle set tsh"); - - using namespace test::jtx; - using namespace std::literals; - using namespace oracle; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - env.fund(XRP(1000), account); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // set oracle - env.close(std::chrono::seconds(300)); - Oracle oracle( - env, - {.owner = account, - .series = {{"XRP", "USD", 740, 1}}, - .fee = 10000}); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - } - - void - testOracleDeleteTSH(FeatureBitset features) - { - testcase("oracle delete tsh"); - - using namespace test::jtx; - using namespace std::literals; - using namespace oracle; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - env.fund(XRP(1000), account); - env.close(); - - // set oracle - env.close(std::chrono::seconds(300)); - Oracle oracle( - env, - { - .owner = account, - .series = {{"XRP", "USD", 740, 1}}, - }); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // delete oracle - oracle.remove(oracle::RemoveArg{ - .documentID = oracle.documentID(), - .fee = 10000, - }); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - } - // Payment // | otxn | tsh | payment | // | A | A | S | @@ -5672,31 +4374,6 @@ private: } } - void - testPermissionedDomainSetTSH(FeatureBitset features) - { - testcase("permissioned domain set tsh"); - - BEAST_EXPECT(!features[featurePermissionedDomains]); - } - - void - testPermissionedDomainDeleteTSH(FeatureBitset features) - { - testcase("permissioned domain delete tsh"); - - BEAST_EXPECT(!features[featurePermissionedDomains]); - } - - void - testSetFeeTSH(FeatureBitset features) - { - testcase("set fee tsh"); - - // pseudo transaction - pass(); - } - // SetHook // | otxn | tsh | set | // | A | A | S | @@ -5815,88 +4492,6 @@ private: } } - void - testSetRemarksTSH(FeatureBitset features) - { - testcase("set remarks tsh"); - - using namespace test::jtx; - using namespace std::literals; - - // otxn: account - // tsh account - // w/s: strong - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - env.fund(XRP(1000), account); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // set remarks - env(remarks::setRemarks( - account, - keylet::account(account.id()).key, - {{"CAFE", "DEADBEEF", 0}}), - fee(XRP(1)), - ter(tesSUCCESS)); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshSTRONG, __LINE__); - } - - // otxn: account - // tsh: object issuer - // w/s:none - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const account = Account("alice"); - auto const issuer = Account("issuer"); - env.fund(XRP(1000), account, issuer); - env.close(); - - std::string const uri("https://example.com"); - env(remit::remit(issuer, account), remit::uri(uri), fee(XRP(1))); - env.close(); - - // set tsh collect - if (!testStrong) - addWeakTSH(env, account); - - // set tsh hook - setTSHHook(env, account, testStrong); - - // set remarks - env(remarks::setRemarks( - issuer, - keylet::uritoken(issuer, Blob(uri.begin(), uri.end())).key, - {{"CAFE", "DEADBEEF", 0}}), - fee(XRP(1)), - ter(tesSUCCESS)); - env.close(); - - // verify tsh hook triggered - testTSHStrongWeak(env, tshNONE, __LINE__); - } - } - // SignerListSet // | otxn | tsh | sls | // | A | A | S | @@ -6110,24 +4705,6 @@ private: } } - void - testUNLModifyTSH(FeatureBitset features) - { - testcase("unl modify tsh"); - - // pseudo transaction - pass(); - } - - void - testUNLReportTSH(FeatureBitset features) - { - testcase("unl report tsh"); - - // pseudo transaction - pass(); - } - // | otxn | tfBurnable | tsh | mint | burn | buy | sell | cancel // | O | false | O | N/A | S | N/A | S | S // | O | false | I | N/A | N | N/A | W | N/A @@ -6229,7 +4806,10 @@ private: env.close(); // verify tsh hook triggered - auto const expected = testStrong ? tshSTRONG : tshSTRONG; + bool const fixV2 = env.current()->rules().enabled(fixXahauV2); + auto const expected = + (fixV2 ? (testStrong ? tshSTRONG : tshSTRONG) + : (testStrong ? tshNONE : tshNONE)); testTSHStrongWeak(env, expected, __LINE__); } @@ -6310,7 +4890,10 @@ private: env.close(); // verify tsh hook triggered - auto const expected = testStrong ? tshSTRONG : tshSTRONG; + bool const fixV2 = env.current()->rules().enabled(fixXahauV2); + auto const expected = + (fixV2 ? (testStrong ? tshSTRONG : tshSTRONG) + : (testStrong ? tshNONE : tshNONE)); testTSHStrongWeak(env, expected, __LINE__); } } @@ -6416,12 +4999,15 @@ private: env.close(); // verify tsh hook triggered + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); bool const withIOUIssuerWeakTSH = env.current()->rules().enabled(featureIOUIssuerWeakTSH); - auto const expected = testStrong - ? tshNONE - : (withIOUIssuerWeakTSH ? tshWEAK : tshNONE); + auto const expected = + (fixV1 + ? (testStrong ? tshNONE + : (withIOUIssuerWeakTSH ? tshWEAK : tshNONE)) + : (testStrong ? tshSTRONG : tshSTRONG)); testTSHStrongWeak(env, expected, __LINE__); } @@ -6520,11 +5106,14 @@ private: env.close(); // verify tsh hook triggered + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); bool const withIOUIssuerWeakTSH = env.current()->rules().enabled(featureIOUIssuerWeakTSH); - auto const expected = testStrong - ? tshNONE - : (withIOUIssuerWeakTSH ? tshWEAK : tshNONE); + auto const expected = + (fixV1 + ? (testStrong ? tshNONE + : (withIOUIssuerWeakTSH ? tshWEAK : tshNONE)) + : (testStrong ? tshSTRONG : tshSTRONG)); testTSHStrongWeak(env, expected, __LINE__); } @@ -6574,12 +5163,15 @@ private: env.close(); // verify tsh hook triggered + bool const fixV1 = env.current()->rules().enabled(fixXahauV1); bool const withIOUIssuerWeakTSH = env.current()->rules().enabled(featureIOUIssuerWeakTSH); - auto const expected = testStrong - ? tshNONE - : (withIOUIssuerWeakTSH ? tshWEAK : tshNONE); + auto const expected = + (fixV1 + ? (testStrong ? tshNONE + : (withIOUIssuerWeakTSH ? tshWEAK : tshNONE)) + : (testStrong ? tshSTRONG : tshSTRONG)); testTSHStrongWeak(env, expected, __LINE__); } @@ -7527,70 +6119,6 @@ private: } } - void - testXChainCreateClaimIDTSH(FeatureBitset features) - { - testcase("xchain create claim id tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainCommitTSH(FeatureBitset features) - { - testcase("xchain commit tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainClaimTSH(FeatureBitset features) - { - testcase("xchain claim tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainAccountCreateCommitTSH(FeatureBitset features) - { - testcase("xchain account create commit tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainAddClaimAttestationTSH(FeatureBitset features) - { - testcase("xchain add claim attestation tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainAddAccountCreateAttestationTSH(FeatureBitset features) - { - testcase("xchain add account create attestation tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainModifyBridgeTSH(FeatureBitset features) - { - testcase("xchain modify bridge tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - - void - testXChainCreateBridgeTSH(FeatureBitset features) - { - testcase("xchain create bridge tsh"); - - BEAST_EXPECT(!features[featureXChainBridge]); - } - void testEmittedTxnReliability(FeatureBitset features) { @@ -7639,6 +6167,7 @@ private: env.close(); auto const preDest = env.balance(dest); + bool const withFix = env.current()->rules().enabled(fixXahauV2); env.app().openLedger().modify([&](OpenView& view, beast::Journal j) { auto const tx = @@ -7646,15 +6175,24 @@ private: auto result = ripple::apply(env.app(), view, *tx, tapNONE, env.journal); - BEAST_EXPECT(result.ter == tefNONDIR_EMIT); - BEAST_EXPECT(!result.applied); + bool const applyResult = withFix ? false : true; + if (withFix) + { + BEAST_EXPECT(result.ter == tefNONDIR_EMIT); + } + else + { + BEAST_EXPECT(result.ter == tesSUCCESS); + } + BEAST_EXPECT(result.applied == applyResult); return result.applied; }); env.close(); auto const postDest = env.balance(dest); - BEAST_EXPECT(postDest == preDest); + auto const postValue = withFix ? XRP(0) : XRP(1); + BEAST_EXPECT(postDest == preDest + postValue); for (size_t i = 0; i < 4; i++) { @@ -7665,7 +6203,8 @@ private: } auto const postDest1 = env.balance(dest); - BEAST_EXPECT(postDest1 == postDest); + auto const postValue1 = withFix ? XRP(0) : XRP(2); + BEAST_EXPECT(postDest1 == postDest + postValue1); } void @@ -8341,162 +6880,51 @@ private: } } - // Builds a manifest signed by `master`, nominating `ephemeral` as the - // signing key. A sequence of UINT32_MAX makes it a revocation, which by - // definition carries no signing key. - static std::string - makeManifestString( - jtx::Account const& master, - jtx::Account const& ephemeral, - std::uint32_t seq) - { - STObject st(sfGeneric); - st[sfSequence] = seq; - st[sfPublicKey] = master.pk(); - - if (seq != std::numeric_limits::max()) - { - st[sfSigningPubKey] = ephemeral.pk(); - sign( - st, - HashPrefix::manifest, - *publicKeyType(ephemeral.pk()), - ephemeral.sk()); - } - - sign( - st, - HashPrefix::manifest, - *publicKeyType(master.pk()), - master.sk(), - sfMasterSignature); - - Serializer s; - st.add(s); - return std::string(static_cast(s.data()), s.size()); - } - - // A manifest transaction carries no account signature, so it cannot be - // submitted through env() the way a signed transaction can. Returns the - // resulting transaction id so the caller can inspect its metadata. - uint256 - submitManifest(jtx::Env& env, std::string const& manifest) - { - Json::Value params; - params[jss::manifest] = strHex(manifest); - auto const jrr = env.rpc("json", "submit", to_string(params)); - - auto const& result = jrr[jss::result]; - - if (!BEAST_EXPECT( - result[jss::engine_result].asString() == "tesSUCCESS")) - { - log << "submitManifest: " << to_string(jrr) << std::endl; - return beast::zero; - } - - // An error response carries no tx_json, and strUnHex("") yields an - // engaged but empty Blob, so fromVoid() would memcpy from nullptr. - auto const blob = strUnHex(result[jss::tx_json][jss::hash].asString()); - auto const hash = - blob ? uint256::fromVoidChecked(*blob) : std::optional{}; - - if (!BEAST_EXPECT(hash.has_value())) - { - log << "submitManifest: " << to_string(jrr) << std::endl; - return beast::zero; - } - - return *hash; - } - - // SetManifest - // | otxn | tsh | manifest | - // | M | M | N/A | - // | M | E | W | ephemeral key's logical account - void - testSetManifestTSH(FeatureBitset features) - { - using namespace test::jtx; - using namespace std::literals; - testcase("set manifest TSH"); - - if (!features[featureOnChainManifests]) - return; - - // otxn: master - // tsh: ephemeral - // w/s: weak - // - // The ephemeral account is only named by the manifest, so it may - // observe the transaction but not rollback it. It therefore fires only - // when it has asked to collect. - for (bool const testStrong : {true, false}) - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const master = Account("master", KeyType::ed25519); - auto const ephemeral = Account("ephemeral", KeyType::ed25519); - env.fund(XRP(1000), master, ephemeral); - env.close(); - - if (!testStrong) - addWeakTSH(env, ephemeral); - - setTSHHook(env, ephemeral, testStrong); - - auto const txHash = - submitManifest(env, makeManifestString(master, ephemeral, 1)); - env.close(); - - // A strong hook on a weak stake holder is never reached. - auto const expected = testStrong ? tshNONE : tshWEAK; - testTSHStrongWeak(env, txHash, expected, __LINE__); - } - - // A revocation names no signing key, so there is no ephemeral stake - // holder to notify at all. - { - test::jtx::Env env{ - *this, - network::makeNetworkConfig(21337, "10", "1000000", "200000"), - features}; - - auto const master = Account("master", KeyType::ed25519); - auto const ephemeral = Account("ephemeral", KeyType::ed25519); - env.fund(XRP(1000), master, ephemeral); - env.close(); - - addWeakTSH(env, ephemeral); - setTSHHook(env, ephemeral, false); - - auto const txHash = submitManifest( - env, - makeManifestString( - master, - ephemeral, - std::numeric_limits::max())); - env.close(); - - testTSHStrongWeak(env, txHash, tshNONE, __LINE__); - } - } - void testTSH(FeatureBitset features) { -#pragma push_macro("TRANSACTION") -#undef TRANSACTION - -#define TRANSACTION(tag, value, name, fields) test##name##TSH(features); - -#include - -#undef TRANSACTION -#pragma pop_macro("TRANSACTION") + testAccountSetTSH(features); + testAccountDeleteTSH(features); + testAMMBidTSH(features); + testAMMCreateTSH(features); + testAMMDeleteTSH(features); + testAMMClawbackTSH(features); + testAMMDepositTSH(features); + testAMMVoteTSH(features); + testAMMWithdrawTSH(features); + testCheckCancelTSH(features); + testCheckCashTSH(features); + testCheckCreateTSH(features); + testClaimRewardTSH(features); + testClawbackTSH(features); + testDepositPreauthTSH(features); + testEscrowCancelTSH(features); + testEscrowIDCancelTSH(features); + testEscrowCreateTSH(features); + testEscrowFinishTSH(features); + testEscrowIDFinishTSH(features); + testGenesisMintTSH(features); + testImportTSH(features); + testInvokeTSH(features); + testOfferCancelTSH(features); + testOfferCreateTSH(features); + testPaymentTSH(features); + testPaymentChannelClaimTSH(features); + testPaymentChannelCreateTSH(features); + testPaymentChannelFundTSH(features); + testSetHookTSH(features); + testSetRegularKeyTSH(features); + testSignerListSetTSH(features); + testTicketCreateTSH(features); + testTrustSetTSH(features); + testURITokenMintTSH(features); + testURITokenBurnTSH(features); + testURITokenBuyTSH(features); + testURITokenCancelSellOfferTSH(features); + testURITokenCreateSellOfferTSH(features); + testRemitTSH(features); + testCronSetTSH(features); + testCronTSH(features); } void @@ -8512,10 +6940,13 @@ public: run(std::uint32_t instance, bool last = false) { using namespace test::jtx; - static FeatureBitset const all{supported_amendments()}; + static FeatureBitset const all{ + supported_amendments() | featureMPTokensV1}; - static std::array const feats{ + static std::array const feats{ all, + all - fixXahauV1 - fixXahauV2 - featureIOUIssuerWeakTSH, + all - fixXahauV2 - featureIOUIssuerWeakTSH, all - featureIOUIssuerWeakTSH, }; @@ -8545,10 +6976,14 @@ public: } \ }; -SETHOOKTSH_TEST(1, true) +SETHOOKTSH_TEST(1, false) +SETHOOKTSH_TEST(2, false) +SETHOOKTSH_TEST(3, true) BEAST_DEFINE_TESTSUITE_PRIO(SetHookTSH0, app, ripple, 2); BEAST_DEFINE_TESTSUITE_PRIO(SetHookTSH1, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(SetHookTSH2, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(SetHookTSH3, app, ripple, 2); } // namespace test } // namespace ripple