From 5d34aced2ceae52b83cd0349cd7830c7b7481361 Mon Sep 17 00:00:00 2001 From: Niven Date: Fri, 21 Jul 2023 11:20:23 +0800 Subject: [PATCH] Add bool flag to validation for evm context (#2201) --- src/masternodes/mn_checks.cpp | 19 +++++++++++---- src/masternodes/mn_rpc.cpp | 3 +-- src/miner.cpp | 46 ++++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index f52c707cf28..05149f038aa 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -769,6 +769,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { uint64_t time; uint32_t txn; uint64_t evmContext; + bool useEvmContext; public: CCustomTxApplyVisitor(const CTransaction &tx, @@ -778,12 +779,14 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { const Consensus::Params &consensus, uint64_t time, uint32_t txn, - const uint64_t evmContext) + const uint64_t evmContext, + const bool useEvmContext) : CCustomTxVisitor(tx, height, coins, mnview, consensus), time(time), txn(txn), - evmContext(evmContext) {} + evmContext(evmContext), + useEvmContext(useEvmContext) {} Res operator()(const CCreateMasterNodeMessage &obj) const { Require(CheckMasternodeCreationTx()); @@ -3927,7 +3930,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { return Res::Err("evm tx size too large"); CrossBoundaryResult result; - const auto prevalidateResults = evm_try_prevalidate_raw_tx(result, HexStr(obj.evmTx), true, evmContext); + const auto prevalidateResults = evm_try_prevalidate_raw_tx(result, HexStr(obj.evmTx), useEvmContext, evmContext); // Completely remove this fork guard on mainnet upgrade to restore nonce check from EVM activation if (height >= static_cast(consensus.ChangiIntermediateHeight)) { @@ -4174,10 +4177,16 @@ Res CustomTxVisit(CCustomCSView &mnview, if (IsDisabledTx(height, tx, consensus)) { return Res::ErrCode(CustomTxErrCodes::Fatal, "Disabled custom transaction"); } + auto context = evmContext; - if (context == 0) context = evm_get_context(); + bool useEvmContext = true; + if (context == 0) { + useEvmContext = false; + context = evm_get_context(); + } + try { - return std::visit(CCustomTxApplyVisitor(tx, height, coins, mnview, consensus, time, txn, context), txMessage); + return std::visit(CCustomTxApplyVisitor(tx, height, coins, mnview, consensus, time, txn, context, useEvmContext), txMessage); } catch (const std::bad_variant_access &e) { return Res::Err(e.what()); } catch (...) { diff --git a/src/masternodes/mn_rpc.cpp b/src/masternodes/mn_rpc.cpp index 7436fff3743..20dae6f873d 100644 --- a/src/masternodes/mn_rpc.cpp +++ b/src/masternodes/mn_rpc.cpp @@ -457,8 +457,7 @@ void execTestTx(const CTransaction& tx, uint32_t height, CTransactionRef optAuth if (optAuthTx) AddCoins(coins, *optAuthTx, height); CCustomCSView view(*pcustomcsview); - uint64_t gasUsed{}; - res = CustomTxVisit(view, coins, tx, height, Params().GetConsensus(), txMessage, ::ChainActive().Tip()->nTime, gasUsed); + res = CustomTxVisit(view, coins, tx, height, Params().GetConsensus(), txMessage, ::ChainActive().Tip()->nTime); } if (!res) { if (res.code == CustomTxErrCodes::NotEnoughBalance) { diff --git a/src/miner.cpp b/src/miner.cpp index be16662a263..0b766f66524 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -711,15 +711,20 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // Copy of the view CCoinsViewCache coinsView(&::ChainstateActive().CoinsTip()); - // Used to track EVM TXs by sender and nonce. - // Key: sender address, nonce - // Value: fee - std::map, uint64_t>, uint64_t> evmTXFees; + typedef std::array EvmAddress; + struct EvmAddressWithNonce { + EvmAddress address; + uint64_t nonce; + }; - // Used to track EVM TXs by sender - // Key: sender address - // Value: vector of mempool TX iterator - std::map, std::vector> evmTXs; + struct EVMMinerContext { + // Used to track EVM TXs by sender and nonce. + std::map feeMap; + // Used to track EVM TXs by sender + std::map> addressTxsMap; + }; + + EVMMinerContext evmMinerContext; while (mi != mempool.mapTx.get().end() || !mapModifiedTx.empty() || !failedNonces.empty()) { @@ -855,6 +860,9 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // Only check custom TXs if (txType != CustomTxType::None) { if (txType == CustomTxType::EvmTx) { + auto evmFeeMap = evmMinerContext.feeMap; + auto evmAddressTxsMap = evmMinerContext.addressTxsMap; + auto txMessage = customTypeToMessage(txType); if (!CustomMetadataParse(nHeight, Params().GetConsensus(), metadata, txMessage)) { customTxPassed = false; @@ -871,29 +879,29 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda } const auto evmKey = std::make_pair(txResult.sender, txResult.nonce); - if (evmTXFees.count(evmKey)) { - const auto& gasFees = evmTXFees.at(evmKey); + if (evmFeeMap.count(evmKey)) { + const auto& gasFees = evmFeeMap.at(evmKey); if (txResult.tx_fees > gasFees) { // Higher paying fee. Remove all TXs from sender and add to collection to add them again in order. - RemoveEVMTransactions(evmTXs[txResult.sender]); - for (auto it = evmTXFees.begin(); it != evmTXFees.end();) { + RemoveEVMTransactions(evmAddressTxsMap[txResult.sender]); + for (auto it = evmFeeMap.begin(); it != evmFeeMap.end();) { const auto& [sender, nonce] = it->first; if (sender == txResult.sender) { - it = evmTXFees.erase(it); + it = evmFeeMap.erase(it); } else { ++it; } } - checkedTX.erase(evmTXs[txResult.sender][txResult.nonce]->GetTx().GetHash()); - evmTXs[txResult.sender][txResult.nonce] = sortedEntries[i]; + checkedTX.erase(evmAddressTxsMap[txResult.sender][txResult.nonce]->GetTx().GetHash()); + evmAddressTxsMap[txResult.sender][txResult.nonce] = sortedEntries[i]; auto count{txResult.nonce}; - for (const auto& entry : evmTXs[txResult.sender]) { + for (const auto& entry : evmAddressTxsMap[txResult.sender]) { inBlock.erase(entry); checkedTX.erase(entry->GetTx().GetHash()); replaceByFee.emplace(count, entry); ++count; } - evmTXs.erase(txResult.sender); + evmAddressTxsMap.erase(txResult.sender); evm_remove_txs_by_sender(evmContext, txResult.sender); customTxPassed = false; break; @@ -910,8 +918,8 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda break; } - evmTXFees.emplace(std::make_pair(txResult.sender, txResult.nonce), txResult.tx_fees); - evmTXs[txResult.sender].push_back(sortedEntries[i]); + evmFeeMap.emplace({ txResult.sender, txResult.nonce }, txResult.tx_fees); + evmAddressTxsMap[txResult.sender].push_back(sortedEntries[i]); } const auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmContext);