From 391945863ad7f1f9f397f2fc34c6578be3d4ce47 Mon Sep 17 00:00:00 2001 From: Jouzo <15011228+Jouzo@users.noreply.github.com> Date: Wed, 26 Jul 2023 03:52:49 +0200 Subject: [PATCH] Guard TransactionQueue data with single mutex (#2225) * Guard transaction queue data in with single mutex * Rename context to queue_id * Rename context * Trigger actions --- lib/ain-evm/src/core.rs | 42 ++++----- lib/ain-evm/src/evm.rs | 28 +++--- lib/ain-evm/src/txqueue.rs | 160 +++++++++++++++++---------------- lib/ain-evm/tests/block.rs | 44 ++++----- lib/ain-grpc/src/tests.rs | 2 +- lib/ain-rs-exports/src/evm.rs | 70 +++++++-------- lib/ain-rs-exports/src/lib.rs | 23 +++-- src/masternodes/mn_checks.cpp | 26 +++--- src/masternodes/mn_checks.h | 4 +- src/masternodes/validation.cpp | 10 +-- src/masternodes/validation.h | 2 +- src/miner.cpp | 26 +++--- src/miner.h | 2 +- src/validation.cpp | 14 +-- src/validation.h | 2 +- 15 files changed, 233 insertions(+), 222 deletions(-) diff --git a/lib/ain-evm/src/core.rs b/lib/ain-evm/src/core.rs index 906a3d6abb..4a4c841b3a 100644 --- a/lib/ain-evm/src/core.rs +++ b/lib/ain-evm/src/core.rs @@ -167,7 +167,7 @@ impl EVMCoreService { pub fn validate_raw_tx( &self, tx: &str, - context: u64, + queue_id: u64, use_context: bool, ) -> Result> { debug!("[validate_raw_tx] raw transaction : {:#?}", tx); @@ -258,7 +258,7 @@ impl EVMCoreService { debug!("[validate_raw_tx] used_gas: {:#?}", used_gas); let total_current_gas_used = self .tx_queues - .get_total_gas_used(context) + .get_total_gas_used(queue_id) .unwrap_or_default(); if U256::from(total_current_gas_used + used_gas) > MAX_GAS_PER_BLOCK { @@ -287,20 +287,20 @@ impl EVMCoreService { impl EVMCoreService { pub fn add_balance( &self, - context: u64, + queue_id: u64, address: H160, amount: U256, hash: NativeTxHash, ) -> Result<(), EVMError> { let queue_tx = QueueTx::BridgeTx(BridgeTx::EvmIn(BalanceUpdate { address, amount })); self.tx_queues - .queue_tx(context, queue_tx, hash, 0u64, U256::zero())?; + .queue_tx(queue_id, queue_tx, hash, 0u64, U256::zero())?; Ok(()) } pub fn sub_balance( &self, - context: u64, + queue_id: u64, address: H160, amount: U256, hash: NativeTxHash, @@ -320,34 +320,34 @@ impl EVMCoreService { } else { let queue_tx = QueueTx::BridgeTx(BridgeTx::EvmOut(BalanceUpdate { address, amount })); self.tx_queues - .queue_tx(context, queue_tx, hash, 0u64, U256::zero())?; + .queue_tx(queue_id, queue_tx, hash, 0u64, U256::zero())?; Ok(()) } } - pub fn get_context(&self) -> u64 { - self.tx_queues.get_context() + pub fn get_queue_id(&self) -> u64 { + self.tx_queues.get_queue_id() } - pub fn clear(&self, context: u64) -> Result<(), EVMError> { - self.tx_queues.clear(context)?; + pub fn clear(&self, queue_id: u64) -> Result<(), EVMError> { + self.tx_queues.clear(queue_id)?; Ok(()) } - pub fn remove(&self, context: u64) { - self.tx_queues.remove(context); + pub fn remove(&self, queue_id: u64) { + self.tx_queues.remove(queue_id); } - pub fn remove_txs_by_sender(&self, context: u64, address: H160) -> Result<(), EVMError> { - self.tx_queues.remove_txs_by_sender(context, address)?; + pub fn remove_txs_by_sender(&self, queue_id: u64, address: H160) -> Result<(), EVMError> { + self.tx_queues.remove_txs_by_sender(queue_id, address)?; Ok(()) } - /// Retrieves the next valid nonce for the specified account within a particular context. + /// Retrieves the next valid nonce for the specified account within a particular queue. /// /// The method first attempts to retrieve the next valid nonce from the transaction queue associated with the - /// provided context. If no nonce is found in the transaction queue, that means that no transactions have been - /// queued for this account in this context. It falls back to retrieving the nonce from the storage at the latest + /// provided queue_id. If no nonce is found in the transaction queue, that means that no transactions have been + /// queued for this account in this queue_id. It falls back to retrieving the nonce from the storage at the latest /// block. If no nonce is found in the storage (i.e., no transactions for this account have been committed yet), /// the nonce is defaulted to zero. /// @@ -356,16 +356,16 @@ impl EVMCoreService { /// /// # Arguments /// - /// * `context` - The context queue number. + /// * `queue_id` - The queue_id queue number. /// * `address` - The EVM address of the account whose nonce we want to retrieve. /// /// # Returns /// /// Returns the next valid nonce as a `U256`. Defaults to U256::zero() - pub fn get_next_valid_nonce_in_context(&self, context: u64, address: H160) -> U256 { + pub fn get_next_valid_nonce_in_queue(&self, queue_id: u64, address: H160) -> U256 { let nonce = self .tx_queues - .get_next_valid_nonce(context, address) + .get_next_valid_nonce(queue_id, address) .unwrap_or_else(|| { let latest_block = self .storage @@ -378,7 +378,7 @@ impl EVMCoreService { }); debug!( - "Account {:x?} nonce {:x?} in context {context}", + "Account {:x?} nonce {:x?} in queue_id {queue_id}", address, nonce ); nonce diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index e4612218ba..0935c99659 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -90,15 +90,15 @@ impl EVMServices { pub fn finalize_block( &self, - context: u64, + queue_id: u64, update_state: bool, difficulty: u32, beneficiary: H160, timestamp: u64, ) -> Result> { - let mut all_transactions = Vec::with_capacity(self.core.tx_queues.len(context)); - let mut failed_transactions = Vec::with_capacity(self.core.tx_queues.len(context)); - let mut receipts_v3: Vec = Vec::with_capacity(self.core.tx_queues.len(context)); + let mut all_transactions = Vec::with_capacity(self.core.tx_queues.len(queue_id)); + let mut failed_transactions = Vec::with_capacity(self.core.tx_queues.len(queue_id)); + let mut receipts_v3: Vec = Vec::with_capacity(self.core.tx_queues.len(queue_id)); let mut total_gas_used = 0u64; let mut total_gas_fees = U256::zero(); let mut logs_bloom: Bloom = Bloom::default(); @@ -145,7 +145,7 @@ impl EVMServices { let mut executor = AinExecutor::new(&mut backend); - for (queue_tx, hash) in self.core.tx_queues.get_cloned_vec(context) { + for (queue_tx, hash) in self.core.tx_queues.get_cloned_vec(queue_id) { match queue_tx { QueueTx::SignedTx(signed_tx) => { if ain_cpp_imports::past_changi_intermediate_height_4_height() { @@ -185,8 +185,8 @@ impl EVMServices { } QueueTx::BridgeTx(BridgeTx::EvmIn(BalanceUpdate { address, amount })) => { debug!( - "[finalize_block] EvmIn for address {:x?}, amount: {}, context {}", - address, amount, context + "[finalize_block] EvmIn for address {:x?}, amount: {}, queue_id {}", + address, amount, queue_id ); if let Err(e) = executor.add_balance(address, amount) { debug!("[finalize_block] EvmIn failed with {e}"); @@ -268,7 +268,7 @@ impl EVMServices { total_priority_fees ); - match self.core.tx_queues.get_total_fees(context) { + match self.core.tx_queues.get_total_fees(queue_id) { 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()); @@ -276,15 +276,15 @@ impl EVMServices { } None => { return Err(anyhow!( - "EVM block rejected because failed to get total fees from context: {}", - context + "EVM block rejected because failed to get total fees from queue_id: {}", + queue_id ) .into()) } } if update_state { - self.core.tx_queues.remove(context); + self.core.tx_queues.remove(queue_id); } Ok(FinalizedBlockInfo { @@ -295,7 +295,7 @@ impl EVMServices { }) } else { if update_state { - self.core.tx_queues.remove(context); + self.core.tx_queues.remove(queue_id); } Ok(FinalizedBlockInfo { @@ -333,7 +333,7 @@ impl EVMServices { pub fn queue_tx( &self, - context: u64, + queue_id: u64, tx: QueueTx, hash: NativeTxHash, gas_used: u64, @@ -347,7 +347,7 @@ impl EVMServices { self.core .tx_queues - .queue_tx(context, tx.clone(), hash, gas_used, base_fee)?; + .queue_tx(queue_id, tx.clone(), hash, gas_used, base_fee)?; if let QueueTx::SignedTx(signed_tx) = tx { self.filters.add_tx_to_filters(signed_tx.transaction.hash()) diff --git a/lib/ain-evm/src/txqueue.rs b/lib/ain-evm/src/txqueue.rs index 34b9e6c475..132538e054 100644 --- a/lib/ain-evm/src/txqueue.rs +++ b/lib/ain-evm/src/txqueue.rs @@ -22,9 +22,9 @@ impl Default for TransactionQueueMap { } } -/// Holds multiple `TransactionQueue`s, each associated with a unique context ID. +/// Holds multiple `TransactionQueue`s, each associated with a unique queue ID. /// -/// Context IDs are randomly generated and used to access distinct transaction queues. +/// Queue IDs are randomly generated and used to access distinct transaction queues. impl TransactionQueueMap { pub fn new() -> Self { TransactionQueueMap { @@ -32,43 +32,43 @@ impl TransactionQueueMap { } } - /// `get_context` generates a unique random ID, creates a new `TransactionQueue` for that ID, + /// `get_queue_id` generates a unique random ID, creates a new `TransactionQueue` for that ID, /// and then returns the ID. - pub fn get_context(&self) -> u64 { + pub fn get_queue_id(&self) -> u64 { let mut rng = rand::thread_rng(); loop { - let context = rng.gen(); - // Safety check to disallow 0 as it's equivalent to no context - if context == 0 { + let queue_id = rng.gen(); + // Safety check to disallow 0 as it's equivalent to no queue_id + if queue_id == 0 { continue; }; let mut write_guard = self.queues.write().unwrap(); - if let std::collections::hash_map::Entry::Vacant(e) = write_guard.entry(context) { + if let std::collections::hash_map::Entry::Vacant(e) = write_guard.entry(queue_id) { e.insert(TransactionQueue::new()); - return context; + return queue_id; } } } /// Try to remove and return the `TransactionQueue` associated with the provided - /// context ID. - pub fn remove(&self, context_id: u64) -> Option { - self.queues.write().unwrap().remove(&context_id) + /// queue ID. + pub fn remove(&self, queue_id: u64) -> Option { + self.queues.write().unwrap().remove(&queue_id) } - /// Clears the `TransactionQueue` vector associated with the provided context ID. - pub fn clear(&self, context_id: u64) -> Result<(), QueueError> { + /// Clears the `TransactionQueue` vector associated with the provided queue ID. + pub fn clear(&self, queue_id: u64) -> Result<(), QueueError> { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .ok_or(QueueError::NoSuchContext) .map(TransactionQueue::clear) } /// Attempts to add a new transaction to the `TransactionQueue` associated with the - /// provided context ID. If the transaction is a `SignedTx`, it also updates the + /// provided queue ID. If the transaction is a `SignedTx`, it also updates the /// corresponding account's nonce. /// Nonces for each account's transactions must be in strictly increasing order. This means that if the last /// queued transaction for an account has nonce 3, the next one should have nonce 4. If a `SignedTx` with a nonce @@ -77,13 +77,13 @@ impl TransactionQueueMap { /// /// # Errors /// - /// Returns `QueueError::NoSuchContext` if no queue is associated with the given context ID. + /// Returns `QueueError::NoSuchContext` if no queue is associated with the given queue ID. /// Returns `QueueError::InvalidNonce` if a `SignedTx` is provided with a nonce that is not one more than the /// previous nonce of transactions from the same sender in the queue. /// pub fn queue_tx( &self, - context_id: u64, + queue_id: u64, tx: QueueTx, hash: NativeTxHash, gas_used: u64, @@ -92,77 +92,77 @@ impl TransactionQueueMap { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .ok_or(QueueError::NoSuchContext) .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 + /// 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() - .get(&context_id) + .get(&queue_id) .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() - .get(&context_id) + .get(&queue_id) .map_or(Vec::new(), TransactionQueue::get_cloned_vec) } - pub fn len(&self, context_id: u64) -> usize { + pub fn len(&self, queue_id: u64) -> usize { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .map_or(0, TransactionQueue::len) } /// Removes all transactions in the queue whose sender matches the provided sender address. /// # Errors /// - /// Returns `QueueError::NoSuchContext` if no queue is associated with the given context ID. + /// Returns `QueueError::NoSuchContext` if no queue is associated with the given queue ID. /// - pub fn remove_txs_by_sender(&self, context_id: u64, sender: H160) -> Result<(), QueueError> { + pub fn remove_txs_by_sender(&self, queue_id: u64, sender: H160) -> Result<(), QueueError> { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .ok_or(QueueError::NoSuchContext) .map(|queue| queue.remove_txs_by_sender(sender)) } /// `get_next_valid_nonce` returns the next valid nonce for the account with the provided address - /// in the `TransactionQueue` associated with the provided context ID. This method assumes that + /// in the `TransactionQueue` associated with the provided queue ID. This method assumes that /// only signed transactions (which include a nonce) are added to the queue using `queue_tx` /// and that their nonces are in increasing order. - pub fn get_next_valid_nonce(&self, context_id: u64, address: H160) -> Option { + pub fn get_next_valid_nonce(&self, queue_id: u64, address: H160) -> Option { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .and_then(|queue| queue.get_next_valid_nonce(address)) } - pub fn get_total_gas_used(&self, context_id: u64) -> Option { + pub fn get_total_gas_used(&self, queue_id: u64) -> Option { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .map(|queue| queue.get_total_gas_used()) } - pub fn get_total_fees(&self, context_id: u64) -> Option { + pub fn get_total_fees(&self, queue_id: u64) -> Option { self.queues .read() .unwrap() - .get(&context_id) + .get(&queue_id) .map(|queue| queue.get_total_fees()) } } @@ -179,49 +179,55 @@ type QueueTxWithNativeHash = (QueueTx, NativeTxHash); /// It's used to manage and process transactions for different accounts. /// #[derive(Debug, Default)] -pub struct TransactionQueue { - transactions: Mutex>, - account_nonces: Mutex>, - total_fees: Mutex, - total_gas_used: Mutex, +struct TransactionQueueData { + transactions: Vec, + account_nonces: HashMap, + total_fees: u64, + total_gas_used: u64, } -impl TransactionQueue { +impl TransactionQueueData { pub fn new() -> Self { Self { - transactions: Mutex::new(Vec::new()), - account_nonces: Mutex::new(HashMap::new()), - total_fees: Mutex::new(0u64), - total_gas_used: Mutex::new(0u64), + transactions: Vec::new(), + account_nonces: HashMap::new(), + total_fees: 0u64, + total_gas_used: 0u64, } } +} - pub fn clear(&self) { - let mut total_fees = self.total_fees.lock().unwrap(); - *total_fees = 0u64; +#[derive(Debug, Default)] +pub struct TransactionQueue { + data: Mutex, +} - let mut total_gas_used = self.total_gas_used.lock().unwrap(); - *total_gas_used = 0u64; +impl TransactionQueue { + fn new() -> Self { + Self { + data: Mutex::new(TransactionQueueData::new()), + } + } - self.transactions.lock().unwrap().clear(); + pub fn clear(&self) { + let mut data = self.data.lock().unwrap(); + data.total_fees = 0u64; + data.total_gas_used = 0u64; + data.transactions.clear(); } pub fn drain_all(&self) -> Vec { - let mut total_fees = self.total_fees.lock().unwrap(); - *total_fees = 0u64; + let mut data = self.data.lock().unwrap(); + data.total_fees = 0u64; + data.total_gas_used = 0u64; - let mut total_gas_used = self.total_gas_used.lock().unwrap(); - *total_gas_used = 0u64; - - self.transactions - .lock() - .unwrap() + data.transactions .drain(..) .collect::>() } pub fn get_cloned_vec(&self) -> Vec { - self.transactions.lock().unwrap().clone() + self.data.lock().unwrap().transactions.clone() } pub fn queue_tx( @@ -230,60 +236,60 @@ impl TransactionQueue { gas_used: u64, base_fee: U256, ) -> Result<(), QueueError> { + let mut data = self.data.lock().unwrap(); if let QueueTx::SignedTx(signed_tx) = &tx.0 { - let mut account_nonces = self.account_nonces.lock().unwrap(); - if let Some(nonce) = account_nonces.get(&signed_tx.sender) { + 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))); } } - account_nonces.insert(signed_tx.sender, signed_tx.nonce()); + data.account_nonces + .insert(signed_tx.sender, signed_tx.nonce()); let gas_fee = match calculate_gas_fee(signed_tx, gas_used.into(), base_fee) { Ok(fee) => fee.as_u64(), Err(_) => return Err(QueueError::InvalidFee), }; - let mut total_fees = self.total_fees.lock().unwrap(); - *total_fees += gas_fee; - - let mut total_gas_used = self.total_gas_used.lock().unwrap(); - *total_gas_used += gas_used; + data.total_fees += gas_fee; + data.total_gas_used += gas_used; } - self.transactions.lock().unwrap().push(tx); + data.transactions.push(tx); Ok(()) } pub fn len(&self) -> usize { - self.transactions.lock().unwrap().len() + self.data.lock().unwrap().transactions.len() } pub fn remove_txs_by_sender(&self, sender: H160) { - self.transactions.lock().unwrap().retain(|(tx, _)| { + let mut data = self.data.lock().unwrap(); + data.transactions.retain(|(tx, _)| { let tx_sender = match tx { QueueTx::SignedTx(tx) => tx.sender, QueueTx::BridgeTx(tx) => tx.sender(), }; tx_sender != sender }); - self.account_nonces.lock().unwrap().remove(&sender); + data.account_nonces.remove(&sender); } pub fn get_next_valid_nonce(&self, address: H160) -> Option { - self.account_nonces + self.data .lock() .unwrap() + .account_nonces .get(&address) .map(ToOwned::to_owned) .map(|nonce| nonce + 1) } pub fn get_total_fees(&self) -> u64 { - *self.total_fees.lock().unwrap() + self.data.lock().unwrap().total_fees } pub fn get_total_gas_used(&self) -> u64 { - *self.total_gas_used.lock().unwrap() + self.data.lock().unwrap().total_gas_used } } @@ -303,7 +309,7 @@ pub enum QueueError { impl std::fmt::Display for QueueError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - QueueError::NoSuchContext => write!(f, "No transaction queue for this context"), + QueueError::NoSuchContext => write!(f, "No transaction queue for this queue"), QueueError::InvalidNonce((tx, nonce)) => write!(f, "Invalid nonce {:x?} for tx {:x?}. Previous queued nonce is {}. TXs should be queued in increasing nonce order.", tx.nonce(), tx.transaction.hash(), nonce), QueueError::InvalidFee => write!(f, "Invalid transaction fee from value overflow"), } diff --git a/lib/ain-evm/tests/block.rs b/lib/ain-evm/tests/block.rs index 8de2ee606f..6a6c3397ea 100644 --- a/lib/ain-evm/tests/block.rs +++ b/lib/ain-evm/tests/block.rs @@ -10,9 +10,9 @@ use ain_evm::evm::EVMServices; #[test] fn test_finalize_block_and_do_not_update_state() { let handler = Handlers::new(); - let context = handler.evm.get_context(); + let queue_id = handler.evm.get_queue_id(); handler.evm.add_balance( - context, + queue_id, "0x4a1080c5533cb89edc4b65013f08f78868e382de" .parse() .unwrap(), @@ -20,10 +20,10 @@ fn test_finalize_block_and_do_not_update_state() { ); let tx1: SignedTx = "f86b02830186a0830186a094a8f7c4c78c36e54c3950ad58dad24ca5e0191b2989056bc75e2d631000008025a0b0842b0c78dd7fc33584ec9a81ab5104fe70169878de188ba6c11fe7605e298aa0735dc483f625f17d68d1e1fae779b7160612628e6dde9eecf087892fe60bba4e".try_into().unwrap(); - handler.evm.tx_queues.add_signed_tx(context, tx1); + handler.evm.tx_queues.add_signed_tx(queue_id, tx1); let old_state = handler.evm.state.read().unwrap(); - let _ = handler.finalize_block(context, false, 0, None).unwrap(); + let _ = handler.finalize_block(queue_id, false, 0, None).unwrap(); let new_state = handler.evm.state.read().unwrap(); assert_eq!(*new_state, *old_state); @@ -32,9 +32,9 @@ fn test_finalize_block_and_do_not_update_state() { #[test] fn test_finalize_block_and_update_state() { let handler = Handlers::new(); - let context = handler.evm.get_context(); + let queue_id = handler.evm.get_queue_id(); handler.evm.add_balance( - context, + queue_id, "0xebf9844ba89c4975bbe4e621dbaf085e6357df3f" .parse() .unwrap(), @@ -42,26 +42,26 @@ fn test_finalize_block_and_update_state() { ); let tx1: SignedTx = "f86b02830186a0830186a094a8f7c4c78c36e54c3950ad58dad24ca5e0191b2989056bc75e2d631000008025a0b0842b0c78dd7fc33584ec9a81ab5104fe70169878de188ba6c11fe7605e298aa0735dc483f625f17d68d1e1fae779b7160612628e6dde9eecf087892fe60bba4e".try_into().unwrap(); - handler.evm.tx_queues.add_signed_tx(context, tx1.clone()); + handler.evm.tx_queues.add_signed_tx(queue_id, tx1.clone()); handler.evm.add_balance( - context, + queue_id, "0x47b16da33f4e7e4a4ed9e52cc561b9ffcb3daf56" .parse() .unwrap(), U256::from_str_radix("100000000000000000000", 10).unwrap(), ); let tx2: SignedTx = "f86b02830186a0830186a094a8f7c4c78c36e54c3950ad58dad24ca5e0191b2989056bc75e2d631000008025a01465e2d999c34b22bf4b8b5c9439918e46341f4f0da1b00a6b0479c541161d4aa074abe79c51bf57086e1e84b57ee483cbb2ecf30e8222bc0472436fabfc57dda8".try_into().unwrap(); - handler.evm.tx_queues.add_signed_tx(context, tx2.clone()); + handler.evm.tx_queues.add_signed_tx(queue_id, tx2.clone()); let tx3: SignedTx = "f86b02830186a0830186a094a8f7c4c78c36e54c3950ad58dad24ca5e0191b2989056bc75e2d631000008025a070b21a24cec13c0569099ee2f8221268103fd609646b73f7c9e85efeb7af5c8ea03d5de75bc12ce28a80f7c0401df6021cc82a334cb1c802c8b9d46223c5c8eb40".try_into().unwrap(); - handler.evm.tx_queues.add_signed_tx(context, tx3.clone()); + handler.evm.tx_queues.add_signed_tx(queue_id, tx3.clone()); - assert_eq!(handler.evm.tx_queues.len(context), 3); - assert_eq!(handler.evm.tx_queues.len(handler.evm.get_context()), 0); + assert_eq!(handler.evm.tx_queues.len(queue_id), 3); + assert_eq!(handler.evm.tx_queues.len(handler.evm.get_queue_id()), 0); let FinalizedBlockInfo { block, failed_txs } = - handler.finalize_block(context, true, 0, None).unwrap(); + handler.finalize_block(queue_id, true, 0, None).unwrap(); assert_eq!( block.transactions, @@ -119,9 +119,9 @@ fn test_deploy_and_call_smart_contract() { let smart_contract_address: H160 = "69762793de93f55ab919c5efdaafb63d413dcbb5".parse().unwrap(); let handler = Handlers::new(); - let context = handler.evm.get_context(); + let queue_id = handler.evm.get_queue_id(); handler.evm.add_balance( - context, + queue_id, "0x4a1080c5533cb89edc4b65013f08f78868e382de" .parse() .unwrap(), @@ -133,13 +133,13 @@ fn test_deploy_and_call_smart_contract() { handler .evm .tx_queues - .add_signed_tx(context, create_smart_contract_tx); + .add_signed_tx(queue_id, create_smart_contract_tx); - handler.finalize_block(context, true, 0, None).unwrap(); + handler.finalize_block(queue_id, true, 0, None).unwrap(); // Fund caller address handler.evm.add_balance( - context, + queue_id, "0xb069baef499f992ff243300f78cf9ca1406a122e" .parse() .unwrap(), @@ -147,14 +147,14 @@ fn test_deploy_and_call_smart_contract() { ); let call_smart_contract_tx: SignedTx = "f8ca018504a817c8008302c1789469762793de93f55ab919c5efdaafb63d413dcbb580b864131a06800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20576f726c64210000000000000000000000000000000000000029a041fc9c0581885d77263dcba0603d8c6c164a9acfe803ad11188069eafa22169ca0018c1ba512639bd8ce32e76bcc2ea0759073a3f908014e47544d6c6674388b37".try_into().unwrap(); - // Each block requires a new context - let context = handler.evm.get_context(); + // Each block requires a new queue_id + let queue_id = handler.evm.get_queue_id(); handler .evm .tx_queues - .add_signed_tx(context, call_smart_contract_tx); + .add_signed_tx(queue_id, call_smart_contract_tx); - handler.finalize_block(context, true, 0, None).unwrap(); + handler.finalize_block(queue_id, true, 0, None).unwrap(); let smart_contract_storage = handler.evm.get_storage(smart_contract_address); assert_eq!( diff --git a/lib/ain-grpc/src/tests.rs b/lib/ain-grpc/src/tests.rs index afb2976d9a..57c7ed3c56 100644 --- a/lib/ain-grpc/src/tests.rs +++ b/lib/ain-grpc/src/tests.rs @@ -44,7 +44,7 @@ fn should_get_balance() { let res = EthService::Eth_GetBalance(handler.clone(), input.clone().into()); assert_eq!(res.unwrap().balance, "0"); - let ctx = handler.evm.get_context(); + let ctx = handler.evm.get_queue_id(); handler .evm diff --git a/lib/ain-rs-exports/src/evm.rs b/lib/ain-rs-exports/src/evm.rs index 67c5096f3c..756ea7b818 100644 --- a/lib/ain-rs-exports/src/evm.rs +++ b/lib/ain-rs-exports/src/evm.rs @@ -94,52 +94,52 @@ pub fn evm_get_balance(address: [u8; 20]) -> u64 { balance.to_satoshi().as_u64() } -/// Retrieves the next valid nonce of an EVM account in a specific context +/// Retrieves the next valid nonce of an EVM account in a specific queue_id /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// * `address` - The EVM address of the account. /// /// # Returns /// -/// Returns the next valid nonce of the account in a specific context as a `u64` -pub fn evm_get_next_valid_nonce_in_context(context: u64, address: [u8; 20]) -> u64 { +/// Returns the next valid nonce of the account in a specific queue_id as a `u64` +pub fn evm_get_next_valid_nonce_in_queue(queue_id: u64, address: [u8; 20]) -> u64 { let address = H160::from(address); let nonce = SERVICES .evm .core - .get_next_valid_nonce_in_context(context, address); + .get_next_valid_nonce_in_queue(queue_id, address); nonce.as_u64() } -/// Removes all transactions in the queue whose sender matches the provided sender address in a specific context +/// Removes all transactions in the queue whose sender matches the provided sender address in a specific queue_id /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// * `address` - The EVM address of the account. /// -pub fn evm_remove_txs_by_sender(context: u64, address: [u8; 20]) { +pub fn evm_remove_txs_by_sender(queue_id: u64, address: [u8; 20]) { let address = H160::from(address); - let _ = SERVICES.evm.core.remove_txs_by_sender(context, address); + let _ = SERVICES.evm.core.remove_txs_by_sender(queue_id, address); } /// EvmIn. Send DFI to an EVM account. /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// * `address` - The EVM address of the account. /// * `amount` - The amount to add as a byte array. /// * `hash` - The hash value as a byte array. /// -pub fn evm_add_balance(context: u64, address: &str, amount: [u8; 32], hash: [u8; 32]) { +pub fn evm_add_balance(queue_id: u64, address: &str, amount: [u8; 32], hash: [u8; 32]) { if let Ok(address) = address.parse() { let _ = SERVICES .evm .core - .add_balance(context, address, amount.into(), hash); + .add_balance(queue_id, address, amount.into(), hash); } } @@ -147,7 +147,7 @@ pub fn evm_add_balance(context: u64, address: &str, amount: [u8; 32], hash: [u8; /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// * `address` - The EVM address of the account. /// * `amount` - The amount to subtract as a byte array. /// * `hash` - The hash value as a byte array. @@ -155,19 +155,19 @@ pub fn evm_add_balance(context: u64, address: &str, amount: [u8; 32], hash: [u8; /// # Errors /// /// Returns an Error if: -/// - the context does not match any existing queue +/// - the queue_id does not match any existing queue /// - the address is not a valid EVM address /// - the account has insufficient balance. /// /// # Returns /// /// Returns `true` if the balance subtraction is successful, `false` otherwise. -pub fn evm_sub_balance(context: u64, address: &str, amount: [u8; 32], hash: [u8; 32]) -> bool { +pub fn evm_sub_balance(queue_id: u64, address: &str, amount: [u8; 32], hash: [u8; 32]) -> bool { if let Ok(address) = address.parse() { if let Ok(()) = SERVICES .evm .core - .sub_balance(context, address, amount.into(), hash) + .sub_balance(queue_id, address, amount.into(), hash) { return true; } @@ -209,8 +209,8 @@ pub fn evm_try_prevalidate_raw_tx( } } - let context = 0; - match SERVICES.evm.core.validate_raw_tx(tx, context, false) { + let queue_id = 0; + match SERVICES.evm.core.validate_raw_tx(tx, queue_id, false) { Ok(ValidateTxInfo { signed_tx, prepay_fee, @@ -236,7 +236,7 @@ pub fn evm_try_prevalidate_raw_tx( /// /// * `result` - Result object /// * `tx` - The raw transaction string. -/// * `context` - The EVM txqueue unique key +/// * `queue_id` - The EVM queue ID /// /// # Errors /// @@ -257,7 +257,7 @@ pub fn evm_try_prevalidate_raw_tx( pub fn evm_try_validate_raw_tx( result: &mut ffi::CrossBoundaryResult, tx: &str, - context: u64, + queue_id: u64, ) -> ffi::ValidateTxCompletion { match SERVICES.evm.verify_tx_fees(tx, true) { Ok(_) => (), @@ -267,7 +267,7 @@ pub fn evm_try_validate_raw_tx( } } - match SERVICES.evm.core.validate_raw_tx(tx, context, true) { + match SERVICES.evm.core.validate_raw_tx(tx, queue_id, true) { Ok(ValidateTxInfo { signed_tx, prepay_fee, @@ -288,30 +288,30 @@ pub fn evm_try_validate_raw_tx( } } -/// Retrieves the EVM context queue. +/// Retrieves the EVM queue ID. /// /// # Returns /// -/// Returns the EVM context queue number as a `u64`. -pub fn evm_get_context() -> u64 { - SERVICES.evm.core.get_context() +/// Returns the EVM queue ID as a `u64`. +pub fn evm_get_queue_id() -> u64 { + SERVICES.evm.core.get_queue_id() } -/// /// Discards an EVM context queue. +/// /// Discards an EVM queue. /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// -pub fn evm_discard_context(context: u64) { - SERVICES.evm.core.remove(context) +pub fn evm_discard_context(queue_id: u64) { + SERVICES.evm.core.remove(queue_id) } /// Add an EVM transaction to a specific queue. /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// * `raw_tx` - The raw transaction string. /// * `hash` - The native transaction hash. /// @@ -323,7 +323,7 @@ pub fn evm_discard_context(context: u64) { /// pub fn evm_try_queue_tx( result: &mut ffi::CrossBoundaryResult, - context: u64, + queue_id: u64, raw_tx: &str, hash: [u8; 32], gas_used: u64, @@ -333,7 +333,7 @@ pub fn evm_try_queue_tx( Ok(signed_tx) => { match SERVICES .evm - .queue_tx(context, signed_tx.into(), hash, gas_used) + .queue_tx(queue_id, signed_tx.into(), hash, gas_used) { Ok(_) => cross_boundary_success(result), Err(e) => cross_boundary_error_return(result, e.to_string()), @@ -347,7 +347,7 @@ pub fn evm_try_queue_tx( /// /// # Arguments /// -/// * `context` - The context queue number. +/// * `queue_id` - The queue ID. /// * `update_state` - A flag indicating whether to update the state. /// * `difficulty` - The block's difficulty. /// * `miner_address` - The miner's EVM address as a byte array. @@ -358,7 +358,7 @@ pub fn evm_try_queue_tx( /// Returns a `FinalizeBlockResult` containing the block hash, failed transactions, burnt fees and priority fees (in satoshis) on success. pub fn evm_try_finalize( result: &mut ffi::CrossBoundaryResult, - context: u64, + queue_id: u64, update_state: bool, difficulty: u32, miner_address: [u8; 20], @@ -367,7 +367,7 @@ pub fn evm_try_finalize( let eth_address = H160::from(miner_address); match SERVICES .evm - .finalize_block(context, update_state, difficulty, eth_address, timestamp) + .finalize_block(queue_id, update_state, difficulty, eth_address, timestamp) { Ok(FinalizedBlockInfo { block_hash, diff --git a/lib/ain-rs-exports/src/lib.rs b/lib/ain-rs-exports/src/lib.rs index e65ef56780..839fdc6791 100644 --- a/lib/ain-rs-exports/src/lib.rs +++ b/lib/ain-rs-exports/src/lib.rs @@ -68,17 +68,22 @@ pub mod ffi { // If they are fallible, it's a TODO to changed and move later // so errors are propogated up properly. fn evm_get_balance(address: [u8; 20]) -> u64; - fn evm_get_next_valid_nonce_in_context(context: u64, address: [u8; 20]) -> u64; - fn evm_remove_txs_by_sender(context: u64, address: [u8; 20]); - fn evm_add_balance(context: u64, address: &str, amount: [u8; 32], native_tx_hash: [u8; 32]); + fn evm_get_next_valid_nonce_in_queue(queue_id: u64, address: [u8; 20]) -> u64; + fn evm_remove_txs_by_sender(queue_id: u64, address: [u8; 20]); + fn evm_add_balance( + queue_id: u64, + address: &str, + amount: [u8; 32], + native_tx_hash: [u8; 32], + ); fn evm_sub_balance( - context: u64, + queue_id: u64, address: &str, amount: [u8; 32], native_tx_hash: [u8; 32], ) -> bool; - fn evm_get_context() -> u64; - fn evm_discard_context(context: u64); + fn evm_get_queue_id() -> u64; + fn evm_discard_context(queue_id: u64); fn evm_disconnect_latest_block(); // Failible functions @@ -92,18 +97,18 @@ pub mod ffi { fn evm_try_validate_raw_tx( result: &mut CrossBoundaryResult, tx: &str, - context: u64, + queue_id: u64, ) -> ValidateTxCompletion; fn evm_try_queue_tx( result: &mut CrossBoundaryResult, - context: u64, + queue_id: u64, raw_tx: &str, hash: [u8; 32], gas_used: u64, ); fn evm_try_finalize( result: &mut CrossBoundaryResult, - context: u64, + queue_id: u64, update_state: bool, difficulty: u32, miner_address: [u8; 20], diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index 418cc6936e..e48bcbc0fc 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -768,7 +768,7 @@ Res CCustomTxVisitor::IsOnChainGovernanceEnabled() const { class CCustomTxApplyVisitor : public CCustomTxVisitor { uint64_t time; uint32_t txn; - uint64_t evmContext; + uint64_t evmQueueId; bool prevalidateEvm; public: @@ -779,13 +779,13 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { const Consensus::Params &consensus, uint64_t time, uint32_t txn, - const uint64_t evmContext, + const uint64_t evmQueueId, const bool prevalidateEvm) : CCustomTxVisitor(tx, height, coins, mnview, consensus), time(time), txn(txn), - evmContext(evmContext), + evmQueueId(evmQueueId), prevalidateEvm(prevalidateEvm) {} Res operator()(const CCreateMasterNodeMessage &obj) const { @@ -3887,7 +3887,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { const auto fromAddress = std::get(dest); arith_uint256 balanceIn = src.amount.nValue; balanceIn *= CAMOUNT_TO_GWEI * WEI_IN_GWEI; - if (!evm_sub_balance(evmContext, HexStr(fromAddress.begin(), fromAddress.end()), ArithToUint256(balanceIn).GetByteArray(), tx.GetHash().GetByteArray())) { + if (!evm_sub_balance(evmQueueId, HexStr(fromAddress.begin(), fromAddress.end()), ArithToUint256(balanceIn).GetByteArray(), tx.GetHash().GetByteArray())) { return DeFiErrors::TransferDomainNotEnoughBalance(EncodeDestination(dest)); } } @@ -3905,7 +3905,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { const auto toAddress = std::get(dest); arith_uint256 balanceIn = dst.amount.nValue; balanceIn *= CAMOUNT_TO_GWEI * WEI_IN_GWEI; - evm_add_balance(evmContext, HexStr(toAddress.begin(), toAddress.end()), ArithToUint256(balanceIn).GetByteArray(), tx.GetHash().GetByteArray()); + evm_add_balance(evmQueueId, HexStr(toAddress.begin(), toAddress.end()), ArithToUint256(balanceIn).GetByteArray(), tx.GetHash().GetByteArray()); } // If you are here to change ChangiIntermediateHeight to NextNetworkUpgradeHeight @@ -3931,7 +3931,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { CrossBoundaryResult result; if (!prevalidateEvm) { - const auto validateResults = evm_try_validate_raw_tx(result, HexStr(obj.evmTx), evmContext); + const auto validateResults = evm_try_validate_raw_tx(result, HexStr(obj.evmTx), evmQueueId); // Completely remove this fork guard on mainnet upgrade to restore nonce check from EVM activation if (height >= static_cast(consensus.ChangiIntermediateHeight)) { if (!result.ok) { @@ -3940,7 +3940,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor { } } - evm_try_queue_tx(result, evmContext, HexStr(obj.evmTx), tx.GetHash().GetByteArray(), validateResults.gas_used); + evm_try_queue_tx(result, evmQueueId, HexStr(obj.evmTx), tx.GetHash().GetByteArray(), validateResults.gas_used); if (!result.ok) { LogPrintf("[evm_try_queue_tx] failed, reason : %s\n", result.reason); return Res::Err("evm tx failed to queue %s\n", result.reason); @@ -4103,7 +4103,7 @@ Res ValidateTransferDomain(const CTransaction &tx, if (!IsEVMEnabled(height, mnview, consensus)) { return DeFiErrors::TransferDomainEVMNotEnabled(); } - + if (height >= static_cast(consensus.ChangiIntermediateHeight4)) { if (!IsTransferDomainEnabled(height, mnview, consensus)) { return DeFiErrors::TransferDomainNotEnabled(); @@ -4184,16 +4184,16 @@ Res CustomTxVisit(CCustomCSView &mnview, const CCustomTxMessage &txMessage, uint64_t time, uint32_t txn, - const uint64_t evmContext) { + const uint64_t evmQueueId) { if (IsDisabledTx(height, tx, consensus)) { return Res::ErrCode(CustomTxErrCodes::Fatal, "Disabled custom transaction"); } - auto context = evmContext; + auto context = evmQueueId; bool prevalidateEvm = false; if (context == 0) { prevalidateEvm = true; - context = evm_get_context(); + context = evm_get_queue_id(); } try { @@ -4283,7 +4283,7 @@ Res ApplyCustomTx(CCustomCSView &mnview, uint64_t time, uint256 *canSpend, uint32_t txn, - const uint64_t evmContext) { + const uint64_t evmQueueId) { auto res = Res::Ok(); if (tx.IsCoinBase() && height > 0) { // genesis contains custom coinbase txs return res; @@ -4307,7 +4307,7 @@ Res ApplyCustomTx(CCustomCSView &mnview, PopulateVaultHistoryData(mnview.GetHistoryWriters(), view, txMessage, txType, height, txn, tx.GetHash()); } - res = CustomTxVisit(view, coins, tx, height, consensus, txMessage, time, txn, evmContext); + res = CustomTxVisit(view, coins, tx, height, consensus, txMessage, time, txn, evmQueueId); if (res) { if (canSpend && txType == CustomTxType::UpdateMasternode) { diff --git a/src/masternodes/mn_checks.h b/src/masternodes/mn_checks.h index 0290fed782..79c0a619ea 100644 --- a/src/masternodes/mn_checks.h +++ b/src/masternodes/mn_checks.h @@ -475,7 +475,7 @@ Res ApplyCustomTx(CCustomCSView &mnview, uint64_t time = 0, uint256 *canSpend = nullptr, uint32_t txn = 0, - const uint64_t evmContext = 0); + const uint64_t evmQueueId = 0); Res CustomTxVisit(CCustomCSView &mnview, const CCoinsViewCache &coins, const CTransaction &tx, @@ -484,7 +484,7 @@ Res CustomTxVisit(CCustomCSView &mnview, const CCustomTxMessage &txMessage, uint64_t time, uint32_t txn = 0, - const uint64_t evmContext = 0); + const uint64_t evmQueueId = 0); ResVal ApplyAnchorRewardTx(CCustomCSView &mnview, const CTransaction &tx, int height, diff --git a/src/masternodes/validation.cpp b/src/masternodes/validation.cpp index 7bf9f8fac2..8b859ce633 100644 --- a/src/masternodes/validation.cpp +++ b/src/masternodes/validation.cpp @@ -2378,7 +2378,7 @@ static void RevertFailedTransferDomainTxs(const std::vector &failed } } -static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &cache, const CChainParams& chainparams, const uint64_t evmContext, std::array& beneficiary) { +static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &cache, const CChainParams& chainparams, const uint64_t evmQueueId, std::array& beneficiary) { if (!IsEVMEnabled(pindex->nHeight, cache, chainparams.GetConsensus())) return; CKeyID minter; @@ -2422,13 +2422,13 @@ static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCus } CrossBoundaryResult result; - const auto blockResult = evm_try_finalize(result, evmContext, false, block.nBits, beneficiary, block.GetBlockTime()); + const auto blockResult = evm_try_finalize(result, evmQueueId, false, block.nBits, beneficiary, block.GetBlockTime()); if (!result.ok) { LogPrintf("ERROR: EVM try finalize failed: %s\n", result.reason.c_str()); } auto evmBlockHashData = std::vector(blockResult.block_hash.rbegin(), blockResult.block_hash.rend()); auto evmBlockHash = uint256(evmBlockHashData); - + cache.SetVMDomainBlockEdge(VMDomainEdge::DVMToEVM, block.GetHash(), evmBlockHash); cache.SetVMDomainBlockEdge(VMDomainEdge::EVMToDVM, evmBlockHash, block.GetHash()); @@ -2467,7 +2467,7 @@ static void ProcessChangiIntermediate4(const CBlockIndex* pindex, CCustomCSView& cache.SetVariable(*attributes); } -void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmContext, std::array& beneficiary) { +void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmQueueId, std::array& beneficiary) { CCustomCSView cache(mnview); // calculate rewards to current block @@ -2522,7 +2522,7 @@ void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSV ProcessGrandCentralEvents(pindex, cache, chainparams); // Execute EVM Queue - ProcessEVMQueue(block, pindex, cache, chainparams, evmContext, beneficiary); + ProcessEVMQueue(block, pindex, cache, chainparams, evmQueueId, beneficiary); // Execute ChangiIntermediate4 Events. Delete when removing Changi forks ProcessChangiIntermediate4(pindex, cache, chainparams); diff --git a/src/masternodes/validation.h b/src/masternodes/validation.h index 0e690cfda8..7fdd12ed9c 100644 --- a/src/masternodes/validation.h +++ b/src/masternodes/validation.h @@ -17,7 +17,7 @@ class CCustomCSView; using CreationTxs = std::map>>>; -void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmContext, std::array& beneficiary); +void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmQueueId, std::array& beneficiary); std::vector CollectAuctionBatches(const CVaultAssets& vaultAssets, const TAmounts& collBalances, const TAmounts& loanBalances); diff --git a/src/miner.cpp b/src/miner.cpp index 5c261113a0..928bf1a2cb 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -271,13 +271,13 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc timeOrdering = false; } - const auto evmContext = evm_get_context(); + const auto evmQueueId = evm_get_queue_id(); std::map txFees; if (timeOrdering) { - addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmContext, txFees); + addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmQueueId, txFees); } else { - addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmContext, txFees); + addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmQueueId, txFees); } XVM xvm{}; @@ -286,8 +286,8 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc std::array beneficiary{}; 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); - evm_discard_context(evmContext); + auto blockResult = evm_try_finalize(result, evmQueueId, false, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), beneficiary, blockTime); + evm_discard_context(evmQueueId); const auto blockHash = std::vector(blockResult.block_hash.begin(), blockResult.block_hash.end()); @@ -603,7 +603,7 @@ void BlockAssembler::RemoveTxs(const std::set &txHashSet, const std::ma }; pblock->vtx.erase( - std::remove_if(pblock->vtx.begin(), pblock->vtx.end(), removeItem), + std::remove_if(pblock->vtx.begin(), pblock->vtx.end(), removeItem), pblock->vtx.end()); // Add descendants @@ -660,7 +660,7 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, std::ve // mapModifiedTxs with the next transaction in the mempool to decide what // transaction package to work on next. template -void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, const uint64_t evmContext, std::map &txFees) +void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, const uint64_t evmQueueId, std::map &txFees) { // mapModifiedTx will store sorted packages after they are modified // because some of their txs are already in the block @@ -855,7 +855,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; @@ -865,7 +865,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_validate_raw_tx(result, HexStr(obj.evmTx), evmQueueId); if (!result.ok) { customTxPassed = false; break; @@ -874,7 +874,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda auto& evmFeeMap = evmPackageContext.feeMap; auto& evmAddressTxsMap = evmPackageContext.addressTxsMap; - const auto addrKey = EvmAddressWithNonce { txResult.sender, txResult.nonce }; + 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; @@ -902,13 +902,13 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda ++count; } evmAddressTxsMap.erase(addrKey.address); - evm_remove_txs_by_sender(evmContext, addrKey.address); + evm_remove_txs_by_sender(evmQueueId, addrKey.address); customTxPassed = false; break; } } - const auto nonce = evm_get_next_valid_nonce_in_context(evmContext, txResult.sender); + const auto nonce = evm_get_next_valid_nonce_in_queue(evmQueueId, txResult.sender); if (nonce != txResult.nonce) { // Only add if not already in failed TXs to prevent adding on second attempt. if (!failedTx.count(iter)) { @@ -923,7 +923,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda evmAddressTxsMap[txResult.sender].emplace(txResult.nonce, sortedEntries[i]); } - const auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmContext); + const auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmQueueId); // Not okay invalidate, undo and skip if (!res.ok) { customTxPassed = false; diff --git a/src/miner.h b/src/miner.h index 026bdc72f2..36cd147ac6 100644 --- a/src/miner.h +++ b/src/miner.h @@ -194,7 +194,7 @@ class BlockAssembler * Increments nPackagesSelected / nDescendantsUpdated with corresponding * statistics from the package selection (for logging statistics). */ template - void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, const uint64_t evmContext, std::map &txFees) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); + void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, const uint64_t evmQueueId, std::map &txFees) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); // helper functions for addPackageTxs() /** Remove confirmed (inBlock) entries from given set */ diff --git a/src/validation.cpp b/src/validation.cpp index 1ecc01ec53..f666d24d1c 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2325,7 +2325,7 @@ static void LogApplyCustomTx(const CTransaction &tx, const int64_t start) { * Validity checks that depend on the UTXO set are also done; ConnectBlock () * can fail if those validity checks fail (among other reasons). */ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, - CCoinsViewCache& view, CCustomCSView& mnview, const CChainParams& chainparams, bool & rewardedAnchors, std::array& beneficiary, bool fJustCheck, const int64_t evmContext) + CCoinsViewCache& view, CCustomCSView& mnview, const CChainParams& chainparams, bool & rewardedAnchors, std::array& beneficiary, bool fJustCheck, const int64_t evmQueueId) { AssertLockHeld(cs_main); assert(pindex); @@ -2669,7 +2669,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl } const auto applyCustomTxTime = GetTimeMicros(); - const auto res = ApplyCustomTx(accountsView, view, tx, chainparams.GetConsensus(), pindex->nHeight, pindex->GetBlockTime(), nullptr, i, evmContext); + const auto res = ApplyCustomTx(accountsView, view, tx, chainparams.GetConsensus(), pindex->nHeight, pindex->GetBlockTime(), nullptr, i, evmQueueId); LogApplyCustomTx(tx, applyCustomTxTime); if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) { @@ -2850,7 +2850,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); - ProcessDeFiEvent(block, pindex, mnview, view, chainparams, creationTxs, evmContext, beneficiary); + ProcessDeFiEvent(block, pindex, mnview, view, chainparams, creationTxs, evmQueueId, beneficiary); // Write any UTXO burns for (const auto& [key, value] : writeBurnEntries) @@ -3314,11 +3314,11 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp CCustomCSView mnview(*pcustomcsview, paccountHistoryDB.get(), pburnHistoryDB.get(), pvaultHistoryDB.get()); bool rewardedAnchors{}; std::array beneficiary{}; - const auto evmContext = evm_get_context(); - bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, mnview, chainparams, rewardedAnchors, beneficiary, false, evmContext); + const auto evmQueueId = evm_get_queue_id(); + bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, mnview, chainparams, rewardedAnchors, beneficiary, false, evmQueueId); GetMainSignals().BlockChecked(blockConnecting, state); if (!rv) { - evm_discard_context(evmContext); + evm_discard_context(evmQueueId); if (state.IsInvalid()) { InvalidBlockFound(pindexNew, state); } @@ -3329,7 +3329,7 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp LogPrint(BCLog::BENCH, " - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal); if (IsEVMEnabled(pindexNew->nHeight, mnview, chainparams.GetConsensus())) { CrossBoundaryResult result; - evm_try_finalize(result, evmContext, true, blockConnecting.nBits, beneficiary, blockConnecting.GetBlockTime()); + evm_try_finalize(result, evmQueueId, true, blockConnecting.nBits, beneficiary, blockConnecting.GetBlockTime()); if (!result.ok && pindexNew->nHeight >= Params().GetConsensus().ChangiIntermediateHeight4) { return error("%s: ConnectBlock %s failed, %s", __func__, pindexNew->GetBlockHash().ToString(), result.reason.c_str()); } diff --git a/src/validation.h b/src/validation.h index c3b79e1742..eda0798112 100644 --- a/src/validation.h +++ b/src/validation.h @@ -736,7 +736,7 @@ class CChainState { // Block (dis)connection on a given view: DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view, CCustomCSView& cache, std::vector & disconnectedAnchorConfirms); bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, - CCoinsViewCache& view, CCustomCSView& cache, const CChainParams& chainparams, bool & rewardedAnchors, std::array& beneficiary, bool fJustCheck = false, const int64_t evmContext = 0) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + CCoinsViewCache& view, CCustomCSView& cache, const CChainParams& chainparams, bool & rewardedAnchors, std::array& beneficiary, bool fJustCheck = false, const int64_t evmQueueId = 0) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Apply the effects of a block disconnection on the UTXO set. bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);