From da52bbef2612deb43fce1f371decff2aa3366b4d Mon Sep 17 00:00:00 2001 From: Bushstar Date: Tue, 25 Jul 2023 06:27:44 +0100 Subject: [PATCH 01/15] Revert "Fix miner crash and refactor transaction removal (#2215)" This reverts commit 01fb687b2600b5dbd8c7094cee219756f7d9b3d5. --- lib/ain-evm/src/evm.rs | 2 - src/miner.cpp | 209 ++++++++++++++++++++--------------------- src/miner.h | 4 +- 3 files changed, 102 insertions(+), 113 deletions(-) diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index e4612218ba..12d231546e 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -36,8 +36,6 @@ pub struct EVMServices { pub struct FinalizedBlockInfo { pub block_hash: [u8; 32], - // TODO: There's no reason for this to be hex encoded and de-coded back again - // We can just send the array of 256 directly, same as block hash. pub failed_transactions: Vec, pub total_burnt_fees: U256, pub total_priority_fees: U256, diff --git a/src/miner.cpp b/src/miner.cpp index 5c261113a0..66c5c89936 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -298,29 +298,12 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc xvm_changi = XVMChangiIntermediate{0,{0, uint256(blockHash), blockResult.total_burnt_fees}}; } - std::set failedTransactions; - for (const auto& txRustStr : blockResult.failed_transactions) { - auto txStr = std::string(txRustStr.data(), txRustStr.length()); - failedTransactions.insert(uint256S(txStr)); + std::vector failedTransactions; + for (const auto& rust_string : blockResult.failed_transactions) { + failedTransactions.emplace_back(rust_string.data(), rust_string.length()); } - std::set failedTransferDomainTxs; - - // Get All TransferDomainTxs - for (const auto &hash : failedTransactions) { - for (const auto &tx : pblock->vtx) { - if (tx && tx->GetHash() == hash) { - std::vector metadata; - const auto txType = GuessCustomTxType(*tx, metadata, false); - if (txType == CustomTxType::TransferDomain) { - failedTransferDomainTxs.insert(hash); - } - break; - } - } - } - - RemoveTxs(failedTransactions, txFees); + RemoveFailedTransactions(failedTransactions, txFees); } // TXs for the creationTx field in new tokens created via token split @@ -571,56 +554,93 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already return nDescendantsUpdated; } -void BlockAssembler::RemoveTxIters(const std::vector iters) { +void BlockAssembler::RemoveEVMTransactions(const std::vector iters) { + + // Make sure we only remove EVM TXs which have no descendants or TX fees. + // Removing others TXs is more complicated and should be handled by RemoveFailedTransactions. for (const auto& iter : iters) { const auto &tx = iter->GetTx(); + std::vector metadata; + const auto txType = GuessCustomTxType(tx, metadata, false); + if (txType != CustomTxType::EvmTx) { + continue; + } + for (size_t i = 0; i < pblock->vtx.size(); ++i) { - auto current = pblock->vtx[i]; - if (current && current->GetHash() == tx.GetHash()) { + if (pblock->vtx[i] && pblock->vtx[i]->GetHash() == iter->GetTx().GetHash()) { pblock->vtx.erase(pblock->vtx.begin() + i); - nBlockWeight -= iter->GetTxWeight(); - nBlockSigOpsCost -= iter->GetSigOpCost(); - nFees -= iter->GetFee(); - --nBlockTx; break; } } + + nBlockWeight -= iter->GetTxWeight(); + --nBlockTx; } } -void BlockAssembler::RemoveTxs(const std::set &txHashSet, const std::map &txFees) { - if (txHashSet.empty()) { return; } +void BlockAssembler::RemoveFailedTransactions(const std::vector &failedTransactions, const std::map &txFees) { + if (failedTransactions.empty()) { + return; + } - auto &blockFees = nFees; - auto &blockTxCount = nBlockTx; + std::vector txsToErase; + for (const auto &txStr : failedTransactions) { + const auto failedHash = uint256S(txStr); + for (const auto &tx : pblock->vtx) { + if (tx && tx->GetHash() == failedHash) { + std::vector metadata; + const auto txType = GuessCustomTxType(*tx, metadata, false); + if (txType == CustomTxType::TransferDomain) { + txsToErase.push_back(failedHash); + } + } + } + } - auto removeItem = [&txHashSet, &blockFees, &blockTxCount, &txFees](const auto &tx) { - auto hash = tx.get()->GetHash(); - if (txHashSet.count(hash) < 1) return false; - blockFees -= txFees.at(hash); - --blockTxCount; - return true; - }; + // Get a copy of the TXs to be erased for restoring to the mempool later + std::vector txsToRemove; + std::set txsToEraseSet(txsToErase.begin(), txsToErase.end()); - pblock->vtx.erase( - std::remove_if(pblock->vtx.begin(), pblock->vtx.end(), removeItem), - pblock->vtx.end()); + for (const auto &tx : pblock->vtx) { + if (tx && txsToEraseSet.count(tx->GetHash())) { + txsToRemove.push_back(tx); + } + } - // Add descendants - std::set descendantTxsToErase; - for (const auto &hash : txHashSet) { + // Add descendants and in turn add their descendants. This needs to + // be done in the order that the TXs are in the block for txsToRemove. + auto size = txsToErase.size(); + for (std::vector::size_type i{}; i < size; ++i) { for (const auto &tx : pblock->vtx) { - if (!tx) continue; - for (const auto &vin : tx->vin) { - if (vin.prevout.hash == hash) { - descendantTxsToErase.insert(hash); + if (tx) { + for (const auto &vin : tx->vin) { + if (vin.prevout.hash == txsToErase[i] && + std::find(txsToErase.begin(), txsToErase.end(), tx->GetHash()) == txsToErase.end()) + { + txsToRemove.push_back(tx); + txsToErase.push_back(tx->GetHash()); + ++size; + } } } } } - // Recursively remove descendants - RemoveTxs(descendantTxsToErase, txFees); + // Erase TXs from block + txsToEraseSet = std::set(txsToErase.begin(), txsToErase.end()); + pblock->vtx.erase( + std::remove_if(pblock->vtx.begin(), pblock->vtx.end(), + [&txsToEraseSet](const auto &tx) { + return tx && txsToEraseSet.count(tx.get()->GetHash()); + }),pblock->vtx.end()); + + for (const auto &tx : txsToRemove) { + // Remove fees. + if (txFees.count(tx->GetHash())) { + nFees -= txFees.at(tx->GetHash()); + } + --nBlockTx; + } } // Skip entries in mapTx that are already in a block or are present @@ -667,6 +687,10 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda indexed_modified_transaction_set mapModifiedTx; // Keep track of entries that failed inclusion, to avoid duplicate work CTxMemPool::setEntries failedTx; + // Keep track of EVM entries that failed nonce check + std::multimap failedNonces; + // Used for replacement Eth TXs when a TX in chain pays a higher fee + std::map replaceByFee; // Start by adding all descendants of previously added txs to mapModifiedTx // and modifying them for their already included ancestors @@ -687,40 +711,15 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // Copy of the view CCoinsViewCache coinsView(&::ChainstateActive().CoinsTip()); - typedef std::array EvmAddress; - - struct EvmAddressWithNonce { - EvmAddress address; - uint64_t nonce; - - bool operator<(const EvmAddressWithNonce& item) const { - return std::tie(address, nonce) < std::tie(item.address, item.nonce); - } - }; - - struct EvmPackageContext { - // Used to track EVM TXs by sender and nonce. - std::map feeMap; - // Used to track EVM nonce and TXs by sender - std::map> addressTxsMap; - // Keep track of EVM entries that failed nonce check - std::multimap failedNonces; - // Used for replacement Eth TXs when a TX in chain pays a higher fee - std::map replaceByFee; - }; - - auto txIters = [](std::map &iterMap) -> std::vector { - std::vector txIters; - for (const auto& [nonce, it] : iterMap) { - txIters.push_back(it); - } - return txIters; - }; + // Used to track EVM TXs by sender and nonce. + // Key: sender address, nonce + // Value: fee + std::map, uint64_t>, uint64_t> evmTXFees; - EvmPackageContext evmPackageContext; - - auto& failedNonces = evmPackageContext.failedNonces; - auto& replaceByFee = evmPackageContext.replaceByFee; + // Used to track EVM TXs by sender + // Key: sender address + // Value: vector of mempool TX iterator + std::map, std::vector> evmTXs; while (mi != mempool.mapTx.get().end() || !mapModifiedTx.empty() || !failedNonces.empty()) { @@ -855,7 +854,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // Only check custom TXs if (txType != CustomTxType::None) { - if (txType == CustomTxType::EvmTx) { + if (txType == CustomTxType::EvmTx) { auto txMessage = customTypeToMessage(txType); if (!CustomMetadataParse(nHeight, Params().GetConsensus(), metadata, txMessage)) { customTxPassed = false; @@ -871,38 +870,31 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda break; } - auto& evmFeeMap = evmPackageContext.feeMap; - auto& evmAddressTxsMap = evmPackageContext.addressTxsMap; - - const auto addrKey = EvmAddressWithNonce { txResult.sender, txResult.nonce }; - if (auto feeEntry = evmFeeMap.find(addrKey); feeEntry != evmFeeMap.end()) { - // Key already exists. We check to see if we need to prioritize higher fee tx - const auto& lastFee = feeEntry->second; - if (txResult.prepay_fee > lastFee) { + const auto evmKey = std::make_pair(txResult.sender, txResult.nonce); + if (evmTXFees.count(evmKey)) { + const auto& gasFees = evmTXFees.at(evmKey); + if (txResult.prepay_fee > gasFees) { // Higher paying fee. Remove all TXs from sender and add to collection to add them again in order. - auto addrTxs = evmAddressTxsMap[addrKey.address]; - RemoveTxIters(txIters(addrTxs)); - // Remove all fee entries relating to the address - for (auto it = evmFeeMap.begin(); it != evmFeeMap.end();) { + RemoveEVMTransactions(evmTXs[txResult.sender]); + for (auto it = evmTXFees.begin(); it != evmTXFees.end();) { const auto& [sender, nonce] = it->first; - if (sender == addrKey.address) { - it = evmFeeMap.erase(it); + if (sender == txResult.sender) { + it = evmTXFees.erase(it); } else { ++it; } } - // Buggy code to fix below: - checkedTX.erase(addrTxs[addrKey.nonce]->GetTx().GetHash()); - addrTxs[addrKey.nonce] = sortedEntries[i]; - auto count{addrKey.nonce}; - for (const auto& [nonce, entry] : addrTxs) { + checkedTX.erase(evmTXs[txResult.sender][txResult.nonce]->GetTx().GetHash()); + evmTXs[txResult.sender][txResult.nonce] = sortedEntries[i]; + auto count{txResult.nonce}; + for (const auto& entry : evmTXs[txResult.sender]) { inBlock.erase(entry); checkedTX.erase(entry->GetTx().GetHash()); replaceByFee.emplace(count, entry); ++count; } - evmAddressTxsMap.erase(addrKey.address); - evm_remove_txs_by_sender(evmContext, addrKey.address); + evmTXs.erase(txResult.sender); + evm_remove_txs_by_sender(evmContext, txResult.sender); customTxPassed = false; break; } @@ -918,9 +910,8 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda break; } - auto addrNonce = EvmAddressWithNonce { txResult.sender, txResult.nonce }; - evmFeeMap.insert({addrNonce, txResult.prepay_fee}); - evmAddressTxsMap[txResult.sender].emplace(txResult.nonce, sortedEntries[i]); + evmTXFees.emplace(std::make_pair(txResult.sender, txResult.nonce), txResult.prepay_fee); + evmTXs[txResult.sender].push_back(sortedEntries[i]); } const auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmContext); diff --git a/src/miner.h b/src/miner.h index 026bdc72f2..610d483f55 100644 --- a/src/miner.h +++ b/src/miner.h @@ -216,9 +216,9 @@ class BlockAssembler * of updated descendants. */ int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); /** Remove failed TransferDoamin transactions from the block */ - void RemoveTxs(const std::set &txHashSet, const std::map &txFees); + void RemoveFailedTransactions(const std::vector &failedTransactions, const std::map &txFees); /** Remove specific TX from the block */ - void RemoveTxIters(const std::vector iters); + void RemoveEVMTransactions(const std::vector iters); }; /** Modify the extranonce in a block */ From b045dff6ab950ad62747f17f1d1d9f539ef126ce Mon Sep 17 00:00:00 2001 From: Bushstar Date: Tue, 25 Jul 2023 06:43:11 +0100 Subject: [PATCH 02/15] Fix segfault bug --- src/miner.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 66c5c89936..cd666aca91 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -716,10 +716,18 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // Value: fee std::map, uint64_t>, uint64_t> evmTXFees; + auto txIters = [](std::map &iterMap) -> std::vector { + std::vector txIters; + for (const auto& [nonce, it] : iterMap) { + txIters.push_back(it); + } + return txIters; + }; + // Used to track EVM TXs by sender // Key: sender address // Value: vector of mempool TX iterator - std::map, std::vector> evmTXs; + std::map, std::map> evmTXs; while (mi != mempool.mapTx.get().end() || !mapModifiedTx.empty() || !failedNonces.empty()) { @@ -875,7 +883,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda const auto& gasFees = evmTXFees.at(evmKey); if (txResult.prepay_fee > gasFees) { // Higher paying fee. Remove all TXs from sender and add to collection to add them again in order. - RemoveEVMTransactions(evmTXs[txResult.sender]); + RemoveEVMTransactions(txIters(evmTXs[txResult.sender])); for (auto it = evmTXFees.begin(); it != evmTXFees.end();) { const auto& [sender, nonce] = it->first; if (sender == txResult.sender) { @@ -887,7 +895,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda checkedTX.erase(evmTXs[txResult.sender][txResult.nonce]->GetTx().GetHash()); evmTXs[txResult.sender][txResult.nonce] = sortedEntries[i]; auto count{txResult.nonce}; - for (const auto& entry : evmTXs[txResult.sender]) { + for (const auto& [nonce, entry] : evmTXs[txResult.sender]) { inBlock.erase(entry); checkedTX.erase(entry->GetTx().GetHash()); replaceByFee.emplace(count, entry); @@ -911,7 +919,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda } evmTXFees.emplace(std::make_pair(txResult.sender, txResult.nonce), txResult.prepay_fee); - evmTXs[txResult.sender].push_back(sortedEntries[i]); + evmTXs[txResult.sender].emplace(txResult.nonce, sortedEntries[i]); } const auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmContext); From b98dd6f5c37a06dd27546cde9032d3b2790d709e Mon Sep 17 00:00:00 2001 From: Bushstar Date: Tue, 25 Jul 2023 12:30:25 +0100 Subject: [PATCH 03/15] Isolate EVM miner processing --- lib/ain-evm/src/evm.rs | 12 +- lib/ain-evm/src/txqueue.rs | 68 +++-- src/miner.cpp | 3 +- test/functional/test_runner.py | 490 ++++++++++++++++----------------- 4 files changed, 295 insertions(+), 278 deletions(-) diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index 12d231546e..4238d6dd4c 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -143,8 +143,8 @@ impl EVMServices { let mut executor = AinExecutor::new(&mut backend); - for (queue_tx, hash) in self.core.tx_queues.get_cloned_vec(context) { - match queue_tx { + for queue_item in self.core.tx_queues.get_cloned_vec(context) { + match queue_item.queue_tx { QueueTx::SignedTx(signed_tx) => { if ain_cpp_imports::past_changi_intermediate_height_4_height() { let nonce = executor.get_nonce(&signed_tx.sender); @@ -170,7 +170,7 @@ impl EVMServices { ); if !exit_reason.is_succeed() { - failed_transactions.push(hex::encode(hash)); + failed_transactions.push(hex::encode(queue_item.tx_hash)); } let gas_fee = calculate_gas_fee(&signed_tx, U256::from(used_gas), base_fee)?; @@ -188,7 +188,7 @@ impl EVMServices { ); if let Err(e) = executor.add_balance(address, amount) { debug!("[finalize_block] EvmIn failed with {e}"); - failed_transactions.push(hex::encode(hash)); + failed_transactions.push(hex::encode(queue_item.tx_hash)); } } QueueTx::BridgeTx(BridgeTx::EvmOut(BalanceUpdate { address, amount })) => { @@ -199,7 +199,7 @@ impl EVMServices { if let Err(e) = executor.sub_balance(address, amount) { debug!("[finalize_block] EvmOut failed with {e}"); - failed_transactions.push(hex::encode(hash)); + failed_transactions.push(hex::encode(queue_item.tx_hash)); } } } @@ -269,7 +269,7 @@ impl EVMServices { match self.core.tx_queues.get_total_fees(context) { Some(total_fees) => { if (total_burnt_fees + total_priority_fees) != U256::from(total_fees) { - return Err(anyhow!("EVM block rejected because block total fees != (burnt fees + priority fees). Burnt fees: {}, priority fees: {}", total_burnt_fees, total_priority_fees).into()); + return Err(anyhow!("EVM block rejected because block total fees != (burnt fees + priority fees). Burnt fees: {}, priority fees: {}, total fees: {}", total_burnt_fees, total_priority_fees, total_fees).into()); } } None => { diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index 34b9e6c475..f46edfc4e2 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -94,13 +94,13 @@ impl TransactionQueueMap { .unwrap() .get(&context_id) .ok_or(QueueError::NoSuchContext) - .map(|queue| queue.queue_tx((tx, hash), gas_used, base_fee))? + .map(|queue| queue.queue_tx(tx, hash, gas_used, base_fee))? } /// `drain_all` returns all transactions from the `TransactionQueue` associated with the /// provided context ID, removing them from the queue. Transactions are returned in the /// order they were added. - pub fn drain_all(&self, context_id: u64) -> Vec { + pub fn drain_all(&self, context_id: u64) -> Vec { self.queues .read() .unwrap() @@ -108,7 +108,7 @@ impl TransactionQueueMap { .map_or(Vec::new(), TransactionQueue::drain_all) } - pub fn get_cloned_vec(&self, context_id: u64) -> Vec { + pub fn get_cloned_vec(&self, context_id: u64) -> Vec { self.queues .read() .unwrap() @@ -173,14 +173,20 @@ pub enum QueueTx { BridgeTx(BridgeTx), } -type QueueTxWithNativeHash = (QueueTx, NativeTxHash); +#[derive(Debug, Clone)] +pub struct QueueTxItem { + pub queue_tx: QueueTx, + pub tx_hash: NativeTxHash, + pub tx_fee: u64, + pub gas_used: u64, +} /// The `TransactionQueue` holds a queue of transactions and a map of account nonces. /// It's used to manage and process transactions for different accounts. /// #[derive(Debug, Default)] pub struct TransactionQueue { - transactions: Mutex>, + transactions: Mutex>, account_nonces: Mutex>, total_fees: Mutex, total_gas_used: Mutex, @@ -206,7 +212,7 @@ impl TransactionQueue { self.transactions.lock().unwrap().clear(); } - pub fn drain_all(&self) -> Vec { + pub fn drain_all(&self) -> Vec { let mut total_fees = self.total_fees.lock().unwrap(); *total_fees = 0u64; @@ -217,20 +223,22 @@ impl TransactionQueue { .lock() .unwrap() .drain(..) - .collect::>() + .collect::>() } - pub fn get_cloned_vec(&self) -> Vec { + pub fn get_cloned_vec(&self) -> Vec { self.transactions.lock().unwrap().clone() } pub fn queue_tx( &self, - tx: QueueTxWithNativeHash, + tx: QueueTx, + tx_hash: NativeTxHash, gas_used: u64, base_fee: U256, ) -> Result<(), QueueError> { - if let QueueTx::SignedTx(signed_tx) = &tx.0 { + let mut gas_fee: u64 = 0; + if let QueueTx::SignedTx(signed_tx) = &tx { let mut account_nonces = self.account_nonces.lock().unwrap(); if let Some(nonce) = account_nonces.get(&signed_tx.sender) { if signed_tx.nonce() != nonce + 1 { @@ -239,7 +247,7 @@ impl TransactionQueue { } account_nonces.insert(signed_tx.sender, signed_tx.nonce()); - let gas_fee = match calculate_gas_fee(signed_tx, gas_used.into(), base_fee) { + gas_fee = match calculate_gas_fee(signed_tx, gas_used.into(), base_fee) { Ok(fee) => fee.as_u64(), Err(_) => return Err(QueueError::InvalidFee), }; @@ -250,7 +258,7 @@ impl TransactionQueue { let mut total_gas_used = self.total_gas_used.lock().unwrap(); *total_gas_used += gas_used; } - self.transactions.lock().unwrap().push(tx); + self.transactions.lock().unwrap().push(QueueTxItem { queue_tx: tx, tx_hash, tx_fee: gas_fee, gas_used }); Ok(()) } @@ -259,12 +267,20 @@ impl TransactionQueue { } pub fn remove_txs_by_sender(&self, sender: H160) { - self.transactions.lock().unwrap().retain(|(tx, _)| { - let tx_sender = match tx { + self.transactions.lock().unwrap().retain(|item| { + let tx_sender = match &item.queue_tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; - tx_sender != sender + if tx_sender == sender { + let mut total_fees = self.total_fees.lock().unwrap(); + *total_fees -= item.tx_fee; + + let mut total_gas_used = self.total_gas_used.lock().unwrap(); + *total_gas_used -= item.gas_used; + return false; + } + true }); self.account_nonces.lock().unwrap().remove(&sender); } @@ -335,10 +351,10 @@ mod tests { // Nonce 0, sender 0xe61a3a6eb316d773c773f4ce757a542f673023c6 let tx3 = QueueTx::SignedTx(Box::new(SignedTx::try_from("f869808502540be400832dc6c0943e338e722607a8c1eab615579ace4f6dedfa19fa80840adb1a9a2aa03d28d24808c3de08c606c5544772ded91913f648ad56556f181905208e206c85a00ecd0ba938fb89fc4a17ea333ea842c7305090dee9236e2b632578f9e5045cb3").unwrap())); - queue.queue_tx((tx1, H256::from_low_u64_be(1).into()), 0u64, U256::zero())?; - queue.queue_tx((tx2, H256::from_low_u64_be(2).into()), 0u64, U256::zero())?; + queue.queue_tx(tx1, H256::from_low_u64_be(1).into(), 0u64, U256::zero())?; + queue.queue_tx(tx2, H256::from_low_u64_be(2).into(), 0u64, U256::zero())?; // Should fail as nonce 2 is already queued for this sender - let queued = queue.queue_tx((tx3, H256::from_low_u64_be(3).into()), 0u64, U256::zero()); + let queued = queue.queue_tx(tx3, H256::from_low_u64_be(3).into(), 0u64, U256::zero()); assert!(matches!(queued, Err(QueueError::InvalidNonce { .. }))); Ok(()) } @@ -362,11 +378,11 @@ mod tests { // Nonce 0, sender 0xe61a3a6eb316d773c773f4ce757a542f673023c6 let tx4 = QueueTx::SignedTx(Box::new(SignedTx::try_from("f869808502540be400832dc6c0943e338e722607a8c1eab615579ace4f6dedfa19fa80840adb1a9a2aa03d28d24808c3de08c606c5544772ded91913f648ad56556f181905208e206c85a00ecd0ba938fb89fc4a17ea333ea842c7305090dee9236e2b632578f9e5045cb3").unwrap())); - queue.queue_tx((tx1, H256::from_low_u64_be(1).into()), 0u64, U256::zero())?; - queue.queue_tx((tx2, H256::from_low_u64_be(2).into()), 0u64, U256::zero())?; - queue.queue_tx((tx3, H256::from_low_u64_be(3).into()), 0u64, U256::zero())?; + queue.queue_tx(tx1, H256::from_low_u64_be(1).into(), 0u64, U256::zero())?; + queue.queue_tx(tx2, H256::from_low_u64_be(2).into(), 0u64, U256::zero())?; + queue.queue_tx(tx3, H256::from_low_u64_be(3).into(), 0u64, U256::zero())?; // Should fail as nonce 2 is already queued for this sender - let queued = queue.queue_tx((tx4, H256::from_low_u64_be(4).into()), 0u64, U256::zero()); + let queued = queue.queue_tx(tx4, H256::from_low_u64_be(4).into(), 0u64, U256::zero()); assert!(matches!(queued, Err(QueueError::InvalidNonce { .. }))); Ok(()) } @@ -387,10 +403,10 @@ mod tests { // Nonce 2, sender 0x6bc42fd533d6cb9d973604155e1f7197a3b0e703 let tx4 = QueueTx::SignedTx(Box::new(SignedTx::try_from("f869028502540be400832dc6c0943e338e722607a8c1eab615579ace4f6dedfa19fa80840adb1a9a2aa09588b47d2cd3f474d6384309cca5cb8e360cb137679f0a1589a1c184a15cb27ca0453ddbf808b83b279cac3226b61a9d83855aba60ae0d3a8407cba0634da7459d").unwrap())); - queue.queue_tx((tx1, H256::from_low_u64_be(1).into()), 0u64, U256::zero())?; - queue.queue_tx((tx2, H256::from_low_u64_be(2).into()), 0u64, U256::zero())?; - queue.queue_tx((tx3, H256::from_low_u64_be(3).into()), 0u64, U256::zero())?; - queue.queue_tx((tx4, H256::from_low_u64_be(4).into()), 0u64, U256::zero())?; + queue.queue_tx(tx1, H256::from_low_u64_be(1).into(), 0u64, U256::zero())?; + queue.queue_tx(tx2, H256::from_low_u64_be(2).into(), 0u64, U256::zero())?; + queue.queue_tx(tx3, H256::from_low_u64_be(3).into(), 0u64, U256::zero())?; + queue.queue_tx(tx4, H256::from_low_u64_be(4).into(), 0u64, U256::zero())?; Ok(()) } } diff --git a/src/miner.cpp b/src/miner.cpp index cd666aca91..e4cf42a0c0 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -287,6 +287,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc std::copy(nodePtr->ownerAuthAddress.begin(), nodePtr->ownerAuthAddress.end(), beneficiary.begin()); CrossBoundaryResult result; auto blockResult = evm_try_finalize(result, evmContext, false, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), beneficiary, blockTime); + LogPrintf("XXX result %d reason %s\n", result.ok, result.reason); evm_discard_context(evmContext); const auto blockHash = std::vector(blockResult.block_hash.begin(), blockResult.block_hash.end()); @@ -872,7 +873,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda const auto obj = std::get(txMessage); CrossBoundaryResult result; - const auto txResult = evm_try_validate_raw_tx(result, HexStr(obj.evmTx), evmContext); + const auto txResult = evm_try_prevalidate_raw_tx(result, HexStr(obj.evmTx)); if (!result.ok) { customTxPassed = false; break; diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index f2b562c331..bd2e773133 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -85,252 +85,252 @@ # Scripts that are run by default. # Longest test should go first, to favor running tests in parallel # vv Tests less than 5m vv - 'mining_getblocktemplate_longpoll.py', - 'feature_maxuploadtarget.py', - 'rpc_fundrawtransaction.py', - 'p2p_compactblocks.py', - 'feature_segwit.py', - # vv Tests less than 2m vv - 'wallet_basic.py', - 'wallet_labels.py', - 'p2p_segwit.py', - 'p2p_segwit2.py', - 'p2p_timeouts.py', - 'p2p_tx_download.py', - 'wallet_dump.py', - 'wallet_listtransactions.py', - # vv Tests less than 60s vv - 'p2p_sendheaders.py', - 'wallet_zapwallettxes.py', - 'wallet_importmulti.py', - 'mempool_limit.py', - 'rpc_txoutproof.py', - 'wallet_listreceivedby.py', - 'wallet_abandonconflict.py', - 'feature_csv_activation.py', - 'rpc_rawtransaction.py', - 'wallet_address_types.py', # nodes = 6 - 'feature_bip68_sequence.py', - 'p2p_feefilter.py', - 'feature_reindex.py', - 'feature_abortnode.py', - # vv Tests less than 30s vv - 'wallet_keypool_topup.py', - 'feature_stored_interest.py', - 'feature_fee_estimation.py', - 'feature_dip1.py', - 'feature_dfip8_communitybalances.py', - 'feature_anchor_rewards.py', - 'feature_anchorauths_pruning.py', - 'feature_autoauth.py', - 'feature_lock_unspends.py', - 'feature_bitcoin_wallet.py', - 'feature_bitcoin_htlc.py', - 'feature_asymmetric_fee.py', - 'feature_token_split.py', - 'feature_token_split_mechanism.py', - 'feature_commission_fix.py', - 'feature_token_split_usd_value.py', - 'feature_token_merge_usd_value.py', - 'feature_token_merge.py', - 'feature_communitybalance_reorg.py', - 'feature_auth_return_change.py', - 'feature_setgov.py', - 'feature_rpcstats.py', - 'feature_futures.py', - 'interface_zmq.py', - 'feature_restore_utxo.py', - 'interface_defi_cli.py', - 'mempool_resurrect.py', - 'wallet_txn_doublespend.py --mineblock', - 'feature_migrate_v1_in_futures.py', - 'wallet_txn_clone.py', - 'wallet_txn_clone.py --segwit', - 'rpc_getchaintips.py', - 'rpc_misc.py', - 'rpc_mn_basic.py', - 'feature_smart_contracts.py', - 'feature_reject_customtxs.py', - 'feature_initdist.py', - 'feature_tokens_basic.py', - 'feature_tokens_minting.py', - 'feature_tokens_dat.py', - 'feature_accounts_n_utxos.py', - 'feature_token_fork.py', - 'feature_tokens_multisig.py', - 'interface_rest.py', - 'mempool_spend_coinbase.py', - 'wallet_avoidreuse.py', - 'mempool_reorg.py', - 'mempool_persist.py', - 'wallet_multiwallet.py', - 'wallet_multiwallet.py --usecli', - 'wallet_createwallet.py', - 'wallet_createwallet.py --usecli', - 'feature_negative_loan_interest.py', - 'wallet_watchonly.py', - 'wallet_watchonly.py --usecli', - 'feature_poolpair.py', - 'feature_poolpair_liquidity.py', - 'feature_icx_orderbook.py', - 'feature_icx_orderbook_errors.py', - 'feature_loan_setcollateraltoken.py', - 'feature_loan_setloantoken.py', - 'feature_loan_basics.py', - 'feature_loan_payback_dfi.py', - 'feature_loan_payback_dfi_v2.py', - 'feature_loan_get_interest.py', - 'feature_loan_listauctions.py', - 'feature_loan_auctions.py', - 'feature_loan_dusd_as_collateral.py', - 'feature_loan_payback_with_collateral.py', - 'feature_any_accounts_to_accounts.py', - 'feature_community_development_funds.py', - 'feature_sendtokenstoaddress.py', - 'feature_poolswap.py', - 'feature_split_migrate_lock.py', - 'feature_poolswap_composite.py', - 'feature_poolswap_mechanism.py', - 'feature_poolswap_mainnet.py', - 'feature_prevent_bad_tx_propagation.py', - 'feature_masternode_operator.py', - 'feature_mine_cached.py', - 'feature_mempool_dakota.py', - 'feature_consortium.py', - 'interface_http.py', - 'interface_http_cors.py', - 'interface_rpc.py', - 'rpc_psbt.py', - 'rpc_users.py', - 'feature_proxy.py', - 'rpc_signrawtransaction.py', - 'wallet_groups.py', - 'p2p_disconnect_ban.py', - 'rpc_decodescript.py', - 'rpc_blockchain.py', - 'rpc_deprecated.py', - 'wallet_disable.py', - 'rpc_net.py', - 'wallet_keypool.py', - 'p2p_mempool.py', - 'rpc_setban.py', - 'p2p_blocksonly.py', - 'mining_prioritisetransaction.py', - 'p2p_invalid_locator.py', - 'p2p_invalid_block.py', - 'p2p_invalid_messages.py', - 'p2p_invalid_tx.py', - 'feature_foundation_migration.py', - 'feature_assumevalid.py', - 'example_test.py', - 'feature_jellyfish_initial_funds.py', - 'wallet_txn_doublespend.py', - 'wallet_txn_clone.py --mineblock', - 'feature_notifications.py', - 'rpc_getblockfilter.py', - 'rpc_invalidateblock.py', - 'feature_rbf.py', - 'mempool_packages.py', - 'mempool_package_onemore.py', - 'rpc_createmultisig.py', - 'feature_versionbits_warning.py', - 'rpc_preciousblock.py', - 'wallet_importprunedfunds.py', - 'p2p_leak_tx.py', - 'rpc_signmessage.py', - 'wallet_balance.py', - 'feature_nulldummy.py', - 'wallet_import_rescan.py', # nodes = 6 - 'wallet_import_with_label.py', - 'rpc_bind.py --ipv4', - 'rpc_bind.py --ipv6', - 'rpc_bind.py --nonloopback', - 'mining_basic.py', - 'wallet_bumpfee.py', - 'wallet_bumpfee_totalfee_deprecation.py', - 'rpc_named_arguments.py', - 'wallet_listsinceblock.py', - 'p2p_leak.py', - 'feature_higher_collateral_factor.py', - 'feature_skip_collateral_factor_check.py', - 'wallet_encryption.py', - 'feature_dersig.py', - 'feature_cltv.py', - 'rpc_updatemasternode.py', - 'rpc_uptime.py', - 'feature_longterm_lockin.py', - 'wallet_resendwallettransactions.py', - 'feature_custom_poolreward.py', - 'wallet_fallbackfee.py', - 'feature_token_lock.py', - 'feature_minchainwork.py', - 'rpc_getblockstats.py', - 'feature_median_time.py', - 'wallet_create_tx.py', - 'p2p_fingerprint.py', - 'feature_uacomment.py', - 'wallet_coinbase_category.py', - 'feature_filelock.py', - 'p2p_unrequested_blocks.py', - 'rpc_listaccounthistory.py', - 'feature_listaccounthistory_multiaccountquery.py', - 'rpc_getaccounthistory.py', - 'feature_includeconf.py', - 'rpc_deriveaddresses.py', - 'rpc_deriveaddresses.py --usecli', - 'rpc_scantxoutset.py', - 'rpc_getcustomtx.py', - 'rpc_listvaulthistory.py', - 'feature_logging.py', - 'feature_loan_scheme.py', - # 'feature_forced_reward_address.py', - 'feature_loan_vault.py', - 'feature_loan_deposittovault.py', - 'feature_loan_interest.py', - 'feature_loan_estimateloan.py', - 'feature_loan_priceupdate.py', - 'feature_loan_vaultstate.py', - 'feature_loan.py', - 'feature_evm_contracts.py', - 'feature_evm_fee.py', - 'feature_evm_genesis.py', - 'feature_evm_rollback.py', - 'feature_evm_rpc_transaction.py', - 'feature_evm_rpc.py', - 'feature_evm_vmmap_rpc.py', - 'feature_evm_smart_contract.py', - 'feature_evm_transferdomain.py', + # 'mining_getblocktemplate_longpoll.py', + # 'feature_maxuploadtarget.py', + # 'rpc_fundrawtransaction.py', + # 'p2p_compactblocks.py', + # 'feature_segwit.py', + # # vv Tests less than 2m vv + # 'wallet_basic.py', + # 'wallet_labels.py', + # 'p2p_segwit.py', + # 'p2p_segwit2.py', + # 'p2p_timeouts.py', + # 'p2p_tx_download.py', + # 'wallet_dump.py', + # 'wallet_listtransactions.py', + # # vv Tests less than 60s vv + # 'p2p_sendheaders.py', + # 'wallet_zapwallettxes.py', + # 'wallet_importmulti.py', + # 'mempool_limit.py', + # 'rpc_txoutproof.py', + # 'wallet_listreceivedby.py', + # 'wallet_abandonconflict.py', + # 'feature_csv_activation.py', + # 'rpc_rawtransaction.py', + # 'wallet_address_types.py', # nodes = 6 + # 'feature_bip68_sequence.py', + # 'p2p_feefilter.py', + # 'feature_reindex.py', + # 'feature_abortnode.py', + # # vv Tests less than 30s vv + # 'wallet_keypool_topup.py', + # 'feature_stored_interest.py', + # 'feature_fee_estimation.py', + # 'feature_dip1.py', + # 'feature_dfip8_communitybalances.py', + # 'feature_anchor_rewards.py', + # 'feature_anchorauths_pruning.py', + # 'feature_autoauth.py', + # 'feature_lock_unspends.py', + # 'feature_bitcoin_wallet.py', + # 'feature_bitcoin_htlc.py', + # 'feature_asymmetric_fee.py', + # 'feature_token_split.py', + # 'feature_token_split_mechanism.py', + # 'feature_commission_fix.py', + # 'feature_token_split_usd_value.py', + # 'feature_token_merge_usd_value.py', + # 'feature_token_merge.py', + # 'feature_communitybalance_reorg.py', + # 'feature_auth_return_change.py', + # 'feature_setgov.py', + # 'feature_rpcstats.py', + # 'feature_futures.py', + # 'interface_zmq.py', + # 'feature_restore_utxo.py', + # 'interface_defi_cli.py', + # 'mempool_resurrect.py', + # 'wallet_txn_doublespend.py --mineblock', + # 'feature_migrate_v1_in_futures.py', + # 'wallet_txn_clone.py', + # 'wallet_txn_clone.py --segwit', + # 'rpc_getchaintips.py', + # 'rpc_misc.py', + # 'rpc_mn_basic.py', + # 'feature_smart_contracts.py', + # 'feature_reject_customtxs.py', + # 'feature_initdist.py', + # 'feature_tokens_basic.py', + # 'feature_tokens_minting.py', + # 'feature_tokens_dat.py', + # 'feature_accounts_n_utxos.py', + # 'feature_token_fork.py', + # 'feature_tokens_multisig.py', + # 'interface_rest.py', + # 'mempool_spend_coinbase.py', + # 'wallet_avoidreuse.py', + # 'mempool_reorg.py', + # 'mempool_persist.py', + # 'wallet_multiwallet.py', + # 'wallet_multiwallet.py --usecli', + # 'wallet_createwallet.py', + # 'wallet_createwallet.py --usecli', + # 'feature_negative_loan_interest.py', + # 'wallet_watchonly.py', + # 'wallet_watchonly.py --usecli', + # 'feature_poolpair.py', + # 'feature_poolpair_liquidity.py', + # 'feature_icx_orderbook.py', + # 'feature_icx_orderbook_errors.py', + # 'feature_loan_setcollateraltoken.py', + # 'feature_loan_setloantoken.py', + # 'feature_loan_basics.py', + # 'feature_loan_payback_dfi.py', + # 'feature_loan_payback_dfi_v2.py', + # 'feature_loan_get_interest.py', + # 'feature_loan_listauctions.py', + # 'feature_loan_auctions.py', + # 'feature_loan_dusd_as_collateral.py', + # 'feature_loan_payback_with_collateral.py', + # 'feature_any_accounts_to_accounts.py', + # 'feature_community_development_funds.py', + # 'feature_sendtokenstoaddress.py', + # 'feature_poolswap.py', + # 'feature_split_migrate_lock.py', + # 'feature_poolswap_composite.py', + # 'feature_poolswap_mechanism.py', + # 'feature_poolswap_mainnet.py', + # 'feature_prevent_bad_tx_propagation.py', + # 'feature_masternode_operator.py', + # 'feature_mine_cached.py', + # 'feature_mempool_dakota.py', + # 'feature_consortium.py', + # 'interface_http.py', + # 'interface_http_cors.py', + # 'interface_rpc.py', + # 'rpc_psbt.py', + # 'rpc_users.py', + # 'feature_proxy.py', + # 'rpc_signrawtransaction.py', + # 'wallet_groups.py', + # 'p2p_disconnect_ban.py', + # 'rpc_decodescript.py', + # 'rpc_blockchain.py', + # 'rpc_deprecated.py', + # 'wallet_disable.py', + # 'rpc_net.py', + # 'wallet_keypool.py', + # 'p2p_mempool.py', + # 'rpc_setban.py', + # 'p2p_blocksonly.py', + # 'mining_prioritisetransaction.py', + # 'p2p_invalid_locator.py', + # 'p2p_invalid_block.py', + # 'p2p_invalid_messages.py', + # 'p2p_invalid_tx.py', + # 'feature_foundation_migration.py', + # 'feature_assumevalid.py', + # 'example_test.py', + # 'feature_jellyfish_initial_funds.py', + # 'wallet_txn_doublespend.py', + # 'wallet_txn_clone.py --mineblock', + # 'feature_notifications.py', + # 'rpc_getblockfilter.py', + # 'rpc_invalidateblock.py', + # 'feature_rbf.py', + # 'mempool_packages.py', + # 'mempool_package_onemore.py', + # 'rpc_createmultisig.py', + # 'feature_versionbits_warning.py', + # 'rpc_preciousblock.py', + # 'wallet_importprunedfunds.py', + # 'p2p_leak_tx.py', + # 'rpc_signmessage.py', + # 'wallet_balance.py', + # 'feature_nulldummy.py', + # 'wallet_import_rescan.py', # nodes = 6 + # 'wallet_import_with_label.py', + # 'rpc_bind.py --ipv4', + # 'rpc_bind.py --ipv6', + # 'rpc_bind.py --nonloopback', + # 'mining_basic.py', + # 'wallet_bumpfee.py', + # 'wallet_bumpfee_totalfee_deprecation.py', + # 'rpc_named_arguments.py', + # 'wallet_listsinceblock.py', + # 'p2p_leak.py', + # 'feature_higher_collateral_factor.py', + # 'feature_skip_collateral_factor_check.py', + # 'wallet_encryption.py', + # 'feature_dersig.py', + # 'feature_cltv.py', + # 'rpc_updatemasternode.py', + # 'rpc_uptime.py', + # 'feature_longterm_lockin.py', + # 'wallet_resendwallettransactions.py', + # 'feature_custom_poolreward.py', + # 'wallet_fallbackfee.py', + # 'feature_token_lock.py', + # 'feature_minchainwork.py', + # 'rpc_getblockstats.py', + # 'feature_median_time.py', + # 'wallet_create_tx.py', + # 'p2p_fingerprint.py', + # 'feature_uacomment.py', + # 'wallet_coinbase_category.py', + # 'feature_filelock.py', + # 'p2p_unrequested_blocks.py', + # 'rpc_listaccounthistory.py', + # 'feature_listaccounthistory_multiaccountquery.py', + # 'rpc_getaccounthistory.py', + # 'feature_includeconf.py', + # 'rpc_deriveaddresses.py', + # 'rpc_deriveaddresses.py --usecli', + # 'rpc_scantxoutset.py', + # 'rpc_getcustomtx.py', + # 'rpc_listvaulthistory.py', + # 'feature_logging.py', + # 'feature_loan_scheme.py', + # # 'feature_forced_reward_address.py', + # 'feature_loan_vault.py', + # 'feature_loan_deposittovault.py', + # 'feature_loan_interest.py', + # 'feature_loan_estimateloan.py', + # 'feature_loan_priceupdate.py', + # 'feature_loan_vaultstate.py', + # 'feature_loan.py', + # 'feature_evm_contracts.py', + # 'feature_evm_fee.py', + # 'feature_evm_genesis.py', + # 'feature_evm_rollback.py', + # 'feature_evm_rpc_transaction.py', + # 'feature_evm_rpc.py', + # 'feature_evm_vmmap_rpc.py', + # 'feature_evm_smart_contract.py', + # 'feature_evm_transferdomain.py', 'feature_evm.py', - 'feature_loan_low_interest.py', - 'feature_loan_estimatecollateral.py', - 'feature_vault_pct_check_factor.py', - 'p2p_node_network_limited.py', - 'p2p_permissions.py', - 'feature_blocksdir.py', - 'feature_config_args.py', - 'feature_account_mining.py', - 'feature_accounts_validation.py', - 'feature_listaccounts_pagination.py', - 'feature_on_chain_government.py', - 'feature_on_chain_government_voting_period_alignment.py', - 'feature_on_chain_government_fee_distribution.py', - 'feature_on_chain_government_voting_scenarios.py', - 'rpc_listgovproposals.py', - 'rpc_help.py', - 'feature_help.py', - 'feature_shutdown.py', - 'feature_oracles.py', - 'feature_checkpoint.py', - 'rpc_getmininginfo.py', - 'feature_burn_address.py', - 'feature_eunos_balances.py', - 'feature_sendutxosfrom.py', - 'feature_testpoolswap.py', - 'feature_update_mn.py', - 'feature_block_reward.py', - 'feature_negative_interest.py', - 'rpc_getstoredinterest.py', - 'feature_dusd_loans.py', + # 'feature_loan_low_interest.py', + # 'feature_loan_estimatecollateral.py', + # 'feature_vault_pct_check_factor.py', + # 'p2p_node_network_limited.py', + # 'p2p_permissions.py', + # 'feature_blocksdir.py', + # 'feature_config_args.py', + # 'feature_account_mining.py', + # 'feature_accounts_validation.py', + # 'feature_listaccounts_pagination.py', + # 'feature_on_chain_government.py', + # 'feature_on_chain_government_voting_period_alignment.py', + # 'feature_on_chain_government_fee_distribution.py', + # 'feature_on_chain_government_voting_scenarios.py', + # 'rpc_listgovproposals.py', + # 'rpc_help.py', + # 'feature_help.py', + # 'feature_shutdown.py', + # 'feature_oracles.py', + # 'feature_checkpoint.py', + # 'rpc_getmininginfo.py', + # 'feature_burn_address.py', + # 'feature_eunos_balances.py', + # 'feature_sendutxosfrom.py', + # 'feature_testpoolswap.py', + # 'feature_update_mn.py', + # 'feature_block_reward.py', + # 'feature_negative_interest.py', + # 'rpc_getstoredinterest.py', + # 'feature_dusd_loans.py', # Don't append tests at the end to avoid merge conflicts # Put them in a random line within the section that fits their approximate run-time ] From a53e9c3183fca8d14ebc68a0987c086d86ca6f04 Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 25 Jul 2023 19:00:09 +0800 Subject: [PATCH 04/15] fix lint --- lib/ain-evm/src/txqueue.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index f46edfc4e2..1512dc121c 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -258,7 +258,12 @@ impl TransactionQueue { let mut total_gas_used = self.total_gas_used.lock().unwrap(); *total_gas_used += gas_used; } - self.transactions.lock().unwrap().push(QueueTxItem { queue_tx: tx, tx_hash, tx_fee: gas_fee, gas_used }); + self.transactions.lock().unwrap().push(QueueTxItem { + queue_tx: tx, + tx_hash, + tx_fee: gas_fee, + gas_used, + }); Ok(()) } @@ -275,7 +280,7 @@ impl TransactionQueue { if tx_sender == sender { let mut total_fees = self.total_fees.lock().unwrap(); *total_fees -= item.tx_fee; - + let mut total_gas_used = self.total_gas_used.lock().unwrap(); *total_gas_used -= item.gas_used; return false; From d5bab2be5979bae6532ea770683369cfabf9e78a Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 25 Jul 2023 19:01:56 +0800 Subject: [PATCH 05/15] Revert test runner --- test/functional/test_runner.py | 490 ++++++++++++++++----------------- 1 file changed, 245 insertions(+), 245 deletions(-) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index bd2e773133..f2b562c331 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -85,252 +85,252 @@ # Scripts that are run by default. # Longest test should go first, to favor running tests in parallel # vv Tests less than 5m vv - # 'mining_getblocktemplate_longpoll.py', - # 'feature_maxuploadtarget.py', - # 'rpc_fundrawtransaction.py', - # 'p2p_compactblocks.py', - # 'feature_segwit.py', - # # vv Tests less than 2m vv - # 'wallet_basic.py', - # 'wallet_labels.py', - # 'p2p_segwit.py', - # 'p2p_segwit2.py', - # 'p2p_timeouts.py', - # 'p2p_tx_download.py', - # 'wallet_dump.py', - # 'wallet_listtransactions.py', - # # vv Tests less than 60s vv - # 'p2p_sendheaders.py', - # 'wallet_zapwallettxes.py', - # 'wallet_importmulti.py', - # 'mempool_limit.py', - # 'rpc_txoutproof.py', - # 'wallet_listreceivedby.py', - # 'wallet_abandonconflict.py', - # 'feature_csv_activation.py', - # 'rpc_rawtransaction.py', - # 'wallet_address_types.py', # nodes = 6 - # 'feature_bip68_sequence.py', - # 'p2p_feefilter.py', - # 'feature_reindex.py', - # 'feature_abortnode.py', - # # vv Tests less than 30s vv - # 'wallet_keypool_topup.py', - # 'feature_stored_interest.py', - # 'feature_fee_estimation.py', - # 'feature_dip1.py', - # 'feature_dfip8_communitybalances.py', - # 'feature_anchor_rewards.py', - # 'feature_anchorauths_pruning.py', - # 'feature_autoauth.py', - # 'feature_lock_unspends.py', - # 'feature_bitcoin_wallet.py', - # 'feature_bitcoin_htlc.py', - # 'feature_asymmetric_fee.py', - # 'feature_token_split.py', - # 'feature_token_split_mechanism.py', - # 'feature_commission_fix.py', - # 'feature_token_split_usd_value.py', - # 'feature_token_merge_usd_value.py', - # 'feature_token_merge.py', - # 'feature_communitybalance_reorg.py', - # 'feature_auth_return_change.py', - # 'feature_setgov.py', - # 'feature_rpcstats.py', - # 'feature_futures.py', - # 'interface_zmq.py', - # 'feature_restore_utxo.py', - # 'interface_defi_cli.py', - # 'mempool_resurrect.py', - # 'wallet_txn_doublespend.py --mineblock', - # 'feature_migrate_v1_in_futures.py', - # 'wallet_txn_clone.py', - # 'wallet_txn_clone.py --segwit', - # 'rpc_getchaintips.py', - # 'rpc_misc.py', - # 'rpc_mn_basic.py', - # 'feature_smart_contracts.py', - # 'feature_reject_customtxs.py', - # 'feature_initdist.py', - # 'feature_tokens_basic.py', - # 'feature_tokens_minting.py', - # 'feature_tokens_dat.py', - # 'feature_accounts_n_utxos.py', - # 'feature_token_fork.py', - # 'feature_tokens_multisig.py', - # 'interface_rest.py', - # 'mempool_spend_coinbase.py', - # 'wallet_avoidreuse.py', - # 'mempool_reorg.py', - # 'mempool_persist.py', - # 'wallet_multiwallet.py', - # 'wallet_multiwallet.py --usecli', - # 'wallet_createwallet.py', - # 'wallet_createwallet.py --usecli', - # 'feature_negative_loan_interest.py', - # 'wallet_watchonly.py', - # 'wallet_watchonly.py --usecli', - # 'feature_poolpair.py', - # 'feature_poolpair_liquidity.py', - # 'feature_icx_orderbook.py', - # 'feature_icx_orderbook_errors.py', - # 'feature_loan_setcollateraltoken.py', - # 'feature_loan_setloantoken.py', - # 'feature_loan_basics.py', - # 'feature_loan_payback_dfi.py', - # 'feature_loan_payback_dfi_v2.py', - # 'feature_loan_get_interest.py', - # 'feature_loan_listauctions.py', - # 'feature_loan_auctions.py', - # 'feature_loan_dusd_as_collateral.py', - # 'feature_loan_payback_with_collateral.py', - # 'feature_any_accounts_to_accounts.py', - # 'feature_community_development_funds.py', - # 'feature_sendtokenstoaddress.py', - # 'feature_poolswap.py', - # 'feature_split_migrate_lock.py', - # 'feature_poolswap_composite.py', - # 'feature_poolswap_mechanism.py', - # 'feature_poolswap_mainnet.py', - # 'feature_prevent_bad_tx_propagation.py', - # 'feature_masternode_operator.py', - # 'feature_mine_cached.py', - # 'feature_mempool_dakota.py', - # 'feature_consortium.py', - # 'interface_http.py', - # 'interface_http_cors.py', - # 'interface_rpc.py', - # 'rpc_psbt.py', - # 'rpc_users.py', - # 'feature_proxy.py', - # 'rpc_signrawtransaction.py', - # 'wallet_groups.py', - # 'p2p_disconnect_ban.py', - # 'rpc_decodescript.py', - # 'rpc_blockchain.py', - # 'rpc_deprecated.py', - # 'wallet_disable.py', - # 'rpc_net.py', - # 'wallet_keypool.py', - # 'p2p_mempool.py', - # 'rpc_setban.py', - # 'p2p_blocksonly.py', - # 'mining_prioritisetransaction.py', - # 'p2p_invalid_locator.py', - # 'p2p_invalid_block.py', - # 'p2p_invalid_messages.py', - # 'p2p_invalid_tx.py', - # 'feature_foundation_migration.py', - # 'feature_assumevalid.py', - # 'example_test.py', - # 'feature_jellyfish_initial_funds.py', - # 'wallet_txn_doublespend.py', - # 'wallet_txn_clone.py --mineblock', - # 'feature_notifications.py', - # 'rpc_getblockfilter.py', - # 'rpc_invalidateblock.py', - # 'feature_rbf.py', - # 'mempool_packages.py', - # 'mempool_package_onemore.py', - # 'rpc_createmultisig.py', - # 'feature_versionbits_warning.py', - # 'rpc_preciousblock.py', - # 'wallet_importprunedfunds.py', - # 'p2p_leak_tx.py', - # 'rpc_signmessage.py', - # 'wallet_balance.py', - # 'feature_nulldummy.py', - # 'wallet_import_rescan.py', # nodes = 6 - # 'wallet_import_with_label.py', - # 'rpc_bind.py --ipv4', - # 'rpc_bind.py --ipv6', - # 'rpc_bind.py --nonloopback', - # 'mining_basic.py', - # 'wallet_bumpfee.py', - # 'wallet_bumpfee_totalfee_deprecation.py', - # 'rpc_named_arguments.py', - # 'wallet_listsinceblock.py', - # 'p2p_leak.py', - # 'feature_higher_collateral_factor.py', - # 'feature_skip_collateral_factor_check.py', - # 'wallet_encryption.py', - # 'feature_dersig.py', - # 'feature_cltv.py', - # 'rpc_updatemasternode.py', - # 'rpc_uptime.py', - # 'feature_longterm_lockin.py', - # 'wallet_resendwallettransactions.py', - # 'feature_custom_poolreward.py', - # 'wallet_fallbackfee.py', - # 'feature_token_lock.py', - # 'feature_minchainwork.py', - # 'rpc_getblockstats.py', - # 'feature_median_time.py', - # 'wallet_create_tx.py', - # 'p2p_fingerprint.py', - # 'feature_uacomment.py', - # 'wallet_coinbase_category.py', - # 'feature_filelock.py', - # 'p2p_unrequested_blocks.py', - # 'rpc_listaccounthistory.py', - # 'feature_listaccounthistory_multiaccountquery.py', - # 'rpc_getaccounthistory.py', - # 'feature_includeconf.py', - # 'rpc_deriveaddresses.py', - # 'rpc_deriveaddresses.py --usecli', - # 'rpc_scantxoutset.py', - # 'rpc_getcustomtx.py', - # 'rpc_listvaulthistory.py', - # 'feature_logging.py', - # 'feature_loan_scheme.py', - # # 'feature_forced_reward_address.py', - # 'feature_loan_vault.py', - # 'feature_loan_deposittovault.py', - # 'feature_loan_interest.py', - # 'feature_loan_estimateloan.py', - # 'feature_loan_priceupdate.py', - # 'feature_loan_vaultstate.py', - # 'feature_loan.py', - # 'feature_evm_contracts.py', - # 'feature_evm_fee.py', - # 'feature_evm_genesis.py', - # 'feature_evm_rollback.py', - # 'feature_evm_rpc_transaction.py', - # 'feature_evm_rpc.py', - # 'feature_evm_vmmap_rpc.py', - # 'feature_evm_smart_contract.py', - # 'feature_evm_transferdomain.py', + 'mining_getblocktemplate_longpoll.py', + 'feature_maxuploadtarget.py', + 'rpc_fundrawtransaction.py', + 'p2p_compactblocks.py', + 'feature_segwit.py', + # vv Tests less than 2m vv + 'wallet_basic.py', + 'wallet_labels.py', + 'p2p_segwit.py', + 'p2p_segwit2.py', + 'p2p_timeouts.py', + 'p2p_tx_download.py', + 'wallet_dump.py', + 'wallet_listtransactions.py', + # vv Tests less than 60s vv + 'p2p_sendheaders.py', + 'wallet_zapwallettxes.py', + 'wallet_importmulti.py', + 'mempool_limit.py', + 'rpc_txoutproof.py', + 'wallet_listreceivedby.py', + 'wallet_abandonconflict.py', + 'feature_csv_activation.py', + 'rpc_rawtransaction.py', + 'wallet_address_types.py', # nodes = 6 + 'feature_bip68_sequence.py', + 'p2p_feefilter.py', + 'feature_reindex.py', + 'feature_abortnode.py', + # vv Tests less than 30s vv + 'wallet_keypool_topup.py', + 'feature_stored_interest.py', + 'feature_fee_estimation.py', + 'feature_dip1.py', + 'feature_dfip8_communitybalances.py', + 'feature_anchor_rewards.py', + 'feature_anchorauths_pruning.py', + 'feature_autoauth.py', + 'feature_lock_unspends.py', + 'feature_bitcoin_wallet.py', + 'feature_bitcoin_htlc.py', + 'feature_asymmetric_fee.py', + 'feature_token_split.py', + 'feature_token_split_mechanism.py', + 'feature_commission_fix.py', + 'feature_token_split_usd_value.py', + 'feature_token_merge_usd_value.py', + 'feature_token_merge.py', + 'feature_communitybalance_reorg.py', + 'feature_auth_return_change.py', + 'feature_setgov.py', + 'feature_rpcstats.py', + 'feature_futures.py', + 'interface_zmq.py', + 'feature_restore_utxo.py', + 'interface_defi_cli.py', + 'mempool_resurrect.py', + 'wallet_txn_doublespend.py --mineblock', + 'feature_migrate_v1_in_futures.py', + 'wallet_txn_clone.py', + 'wallet_txn_clone.py --segwit', + 'rpc_getchaintips.py', + 'rpc_misc.py', + 'rpc_mn_basic.py', + 'feature_smart_contracts.py', + 'feature_reject_customtxs.py', + 'feature_initdist.py', + 'feature_tokens_basic.py', + 'feature_tokens_minting.py', + 'feature_tokens_dat.py', + 'feature_accounts_n_utxos.py', + 'feature_token_fork.py', + 'feature_tokens_multisig.py', + 'interface_rest.py', + 'mempool_spend_coinbase.py', + 'wallet_avoidreuse.py', + 'mempool_reorg.py', + 'mempool_persist.py', + 'wallet_multiwallet.py', + 'wallet_multiwallet.py --usecli', + 'wallet_createwallet.py', + 'wallet_createwallet.py --usecli', + 'feature_negative_loan_interest.py', + 'wallet_watchonly.py', + 'wallet_watchonly.py --usecli', + 'feature_poolpair.py', + 'feature_poolpair_liquidity.py', + 'feature_icx_orderbook.py', + 'feature_icx_orderbook_errors.py', + 'feature_loan_setcollateraltoken.py', + 'feature_loan_setloantoken.py', + 'feature_loan_basics.py', + 'feature_loan_payback_dfi.py', + 'feature_loan_payback_dfi_v2.py', + 'feature_loan_get_interest.py', + 'feature_loan_listauctions.py', + 'feature_loan_auctions.py', + 'feature_loan_dusd_as_collateral.py', + 'feature_loan_payback_with_collateral.py', + 'feature_any_accounts_to_accounts.py', + 'feature_community_development_funds.py', + 'feature_sendtokenstoaddress.py', + 'feature_poolswap.py', + 'feature_split_migrate_lock.py', + 'feature_poolswap_composite.py', + 'feature_poolswap_mechanism.py', + 'feature_poolswap_mainnet.py', + 'feature_prevent_bad_tx_propagation.py', + 'feature_masternode_operator.py', + 'feature_mine_cached.py', + 'feature_mempool_dakota.py', + 'feature_consortium.py', + 'interface_http.py', + 'interface_http_cors.py', + 'interface_rpc.py', + 'rpc_psbt.py', + 'rpc_users.py', + 'feature_proxy.py', + 'rpc_signrawtransaction.py', + 'wallet_groups.py', + 'p2p_disconnect_ban.py', + 'rpc_decodescript.py', + 'rpc_blockchain.py', + 'rpc_deprecated.py', + 'wallet_disable.py', + 'rpc_net.py', + 'wallet_keypool.py', + 'p2p_mempool.py', + 'rpc_setban.py', + 'p2p_blocksonly.py', + 'mining_prioritisetransaction.py', + 'p2p_invalid_locator.py', + 'p2p_invalid_block.py', + 'p2p_invalid_messages.py', + 'p2p_invalid_tx.py', + 'feature_foundation_migration.py', + 'feature_assumevalid.py', + 'example_test.py', + 'feature_jellyfish_initial_funds.py', + 'wallet_txn_doublespend.py', + 'wallet_txn_clone.py --mineblock', + 'feature_notifications.py', + 'rpc_getblockfilter.py', + 'rpc_invalidateblock.py', + 'feature_rbf.py', + 'mempool_packages.py', + 'mempool_package_onemore.py', + 'rpc_createmultisig.py', + 'feature_versionbits_warning.py', + 'rpc_preciousblock.py', + 'wallet_importprunedfunds.py', + 'p2p_leak_tx.py', + 'rpc_signmessage.py', + 'wallet_balance.py', + 'feature_nulldummy.py', + 'wallet_import_rescan.py', # nodes = 6 + 'wallet_import_with_label.py', + 'rpc_bind.py --ipv4', + 'rpc_bind.py --ipv6', + 'rpc_bind.py --nonloopback', + 'mining_basic.py', + 'wallet_bumpfee.py', + 'wallet_bumpfee_totalfee_deprecation.py', + 'rpc_named_arguments.py', + 'wallet_listsinceblock.py', + 'p2p_leak.py', + 'feature_higher_collateral_factor.py', + 'feature_skip_collateral_factor_check.py', + 'wallet_encryption.py', + 'feature_dersig.py', + 'feature_cltv.py', + 'rpc_updatemasternode.py', + 'rpc_uptime.py', + 'feature_longterm_lockin.py', + 'wallet_resendwallettransactions.py', + 'feature_custom_poolreward.py', + 'wallet_fallbackfee.py', + 'feature_token_lock.py', + 'feature_minchainwork.py', + 'rpc_getblockstats.py', + 'feature_median_time.py', + 'wallet_create_tx.py', + 'p2p_fingerprint.py', + 'feature_uacomment.py', + 'wallet_coinbase_category.py', + 'feature_filelock.py', + 'p2p_unrequested_blocks.py', + 'rpc_listaccounthistory.py', + 'feature_listaccounthistory_multiaccountquery.py', + 'rpc_getaccounthistory.py', + 'feature_includeconf.py', + 'rpc_deriveaddresses.py', + 'rpc_deriveaddresses.py --usecli', + 'rpc_scantxoutset.py', + 'rpc_getcustomtx.py', + 'rpc_listvaulthistory.py', + 'feature_logging.py', + 'feature_loan_scheme.py', + # 'feature_forced_reward_address.py', + 'feature_loan_vault.py', + 'feature_loan_deposittovault.py', + 'feature_loan_interest.py', + 'feature_loan_estimateloan.py', + 'feature_loan_priceupdate.py', + 'feature_loan_vaultstate.py', + 'feature_loan.py', + 'feature_evm_contracts.py', + 'feature_evm_fee.py', + 'feature_evm_genesis.py', + 'feature_evm_rollback.py', + 'feature_evm_rpc_transaction.py', + 'feature_evm_rpc.py', + 'feature_evm_vmmap_rpc.py', + 'feature_evm_smart_contract.py', + 'feature_evm_transferdomain.py', 'feature_evm.py', - # 'feature_loan_low_interest.py', - # 'feature_loan_estimatecollateral.py', - # 'feature_vault_pct_check_factor.py', - # 'p2p_node_network_limited.py', - # 'p2p_permissions.py', - # 'feature_blocksdir.py', - # 'feature_config_args.py', - # 'feature_account_mining.py', - # 'feature_accounts_validation.py', - # 'feature_listaccounts_pagination.py', - # 'feature_on_chain_government.py', - # 'feature_on_chain_government_voting_period_alignment.py', - # 'feature_on_chain_government_fee_distribution.py', - # 'feature_on_chain_government_voting_scenarios.py', - # 'rpc_listgovproposals.py', - # 'rpc_help.py', - # 'feature_help.py', - # 'feature_shutdown.py', - # 'feature_oracles.py', - # 'feature_checkpoint.py', - # 'rpc_getmininginfo.py', - # 'feature_burn_address.py', - # 'feature_eunos_balances.py', - # 'feature_sendutxosfrom.py', - # 'feature_testpoolswap.py', - # 'feature_update_mn.py', - # 'feature_block_reward.py', - # 'feature_negative_interest.py', - # 'rpc_getstoredinterest.py', - # 'feature_dusd_loans.py', + 'feature_loan_low_interest.py', + 'feature_loan_estimatecollateral.py', + 'feature_vault_pct_check_factor.py', + 'p2p_node_network_limited.py', + 'p2p_permissions.py', + 'feature_blocksdir.py', + 'feature_config_args.py', + 'feature_account_mining.py', + 'feature_accounts_validation.py', + 'feature_listaccounts_pagination.py', + 'feature_on_chain_government.py', + 'feature_on_chain_government_voting_period_alignment.py', + 'feature_on_chain_government_fee_distribution.py', + 'feature_on_chain_government_voting_scenarios.py', + 'rpc_listgovproposals.py', + 'rpc_help.py', + 'feature_help.py', + 'feature_shutdown.py', + 'feature_oracles.py', + 'feature_checkpoint.py', + 'rpc_getmininginfo.py', + 'feature_burn_address.py', + 'feature_eunos_balances.py', + 'feature_sendutxosfrom.py', + 'feature_testpoolswap.py', + 'feature_update_mn.py', + 'feature_block_reward.py', + 'feature_negative_interest.py', + 'rpc_getstoredinterest.py', + 'feature_dusd_loans.py', # Don't append tests at the end to avoid merge conflicts # Put them in a random line within the section that fits their approximate run-time ] From 773f172f2e4fc7fb2993331964a4c1f27855f08b Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 25 Jul 2023 19:18:37 +0800 Subject: [PATCH 06/15] Fixes to total fees and gas used --- lib/ain-evm/src/txqueue.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index 1512dc121c..f4d61b64b4 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -272,21 +272,29 @@ impl TransactionQueue { } pub fn remove_txs_by_sender(&self, sender: H160) { - self.transactions.lock().unwrap().retain(|item| { - let tx_sender = match &item.queue_tx { + let mut tx_items = self.transactions.lock().unwrap(); + for queue_item in &*tx_items { + let tx_sender = match &queue_item.queue_tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; if tx_sender == sender { let mut total_fees = self.total_fees.lock().unwrap(); - *total_fees -= item.tx_fee; + *total_fees -= queue_item.tx_fee; let mut total_gas_used = self.total_gas_used.lock().unwrap(); - *total_gas_used -= item.gas_used; - return false; + *total_gas_used -= queue_item.gas_used; } - true + } + + tx_items.retain(|item| { + let tx_sender = match &item.queue_tx { + QueueTx::SignedTx(tx) => tx.sender, + QueueTx::BridgeTx(tx) => tx.sender(), + }; + tx_sender != sender }); + self.account_nonces.lock().unwrap().remove(&sender); } From 58486bfc1039a052cc30de8e9b3a6c69784d8c9d Mon Sep 17 00:00:00 2001 From: Bushstar Date: Tue, 25 Jul 2023 12:33:18 +0100 Subject: [PATCH 07/15] Remove logging --- src/miner.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index e4cf42a0c0..100a5bb10f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -287,7 +287,6 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc std::copy(nodePtr->ownerAuthAddress.begin(), nodePtr->ownerAuthAddress.end(), beneficiary.begin()); CrossBoundaryResult result; auto blockResult = evm_try_finalize(result, evmContext, false, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), beneficiary, blockTime); - LogPrintf("XXX result %d reason %s\n", result.ok, result.reason); evm_discard_context(evmContext); const auto blockHash = std::vector(blockResult.block_hash.begin(), blockResult.block_hash.end()); From 88bd803f1d1677d2ac6f294368f20c3f2668d6cf Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 26 Jul 2023 13:42:16 +0800 Subject: [PATCH 08/15] Fix merge errors --- lib/ain-evm/src/txqueue.rs | 24 +++++++++++------------- src/miner.cpp | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index 414bbc254c..b758aa2596 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -100,7 +100,7 @@ impl TransactionQueueMap { /// `drain_all` returns all transactions from the `TransactionQueue` associated with the /// provided queue ID, removing them from the queue. Transactions are returned in the /// order they were added. - pub fn drain_all(&self, context_id: u64) -> Vec { + pub fn drain_all(&self, queue_id: u64) -> Vec { self.queues .read() .unwrap() @@ -108,7 +108,7 @@ impl TransactionQueueMap { .map_or(Vec::new(), TransactionQueue::drain_all) } - pub fn get_cloned_vec(&self, context_id: u64) -> Vec { + pub fn get_cloned_vec(&self, queue_id: u64) -> Vec { self.queues .read() .unwrap() @@ -222,7 +222,7 @@ impl TransactionQueue { data.transactions.clear(); } - pub fn drain_all(&self) -> Vec { + pub fn drain_all(&self) -> Vec { let mut data = self.data.lock().unwrap(); data.total_fees = 0u64; data.total_gas_used = 0u64; @@ -233,7 +233,7 @@ impl TransactionQueue { } pub fn get_cloned_vec(&self) -> Vec { - self.transactions.lock().unwrap().clone() + self.data.lock().unwrap().transactions.clone() } pub fn queue_tx( @@ -245,7 +245,7 @@ impl TransactionQueue { ) -> Result<(), QueueError> { let mut gas_fee: u64 = 0; let mut data = self.data.lock().unwrap(); - if let QueueTx::SignedTx(signed_tx) = &tx.0 { + if let QueueTx::SignedTx(signed_tx) = &tx { if let Some(nonce) = data.account_nonces.get(&signed_tx.sender) { if signed_tx.nonce() != nonce + 1 { return Err(QueueError::InvalidNonce((signed_tx.clone(), *nonce))); @@ -277,21 +277,19 @@ impl TransactionQueue { pub fn remove_txs_by_sender(&self, sender: H160) { let mut data = self.data.lock().unwrap(); - for queue_item in data.transactions { + let queued_txs = &self.data.lock().unwrap().transactions; + for queue_item in queued_txs { let tx_sender = match &queue_item.queue_tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; if tx_sender == sender { - let mut total_fees = self.total_fees.lock().unwrap(); - *total_fees -= queue_item.tx_fee; - - let mut total_gas_used = self.total_gas_used.lock().unwrap(); - *total_gas_used -= queue_item.gas_used; + data.total_fees -= queue_item.tx_fee; + data.total_gas_used -= queue_item.gas_used; } } - data.transactions.retain(|(tx, _)| { - let tx_sender = match tx { + data.transactions.retain(|item| { + let tx_sender = match &item.queue_tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; diff --git a/src/miner.cpp b/src/miner.cpp index 19171c0db8..10da41c421 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -902,7 +902,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda ++count; } evmTXs.erase(txResult.sender); - evm_remove_txs_by_sender(evmContext, txResult.sender); + evm_remove_txs_by_sender(evmQueueId, txResult.sender); customTxPassed = false; break; } From e3ecee58a4584465420476b77b1e82dba9a5da09 Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 26 Jul 2023 14:37:41 +0800 Subject: [PATCH 09/15] Fixes to match rust build triplet and target triplet --- configure.ac | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 83be49fd29..75a71ff88d 100644 --- a/configure.ac +++ b/configure.ac @@ -1375,19 +1375,21 @@ AC_SUBST(PROTOC) AC_SUBST(PROTOC_INCLUDE_DIR) dnl If the host and build triplets are the same, we keep this empty -if test x$host = x$build; then +RUST_HOST=`$ac_abs_confdir/make.sh get_rust_triplet "$build"` +if test $? != 0; then +AC_MSG_ERROR("unsupported build system") +fi + +RUST_TARGET=`$ac_abs_confdir/make.sh get_rust_triplet "$host"` +if test $? != 0; then +AC_MSG_ERROR("unsupported host target") +fi + +if test x$RUST_HOST = x$RUST_TARGET; then RUST_TARGET= RUST_HOST= -else - RUST_HOST=`$ac_abs_confdir/make.sh get_rust_triplet "$build"` - if test $? != 0; then - AC_MSG_ERROR("unsupported build system") - fi - RUST_TARGET=`$ac_abs_confdir/make.sh get_rust_triplet "$host"` - if test $? != 0; then - AC_MSG_ERROR("unsupported host target") - fi fi + AC_SUBST(RUST_TARGET) AC_SUBST(RUST_HOST) AM_CONDITIONAL([HAVE_RUST_TARGET], [test x$RUST_TARGET != x]) From 60487e3568dc1112fdb0bf3ac8e1a44331cf3148 Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 26 Jul 2023 14:49:53 +0800 Subject: [PATCH 10/15] Fix lint --- lib/ain-evm/src/txqueue.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index b758aa2596..faf0ce0bc3 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -226,10 +226,7 @@ impl TransactionQueue { let mut data = self.data.lock().unwrap(); data.total_fees = 0u64; data.total_gas_used = 0u64; - - data.transactions - .drain(..) - .collect::>() + data.transactions.drain(..).collect::>() } pub fn get_cloned_vec(&self) -> Vec { From 858c31a6a5cb60ee3789b7efb5691e4531970df2 Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 26 Jul 2023 14:56:08 +0800 Subject: [PATCH 11/15] Fix comments --- lib/ain-evm/src/txqueue.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index faf0ce0bc3..0b0f0cd47f 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -181,7 +181,8 @@ pub struct QueueTxItem { pub gas_used: u64, } -/// The `TransactionQueue` holds a queue of transactions and a map of account nonces. +/// The `TransactionQueueData` holds a queue of transactions with a map of the account nonces, +/// the total gas fees and the total gas used by the transactions. /// It's used to manage and process transactions for different accounts. /// #[derive(Debug, Default)] From f6c3e5165ae68b7d8da5538fedae22872f271d0e Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 26 Jul 2023 16:15:26 +0800 Subject: [PATCH 12/15] Fix merge bug --- lib/ain-evm/src/txqueue.rs | 10 +++++----- test/functional/feature_evm.py | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index 0b0f0cd47f..e795806010 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -274,16 +274,16 @@ impl TransactionQueue { } pub fn remove_txs_by_sender(&self, sender: H160) { + let tx_queue = self.get_cloned_vec(); let mut data = self.data.lock().unwrap(); - let queued_txs = &self.data.lock().unwrap().transactions; - for queue_item in queued_txs { - let tx_sender = match &queue_item.queue_tx { + for item in tx_queue { + let tx_sender = match &item.queue_tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; if tx_sender == sender { - data.total_fees -= queue_item.tx_fee; - data.total_gas_used -= queue_item.gas_used; + data.total_fees -= item.tx_fee; + data.total_gas_used -= item.gas_used; } } data.transactions.retain(|item| { diff --git a/test/functional/feature_evm.py b/test/functional/feature_evm.py index 3e4612b96e..8aa15ec591 100755 --- a/test/functional/feature_evm.py +++ b/test/functional/feature_evm.py @@ -245,7 +245,8 @@ def run_test(self): 'r': '0x3a0587be1a14bd5e68bc883e627f3c0999cff9458e30ea8049f17bd7369d7d9c', 's': '0x1876f296657bc56499cc6398617f97b2327fa87189c0a49fb671b4361876142a', 'type': '0x0', - 'maxFeePerGas': '0x4e3b29200'} + 'maxFeePerGas': '0x4e3b29200', + 'chainId': '0x1'} ]) # Try and send EVM TX a second time From 0d3f429343b3ae1bea70dcf9ee5eac950219f386 Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 26 Jul 2023 21:18:04 +0800 Subject: [PATCH 13/15] Refactor remove txs from sender --- lib/ain-evm/src/txqueue.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index e795806010..805731d1da 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -274,25 +274,23 @@ impl TransactionQueue { } pub fn remove_txs_by_sender(&self, sender: H160) { - let tx_queue = self.get_cloned_vec(); let mut data = self.data.lock().unwrap(); - for item in tx_queue { + let mut fees_to_remove = 0; + let mut gas_used_to_remove = 0; + data.transactions.retain(|item| { let tx_sender = match &item.queue_tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; if tx_sender == sender { - data.total_fees -= item.tx_fee; - data.total_gas_used -= item.gas_used; + fees_to_remove += item.tx_fee; + gas_used_to_remove += item.gas_used; + return false; } - } - data.transactions.retain(|item| { - let tx_sender = match &item.queue_tx { - QueueTx::SignedTx(tx) => tx.sender, - QueueTx::BridgeTx(tx) => tx.sender(), - }; - tx_sender != sender + true }); + data.total_fees -= fees_to_remove; + data.total_gas_used -= gas_used_to_remove; data.account_nonces.remove(&sender); } From bb7393cac9b8b83d964585432c66f7232568e452 Mon Sep 17 00:00:00 2001 From: Prasanna Loganathar Date: Wed, 26 Jul 2023 22:07:35 +0800 Subject: [PATCH 14/15] Use multimap for replace by fee --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 10da41c421..efccb12cdb 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -690,7 +690,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // Keep track of EVM entries that failed nonce check std::multimap failedNonces; // Used for replacement Eth TXs when a TX in chain pays a higher fee - std::map replaceByFee; + std::multimap replaceByFee; // Start by adding all descendants of previously added txs to mapModifiedTx // and modifying them for their already included ancestors From 25ca6b0118559e82d3ee1ae8442e9f646915b7ca Mon Sep 17 00:00:00 2001 From: Prasanna Loganathar Date: Wed, 26 Jul 2023 22:17:37 +0800 Subject: [PATCH 15/15] Fix flaky test --- test/functional/rpc_updatemasternode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/rpc_updatemasternode.py b/test/functional/rpc_updatemasternode.py index e17d5d7c21..f9bb1afe2c 100755 --- a/test/functional/rpc_updatemasternode.py +++ b/test/functional/rpc_updatemasternode.py @@ -466,7 +466,7 @@ def run_test(self): self.nodes[0].updatemasternode, mn2, {'rewardAddress': script_address}) # Move to fork height - self.nodes[0].generate(510 - self.nodes[0].getblockcount()) + self.nodes[0].generate(510) # Change reward address to script hash post-fork self.nodes[0].updatemasternode(mn2, {'rewardAddress': script_address})