From 129c25a90a020126f3acc22a5fa98f337c559dbc Mon Sep 17 00:00:00 2001 From: Richard Holland Date: Thu, 17 Aug 2023 09:44:38 +0000 Subject: [PATCH] add check in import preclaim for non-zero fee --- src/ripple/app/tx/impl/Import.cpp | 9 ++- src/ripple/app/tx/impl/InvariantCheck.cpp | 7 +- src/ripple/app/tx/impl/Transactor.h | 4 +- src/test/app/Import_test.cpp | 96 ++++++++++++----------- 4 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/ripple/app/tx/impl/Import.cpp b/src/ripple/app/tx/impl/Import.cpp index d2d66609e..bda887930 100644 --- a/src/ripple/app/tx/impl/Import.cpp +++ b/src/ripple/app/tx/impl/Import.cpp @@ -862,6 +862,10 @@ Import::preclaim(PreclaimContext const& ctx) return tefPAST_IMPORT_SEQ; } + // when importing for the first time the fee must be zero + if (!sle && ctx.tx.getFieldAmount(sfFee) != beast::zero) + return temBAD_FEE; + auto const vlInfo = getVLInfo(*xpop, ctx.j); if (!vlInfo) @@ -1174,7 +1178,7 @@ Import::doApply() bool const create = !sle; XRPAmount const bonusAmount = Import::computeStartingBonus(ctx_.view()); - STAmount startBal = create ? STAmount(bonusAmount) : sle->getFieldAmount(sfBalance); + STAmount startBal = create ? STAmount(bonusAmount) : STAmount(mSourceBalance); uint64_t creditDrops = burn.xrp().drops(); if (elapsed < 2'000'000) @@ -1274,9 +1278,6 @@ Import::doApply() XRPAmount Import::calculateBaseFee(ReadView const& view, STTx const& tx) { - if (!view.rules().enabled(featureHooksUpdate1)) - return XRPAmount { 0 }; - if (!view.exists(keylet::account(tx.getAccountID(sfAccount))) && !tx.isFieldPresent(sfIssuer)) return XRPAmount { 0 }; diff --git a/src/ripple/app/tx/impl/InvariantCheck.cpp b/src/ripple/app/tx/impl/InvariantCheck.cpp index 26dbe8c29..cac00c0ef 100644 --- a/src/ripple/app/tx/impl/InvariantCheck.cpp +++ b/src/ripple/app/tx/impl/InvariantCheck.cpp @@ -191,7 +191,12 @@ XRPNotCreated::finalize( return false; } - return (drops_ <= maxDropsAdded.drops() - fee.drops()); + bool const passed = (drops_ <= maxDropsAdded.drops() - fee.drops()); + if (!passed) + JLOG(j.trace()) + << "XRPNotCreated failed."; + return passed; + } if (view.rules().enabled(featureXahauGenesis) && tt == ttGENESIS_MINT && res == tesSUCCESS) diff --git a/src/ripple/app/tx/impl/Transactor.h b/src/ripple/app/tx/impl/Transactor.h index 862e7c6a0..f60514621 100644 --- a/src/ripple/app/tx/impl/Transactor.h +++ b/src/ripple/app/tx/impl/Transactor.h @@ -94,8 +94,8 @@ protected: beast::Journal const j_; AccountID const account_; - XRPAmount mPriorBalance; // Balance before fees. - XRPAmount mSourceBalance; // Balance after fees. + XRPAmount mPriorBalance { 0 }; // Balance before fees. + XRPAmount mSourceBalance { 0 }; // Balance after fees. virtual ~Transactor() = default; Transactor(Transactor const&) = delete; diff --git a/src/test/app/Import_test.cpp b/src/test/app/Import_test.cpp index 8259569b8..1564c65ed 100644 --- a/src/test/app/Import_test.cpp +++ b/src/test/app/Import_test.cpp @@ -36,6 +36,8 @@ if (!(x)) \ return; \ } +#define M(m) memo(m, "", "") + namespace ripple { namespace test { @@ -2534,58 +2536,62 @@ class Import_test : public beast::unit_test::suite env(noop(alice), sig(bob), fee(feeDrops), ter(tefBAD_AUTH)); } - // // // w/ signers list -> dne - // // { - // // test::jtx::Env env{*this, makeNetworkConfig(21337)}; + // w/ signers list -> dne + { +// test::jtx::Env env{*this, makeNetworkConfig(21337)}; + test::jtx::Env env{*this, makeNetworkConfig(21337), supported_amendments(), nullptr, + beast::severities::kTrace + }; - // // auto const feeDrops = env.current()->fees().base; + auto const feeDrops = env.current()->fees().base; - // // burn 1000 xrp - // // auto const master = Account("masterpassphrase"); - // // env(noop(master), fee(1'000'000'000), ter(tesSUCCESS)); - // // env.close(); + // burn 1000 xrp + auto const master = Account("masterpassphrase"); + env(noop(master), fee(1'000'000'000), ter(tesSUCCESS)); + env.close(); - // // // init env - // // auto const alice = Account("alice"); - // // auto const bob = Account("bob"); - // // auto const carol = Account("carol"); - // // env.memoize(alice); - // // env.memoize(bob); - // // env.memoize(carol); + // init env + auto const alice = Account("alice"); + auto const bob = Account("bob"); + auto const carol = Account("carol"); + env.memoize(alice); + env.memoize(bob); + env.memoize(carol); - // // // confirm env - // // auto const preCoins = env.current()->info().drops; - // // BEAST_EXPECT(preCoins == 99'999'999'999'900'000); - // // auto const preAlice = env.balance(alice); - // // BEAST_EXPECT(preAlice == XRP(0)); + // confirm env + auto const preCoins = env.current()->info().drops; + BEAST_EXPECT(preCoins == 99'999'999'999'900'000); + auto const preAlice = env.balance(alice); + BEAST_EXPECT(preAlice == XRP(0)); - // // // import tx - // // auto const xpopJson = loadXpop(ImportTCAccountSet::w_signers); - // // Json::Value tx = import(alice, xpopJson); - // // tx[jss::Sequence] = 0; - // // tx[jss::Fee] = 0; - // // env( - // // tx, - // // alice, - // // msig(bob, carol), - // // fee(3 * feeDrops), - // // ter(tesSUCCESS) - // // ); - // // env.close(); + // import tx + auto const xpopJson = loadXpop(ImportTCAccountSet::w_signers); + Json::Value tx = import(alice, xpopJson); + tx[jss::Sequence] = 0; + tx[jss::Fee] = 0; + env( + tx, + alice, + msig(bob, carol), + M("accountset with signers 2573"), + fee(3 * feeDrops), + ter(tesSUCCESS) + ); + env.close(); - // // // confirm fee was minted - // // auto const postAlice = env.balance(alice); - // // BEAST_EXPECT(postAlice == preAlice + XRP(0.00001) + XRP(2)); - // // auto const postCoins = env.current()->info().drops; - // // BEAST_EXPECT(postCoins == 99'999'999'999'900'000); + // confirm fee was minted + auto const postAlice = env.balance(alice); + BEAST_EXPECT(postAlice == preAlice + XRP(0.00001) + XRP(2)); + auto const postCoins = env.current()->info().drops; + BEAST_EXPECT(postCoins == 99'999'999'999'900'000); - // // // confirm signers not set - // // auto const k = keylet::signers(bob); - // // BEAST_EXPECT(env.current()->read(k) == nullptr); - // // // alice cannnot sign - // // env(noop(alice), sig(alice), fee(feeDrops), - // // ter(tefMASTER_DISABLED)); - // // } + // confirm signers not set + auto const k = keylet::signers(bob); + BEAST_EXPECT(env.current()->read(k) == nullptr); + // alice cannnot sign + env(noop(alice), sig(alice), fee(feeDrops), + ter(tefMASTER_DISABLED)); + } // w/ seed -> funded {