From 74cdfc422845ab06d7ccac4549b6d506fd3b6edc Mon Sep 17 00:00:00 2001 From: Denis Angell Date: Sun, 1 Oct 2023 21:39:59 +0200 Subject: [PATCH] Genesis Mint TSH (#126) * remove console logs * env config no warnings * add genesis mint tsh --- src/ripple/app/hook/applyHook.h | 1 + src/ripple/app/hook/impl/applyHook.cpp | 16 ++++ src/test/app/GenesisMint_test.cpp | 117 +++++++++++++++++++------ src/test/rpc/LedgerRequestRPC_test.cpp | 10 --- 4 files changed, 109 insertions(+), 35 deletions(-) diff --git a/src/ripple/app/hook/applyHook.h b/src/ripple/app/hook/applyHook.h index 3a184f956..3a820561b 100644 --- a/src/ripple/app/hook/applyHook.h +++ b/src/ripple/app/hook/applyHook.h @@ -80,6 +80,7 @@ namespace hook {ttURITOKEN_CREATE_SELL_OFFER, tshROLLBACK }, {ttURITOKEN_CANCEL_SELL_OFFER, tshNONE }, {ttIMPORT, tshROLLBACK }, + {ttGENESIS_MINT, tshCOLLECT }, }; diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index 31cfceeec..a39e83cbc 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -354,6 +354,22 @@ namespace hook break; } + case ttGENESIS_MINT: + { + if (tx.isFieldPresent(sfGenesisMints)) + { + auto const& mints = tx.getFieldArray(sfGenesisMints); + for(auto const& mint : mints) + { + if(mint.isFieldPresent(sfDestination)) + { + ADD_TSH(mint.getAccountID(sfDestination), canRollback); + } + } + } + break; + } + default: return {}; } diff --git a/src/test/app/GenesisMint_test.cpp b/src/test/app/GenesisMint_test.cpp index b92fea2dc..5ee697e0b 100644 --- a/src/test/app/GenesisMint_test.cpp +++ b/src/test/app/GenesisMint_test.cpp @@ -15,11 +15,10 @@ */ //============================================================================== -#include #include - -#include +#include #include +#include namespace ripple { namespace test { @@ -89,6 +88,26 @@ struct GenesisMint_test : public beast::unit_test::suite return tx; } + Json::Value + setAcceptHook(jtx::Account const& account) + { + using namespace jtx; + Json::Value tx; + tx[jss::Account] = account.human(); + tx[jss::TransactionType] = "SetHook"; + tx[jss::Hooks] = Json::arrayValue; + tx[jss::Hooks][0u] = Json::objectValue; + tx[jss::Hooks][0u][jss::Hook] = Json::objectValue; + tx[jss::Hooks][0u][jss::Hook][jss::HookOn] = + "0000000000000000000000000000000000000000000000000000000000000000"; + tx[jss::Hooks][0u][jss::Hook][jss::HookNamespace] = + "0000000000000000000000000000000000000000000000000000000000000000"; + tx[jss::Hooks][0u][jss::Hook][jss::HookApiVersion] = 0; + tx[jss::Hooks][0u][jss::Hook][jss::Flags] = 5; + tx[jss::Hooks][0u][jss::Hook][jss::CreateCode] = strHex(XahauGenesis::AcceptHook); + return tx; + } + void testDisabled(FeatureBitset features) { @@ -174,10 +193,7 @@ struct GenesisMint_test : public beast::unit_test::suite using namespace jtx; using namespace std::literals::chrono_literals; - Env env{*this, envconfig(), features, nullptr, - beast::severities::kWarning -// beast::severities::kTrace - }; + Env env{*this, envconfig(), features, nullptr}; auto const alice = Account("alice"); auto const bob = Account("bob"); auto const invoker = Account("invoker"); @@ -214,10 +230,7 @@ struct GenesisMint_test : public beast::unit_test::suite using namespace jtx; using namespace std::literals::chrono_literals; - Env env{*this, envconfig(), features, nullptr, - beast::severities::kWarning -// beast::severities::kTrace - }; + Env env{*this, envconfig(), features, nullptr}; auto const alice = Account("alice"); auto const bob = Account("bob"); auto const invoker = Account("invoker"); @@ -253,8 +266,6 @@ struct GenesisMint_test : public beast::unit_test::suite BEAST_EXPECT(acc->getFieldAmount(sfBalance).xrp().drops() == 10123000000ULL); } auto const postCoins = env.current()->info().drops; - std::cout << "initCoins: " << initCoins << "\n"; - std::cout << "postCoins: " << postCoins << "\n"; BEAST_EXPECT(initCoins - 1'000'000 /* txn fee */ - 10 /* emitted txn fee */ @@ -383,8 +394,12 @@ struct GenesisMint_test : public beast::unit_test::suite uint256 marks; uint256 flags; - flags.parseHex("0000000000000000000000000000000000000000000000000000000000000001"); - marks.parseHex("1000000000000000000000000000000000000000000000000000000000000000"); + BEAST_EXPECT( + flags.parseHex("000000000000000000000000000000000000000000000000000" + "0000000000001")); + BEAST_EXPECT( + marks.parseHex("100000000000000000000000000000000000000000000000000" + "0000000000000")); // dest + flags { @@ -545,8 +560,6 @@ struct GenesisMint_test : public beast::unit_test::suite BEAST_EXPECT(!!le && le->getFieldAmount(sfBalance).xrp().drops() ==10000000ULL); auto const postCoins = env.current()->info().drops; - std::cout << "initCoins: " << initCoins << "\n"; - std::cout << "postCoins: " << postCoins << "\n"; BEAST_EXPECT(initCoins - 1'000'000 /* txn fee */ - 10 /* emitted txn fee */ == postCoins); } @@ -560,10 +573,7 @@ struct GenesisMint_test : public beast::unit_test::suite using namespace jtx; using namespace std::literals::chrono_literals; - Env env{*this, envconfig(), features, nullptr, - beast::severities::kWarning -// beast::severities::kTrace - }; + Env env{*this, envconfig(), features, nullptr}; auto const alice = Account("alice"); auto const bob = Account("bob"); env.fund(XRP(10000), alice, bob); @@ -584,10 +594,7 @@ struct GenesisMint_test : public beast::unit_test::suite using namespace jtx; using namespace std::literals::chrono_literals; - Env env{*this, envconfig(), features, nullptr, - beast::severities::kWarning -// beast::severities::kTrace - }; + Env env{*this, envconfig(), features, nullptr}; auto const alice = Account("alice"); auto const bob = Account("bob"); env.fund(XRP(10000), alice, bob); @@ -601,6 +608,65 @@ struct GenesisMint_test : public beast::unit_test::suite BEAST_EXPECT(!!le && le->getFieldAmount(sfBalance).xrp().drops() ==10000000000ULL); } + void + testGenesisMintTSH(FeatureBitset features) + { + testcase("GenesisMint TSH"); + using namespace jtx; + using namespace std::literals::chrono_literals; + + Env env{*this, envconfig(), features, nullptr}; + auto const alice = Account("alice"); + auto const bob = Account("bob"); + auto const invoker = Account("invoker"); + env.fund(XRP(10000), alice, bob, invoker); + + // set tsh collect on bob + env(fset(bob, asfTshCollect)); + + // burn down the total ledger coins so that genesis mints don't mint + // above 100B tripping invariant + env(burn(env.master), fee(XRP(10'000'000ULL))); + env.close(); + + // set the test hook + env(setMintHook(env.master), fee(XRP(10))); + env.close(); + + // set the accept hook + env(setAcceptHook(bob), fee(XRP(10))); + env.close(); + + // test a mint + { + env(invoke( + invoker, + env.master, + makeBlob({ + {bob.id(), + XRP(123).value(), + std::nullopt, + std::nullopt}, + })), + fee(XRP(10)), + ter(tesSUCCESS)); + + env.close(); + env.close(); + + // verify tsh hook triggered + Json::Value params; + params[jss::transaction] = + "11A278CCB5829913E5548CD57473328413D56B9C96FC2347803276D5149CBF" + "03"; + auto const jrr = env.rpc("json", "tx", to_string(params)); + auto const meta = jrr[jss::result][jss::meta]; + auto const executions = meta[sfHookExecutions.jsonName]; + auto const execution = executions[0u][sfHookExecution.jsonName]; + BEAST_EXPECT(execution[sfHookResult.jsonName] == 3); + } + } + public: void run() override @@ -612,6 +678,7 @@ public: testGenesisNonEmit(sa); testNonGenesisEmit(sa); testNonGenesisNonEmit(sa); + testGenesisMintTSH(sa); } }; diff --git a/src/test/rpc/LedgerRequestRPC_test.cpp b/src/test/rpc/LedgerRequestRPC_test.cpp index 63db6ef9c..f2ef47a52 100644 --- a/src/test/rpc/LedgerRequestRPC_test.cpp +++ b/src/test/rpc/LedgerRequestRPC_test.cpp @@ -189,10 +189,8 @@ public: BEAST_EXPECT( result[jss::ledger][jss::total_coins] == "100000000000000000"); BEAST_EXPECT(result[jss::ledger][jss::closed] == true); - std::cout << "lgr1: " << result[jss::ledger][jss::ledger_hash] << "\n"; BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash1); BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == zerohash); - std::cout << "acc1: " << result[jss::ledger][jss::account_hash] << "\n"; BEAST_EXPECT(result[jss::ledger][jss::account_hash] == accounthash1); BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] == zerohash); @@ -203,10 +201,8 @@ public: BEAST_EXPECT( result[jss::ledger][jss::total_coins] == "100000000000000000"); BEAST_EXPECT(result[jss::ledger][jss::closed] == true); - std::cout << "lgr 2: " << result[jss::ledger][jss::ledger_hash] << "\n"; BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash2); BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash1); - std::cout << "acc 2: " << result[jss::ledger][jss::account_hash] << "\n"; BEAST_EXPECT( result[jss::ledger][jss::account_hash] == "C6C885F43A772BA455AB96456248D10D2B32E32C24377520D6B7652F3FCEEF31"); @@ -219,10 +215,8 @@ public: BEAST_EXPECT( result[jss::ledger][jss::total_coins] == "99999999999999980"); BEAST_EXPECT(result[jss::ledger][jss::closed] == true); - std::cout << "lgr 3: " << result[jss::ledger][jss::ledger_hash] << "\n"; BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash3); BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash2); - std::cout << "acc 3: " << result[jss::ledger][jss::account_hash] << "\n"; BEAST_EXPECT( result[jss::ledger][jss::account_hash] == "692A26D06FCB0A2685F6DC269A08713E9FD8583056B2E4928CCE76862763609D"); @@ -237,10 +231,8 @@ public: BEAST_EXPECT( result[jss::ledger][jss::total_coins] == "99999999999999960"); BEAST_EXPECT(result[jss::ledger][jss::closed] == true); - std::cout << "lgr 4: " << result[jss::ledger][jss::ledger_hash] << "\n"; BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash4); BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash3); - std::cout << "acc 4: " << result[jss::ledger][jss::account_hash] << "\n"; BEAST_EXPECT( result[jss::ledger][jss::account_hash] == "D6DF68C04B663B45F159AA87072479C54B3930E92E8965154C35A80D508BF958"); @@ -255,10 +247,8 @@ public: BEAST_EXPECT( result[jss::ledger][jss::total_coins] == "99999999999999940"); BEAST_EXPECT(result[jss::ledger][jss::closed] == true); - std::cout << "lgr 5: " << result[jss::ledger][jss::ledger_hash] << "\n"; BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash5); BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash4); - std::cout << "acc 5: " << result[jss::ledger][jss::account_hash] << "\n"; BEAST_EXPECT( result[jss::ledger][jss::account_hash] == "6A1179D2AD9ACDF61E14A076B6FBE305FF032D2193D230DE21BF9358C7E11F09");