Skip to content

Commit

Permalink
Add bool flag to validation for evm context (#2201)
Browse files Browse the repository at this point in the history
  • Loading branch information
sieniven authored and prasannavl committed Jul 21, 2023
1 parent 5a7a1c0 commit 5d34ace
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
19 changes: 14 additions & 5 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
uint64_t time;
uint32_t txn;
uint64_t evmContext;
bool useEvmContext;

public:
CCustomTxApplyVisitor(const CTransaction &tx,
Expand All @@ -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());
Expand Down Expand Up @@ -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<uint32_t>(consensus.ChangiIntermediateHeight)) {
Expand Down Expand Up @@ -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 (...) {
Expand Down
3 changes: 1 addition & 2 deletions src/masternodes/mn_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
46 changes: 27 additions & 19 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<std::array<std::uint8_t, 20>, uint64_t>, uint64_t> evmTXFees;
typedef std::array<std::uint8_t, 20> 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::array<std::uint8_t, 20>, std::vector<CTxMemPool::txiter>> evmTXs;
struct EVMMinerContext {
// Used to track EVM TXs by sender and nonce.
std::map<EvmAddressWithNonce, uint64_t> feeMap;
// Used to track EVM TXs by sender
std::map<EvmAddress, std::vector<CTxMemPool::txiter>> addressTxsMap;
};

EVMMinerContext evmMinerContext;

while (mi != mempool.mapTx.get<T>().end() || !mapModifiedTx.empty() || !failedNonces.empty())
{
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit 5d34ace

Please sign in to comment.