From 2cc5a7d3df20b2b27724e76bc0f0477beee7420e Mon Sep 17 00:00:00 2001 From: Jouzo <15011228+Jouzo@users.noreply.github.com> Date: Tue, 24 Oct 2023 03:24:27 +0100 Subject: [PATCH] Remove BlockTemplateMap (#2603) * Remove BlockTemplateMap * Correctly init CrossBoundaryResult on success * Use mut references instead of raw pointers * Switch C++ ScopedQueue to use safer ref instead of ptr * fmt * Resolve lints * Fix mem leak * Use static globals * fmt * Simplify static mut for err * Return directly the result of get_or_init for additional safety --------- Co-authored-by: Prasanna Loganathar --- lib/ain-evm/src/blocktemplate.rs | 253 ++++------------------------ lib/ain-evm/src/core.rs | 52 ++---- lib/ain-evm/src/evm.rs | 79 ++++----- lib/ain-evm/src/log.rs | 2 +- lib/ain-evm/src/receipt.rs | 2 +- lib/ain-evm/src/transaction/mod.rs | 6 +- lib/ain-grpc/src/rpc/debug.rs | 4 +- lib/ain-rs-exports/src/evm.rs | 178 ++++++++++--------- lib/ain-rs-exports/src/lib.rs | 71 ++++++-- src/consensus/tx_verify.cpp | 6 +- src/dfi/consensus/governance.cpp | 2 +- src/dfi/consensus/loans.cpp | 4 +- src/dfi/consensus/tokens.cpp | 2 +- src/dfi/consensus/txvisitor.cpp | 4 +- src/dfi/consensus/txvisitor.h | 6 +- src/dfi/consensus/xvm.cpp | 28 +-- src/dfi/evm.cpp | 30 ++-- src/dfi/evm.h | 19 ++- src/dfi/govvariables/attributes.cpp | 4 +- src/dfi/govvariables/attributes.h | 2 +- src/dfi/mn_checks.cpp | 22 +-- src/dfi/mn_checks.h | 4 +- src/dfi/mn_rpc.cpp | 4 +- src/dfi/rpc_tokens.cpp | 4 +- src/dfi/tokens.cpp | 14 +- src/dfi/tokens.h | 2 +- src/dfi/validation.cpp | 16 +- src/dfi/validation.h | 4 +- src/miner.cpp | 28 +-- src/miner.h | 4 +- src/test/applytx_tests.cpp | 10 +- src/txmempool.cpp | 4 +- src/validation.cpp | 24 +-- 33 files changed, 357 insertions(+), 537 deletions(-) diff --git a/lib/ain-evm/src/blocktemplate.rs b/lib/ain-evm/src/blocktemplate.rs index 3f1f819138..83074d4cc3 100644 --- a/lib/ain-evm/src/blocktemplate.rs +++ b/lib/ain-evm/src/blocktemplate.rs @@ -1,9 +1,5 @@ -use std::{collections::HashMap, sync::Arc}; - use ethereum::{Block, ReceiptV3, TransactionV2}; use ethereum_types::{Bloom, H160, H256, U256}; -use parking_lot::{Mutex, RwLock}; -use rand::Rng; use crate::{ backend::Vicinity, core::XHash, evm::ExecTxState, receipt::Receipt, transaction::SignedTx, @@ -13,184 +9,6 @@ type Result = std::result::Result; pub type ReceiptAndOptionalContractAddress = (ReceiptV3, Option); -#[derive(Debug)] -pub struct BlockTemplateMap { - templates: RwLock>>, -} - -impl Default for BlockTemplateMap { - fn default() -> Self { - Self::new() - } -} - -/// Holds multiple `BlockTemplate`s, each associated with a unique template ID. -/// -/// Template IDs are randomly generated and used to access distinct transaction templates. -impl BlockTemplateMap { - pub fn new() -> Self { - BlockTemplateMap { - templates: RwLock::new(HashMap::new()), - } - } - - /// `create` generates a unique random ID, creates a new `BlockTemplate` for that ID, - /// and then returns the ID. - /// - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn create(&self, block_data: BlockTemplateData) -> u64 { - let mut rng = rand::thread_rng(); - loop { - let template_id = rng.gen(); - // Safety check to disallow 0 as it's equivalent to no template_id - if template_id == 0 { - continue; - }; - let mut write_guard = self.templates.write(); - - if let std::collections::hash_map::Entry::Vacant(e) = write_guard.entry(template_id) { - e.insert(Arc::new(BlockTemplate::new(block_data))); - return template_id; - } - } - } - - /// Try to remove and return the `BlockTemplate` associated with the provided - /// template ID. - /// - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn remove(&self, template_id: u64) -> Option> { - self.templates.write().remove(&template_id) - } - - /// Returns an atomic reference counting pointer of the `BlockTemplate` associated with the provided template ID. - /// Note that the `BlockTemplate` instance contains the mutex of the `BlockTemplateData`, and this method - /// should be used if multiple read/write operations on the block template is required within the pipeline. This is - /// to ensure the atomicity and functionality of the client, and to maintain the integrity of the block template. - /// - /// # Errors - /// - /// Returns `BlockTemplateError::NoSuchTemplate` if no block template is associated with the given template ID. - /// - /// # Safety - /// - /// Result cannot be used safety unless cs_main lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn get(&self, template_id: u64) -> Result> { - Ok(Arc::clone( - self.templates - .read() - .get(&template_id) - .ok_or(BlockTemplateError::NoSuchTemplate)?, - )) - } - - /// Attempts to add a new transaction to the `BlockTemplate` associated with the provided template ID. - /// Nonces for each account must be in strictly increasing order. This means that if the last added transaction - /// for an account has nonce 3, the next one should have nonce 4. If a `SignedTx` with a nonce that is not one - /// more than the previous nonce is added, an error is returned. This helps to ensure the integrity of the block - /// template and enforce correct nonce usage. - /// - /// # Errors - /// - /// Returns `BlockTemplateError::NoSuchTemplate` if no block template is associated with the given template ID. - /// - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn push_in( - &self, - template_id: u64, - tx_update: ExecTxState, - hash: XHash, - ) -> Result<()> { - self.with_block_template(template_id, |template| template.add_tx(tx_update, hash)) - .and_then(|res| res) - } - - /// Removes all transactions in the block template whose sender matches the provided sender address. - /// # Errors - /// - /// Returns `BlockTemplateError::NoSuchTemplate` if no template is associated with the given template ID. - /// - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn remove_txs_above_hash_in( - &self, - template_id: u64, - target_hash: XHash, - ) -> Result> { - self.with_block_template(template_id, |template| { - template.remove_txs_above_hash(target_hash) - }) - .and_then(|res| res) - } - - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn get_total_gas_used_in(&self, template_id: u64) -> Result { - self.with_block_template(template_id, BlockTemplate::get_total_gas_used) - } - - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn get_target_block_in(&self, template_id: u64) -> Result { - self.with_block_template(template_id, BlockTemplate::get_target_block) - } - - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn get_timestamp_in(&self, template_id: u64) -> Result { - self.with_block_template(template_id, BlockTemplate::get_timestamp) - } - - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn get_latest_state_root_in(&self, template_id: u64) -> Result { - self.with_block_template(template_id, BlockTemplate::get_latest_state_root) - } - - /// Apply the closure to the template associated with the template ID. - /// # Errors - /// - /// Returns `BlockTemplateError::NoSuchTemplate` if no block template is associated with the given template ID. - unsafe fn with_block_template(&self, template_id: u64, f: F) -> Result - where - F: FnOnce(&BlockTemplate) -> T, - { - match self.templates.read().get(&template_id) { - Some(template) => Ok(f(template)), - None => Err(BlockTemplateError::NoSuchTemplate), - } - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct TemplateTxItem { pub tx: Box, @@ -239,7 +57,7 @@ pub struct BlockData { /// The template is used to construct a valid EVM block. /// #[derive(Clone, Debug, Default)] -pub struct BlockTemplateData { +pub struct BlockTemplate { pub transactions: Vec, pub block_data: Option, pub total_gas_used: U256, @@ -250,27 +68,33 @@ pub struct BlockTemplateData { pub initial_state_root: H256, } -#[derive(Debug, Default)] -pub struct BlockTemplate { - pub data: Mutex, -} - impl BlockTemplate { - fn new(block_data: BlockTemplateData) -> Self { + pub fn new( + vicinity: Vicinity, + parent_hash: H256, + dvm_block: u64, + timestamp: u64, + initial_state_root: H256, + ) -> Self { Self { - data: Mutex::new(block_data), + transactions: Vec::new(), + block_data: None, + total_gas_used: U256::zero(), + vicinity, + parent_hash, + dvm_block, + timestamp, + initial_state_root, } } - pub fn add_tx(&self, tx_update: ExecTxState, tx_hash: XHash) -> Result<()> { - let mut data = self.data.lock(); - - data.total_gas_used = data + pub fn add_tx(&mut self, tx_update: ExecTxState, tx_hash: XHash) -> Result<()> { + self.total_gas_used = self .total_gas_used .checked_add(tx_update.gas_used) .ok_or(BlockTemplateError::ValueOverflow)?; - data.transactions.push(TemplateTxItem { + self.transactions.push(TemplateTxItem { tx: tx_update.tx, tx_hash, gas_used: tx_update.gas_used, @@ -282,22 +106,21 @@ impl BlockTemplate { Ok(()) } - pub fn remove_txs_above_hash(&self, target_hash: XHash) -> Result> { - let mut data = self.data.lock(); + pub fn remove_txs_above_hash(&mut self, target_hash: XHash) -> Result> { let mut removed_txs = Vec::new(); - if let Some(index) = data + if let Some(index) = self .transactions .iter() .position(|item| item.tx_hash == target_hash) { - removed_txs = data + removed_txs = self .transactions .drain(index..) .map(|tx_item| tx_item.tx_hash) .collect(); - data.total_gas_used = data.transactions.iter().try_fold(U256::zero(), |acc, tx| { + self.total_gas_used = self.transactions.iter().try_fold(U256::zero(), |acc, tx| { acc.checked_add(tx.gas_used) .ok_or(BlockTemplateError::ValueOverflow) })? @@ -306,49 +129,31 @@ impl BlockTemplate { Ok(removed_txs) } - pub fn get_total_gas_used(&self) -> U256 { - self.data.lock().total_gas_used - } - - pub fn get_target_block(&self) -> U256 { - self.data.lock().vicinity.block_number - } - - pub fn get_timestamp(&self) -> u64 { - self.data.lock().timestamp - } - pub fn get_state_root_from_native_hash(&self, hash: XHash) -> Option { - self.data - .lock() - .transactions + self.transactions .iter() .find(|tx_item| tx_item.tx_hash == hash) .map(|tx_item| tx_item.state_root) } pub fn get_latest_state_root(&self) -> H256 { - let data = self.data.lock(); - data.transactions + self.transactions .last() - .map_or(data.initial_state_root, |tx_item| tx_item.state_root) + .map_or(self.initial_state_root, |tx_item| tx_item.state_root) } pub fn get_latest_logs_bloom(&self) -> Bloom { - let data = self.data.lock(); - data.transactions + self.transactions .last() .map_or(Bloom::default(), |tx_item| tx_item.logs_bloom) } pub fn get_block_base_fee_per_gas(&self) -> U256 { - let data = self.data.lock(); - data.vicinity.block_base_fee_per_gas + self.vicinity.block_base_fee_per_gas } pub fn get_block_number(&self) -> U256 { - let data = self.data.lock(); - data.vicinity.block_number + self.vicinity.block_number } } diff --git a/lib/ain-evm/src/core.rs b/lib/ain-evm/src/core.rs index 6f7888ada2..56f7a90c90 100644 --- a/lib/ain-evm/src/core.rs +++ b/lib/ain-evm/src/core.rs @@ -24,7 +24,7 @@ use vsdb_core::vsdb_set_base_dir; use crate::{ backend::{BackendError, EVMBackend, Vicinity}, block::INITIAL_BASE_FEE, - blocktemplate::BlockTemplateMap, + blocktemplate::BlockTemplate, executor::{AinExecutor, ExecutorContext, TxResponse}, fee::calculate_max_prepay_gas_fee, gas::check_tx_intrinsic_gas, @@ -128,7 +128,6 @@ impl TxValidationCache { } pub struct EVMCoreService { - pub block_templates: Arc, pub trie_store: Arc, pub signed_tx_cache: SignedTxCache, storage: Arc, @@ -175,7 +174,6 @@ impl EVMCoreService { init_vsdb(path); Self { - block_templates: Arc::new(BlockTemplateMap::new()), trie_store: Arc::new(TrieDBStore::restore()), signed_tx_cache: SignedTxCache::default(), storage, @@ -193,7 +191,6 @@ impl EVMCoreService { init_vsdb(evm_datadir); let handler = Self { - block_templates: Arc::new(BlockTemplateMap::new()), trie_store: Arc::new(TrieDBStore::new()), signed_tx_cache: SignedTxCache::default(), storage: Arc::clone(&storage), @@ -328,7 +325,7 @@ impl EVMCoreService { /// # Arguments /// /// * `tx` - The raw tx. - /// * `template_id` - The template_id template number. + /// * `template` - The EVM BlockTemplate. /// /// # Returns /// @@ -339,8 +336,12 @@ impl EVMCoreService { /// Result cannot be used safety unless cs_main lock is taken on C++ side /// across all usages. Note: To be replaced with a proper lock flow later. /// - pub unsafe fn validate_raw_tx(&self, tx: &str, template_id: u64) -> Result { - let state_root = self.block_templates.get_latest_state_root_in(template_id)?; + pub unsafe fn validate_raw_tx( + &self, + tx: &str, + template: &BlockTemplate, + ) -> Result { + let state_root = template.get_latest_state_root(); debug!("[validate_raw_tx] state_root : {:#?}", state_root); if let Some(tx_info) = self @@ -350,7 +351,6 @@ impl EVMCoreService { return Ok(tx_info); } - debug!("[validate_raw_tx] template_id {}", template_id); debug!("[validate_raw_tx] raw transaction : {:#?}", tx); let ValidateTxInfo { @@ -473,7 +473,7 @@ impl EVMCoreService { /// # Arguments /// /// * `tx` - The raw tx. - /// * `template_id` - The template_id template number. + /// * `template` - The EVM BlockTemplate. /// /// # Returns /// @@ -487,19 +487,15 @@ impl EVMCoreService { pub unsafe fn validate_raw_transferdomain_tx( &self, tx: &str, - template_id: u64, + template: &BlockTemplate, context: TransferDomainTxInfo, ) -> Result { - debug!( - "[validate_raw_transferdomain_tx] template_id {}", - template_id - ); debug!( "[validate_raw_transferdomain_tx] raw transaction : {:#?}", tx ); - let state_root = self.block_templates.get_latest_state_root_in(template_id)?; + let state_root = template.get_latest_state_root(); debug!( "[validate_raw_transferdomain_tx] state_root : {:#?}", state_root @@ -740,16 +736,6 @@ impl EVMCoreService { // Block template methods impl EVMCoreService { - /// - /// # Safety - /// - /// Result cannot be used safety unless `cs_main` lock is taken on C++ side - /// across all usages. Note: To be replaced with a proper lock flow later. - /// - pub unsafe fn remove_block_template(&self, template_id: u64) { - self.block_templates.remove(template_id); - } - /// /// # Safety /// @@ -758,19 +744,17 @@ impl EVMCoreService { /// pub unsafe fn remove_txs_above_hash_in_block_template( &self, - template_id: u64, + template: &mut BlockTemplate, target_hash: XHash, ) -> Result> { - let hashes = self - .block_templates - .remove_txs_above_hash_in(template_id, target_hash)?; + let hashes = template.remove_txs_above_hash(target_hash)?; Ok(hashes) } /// Retrieves the next valid nonce for the specified account within a particular block template. /// # Arguments /// - /// * `template_id` - The template_id template number. + /// * `template` - The EVM BlockTemplate. /// * `address` - The EVM address of the account whose nonce we want to retrieve. /// /// # Returns @@ -784,15 +768,13 @@ impl EVMCoreService { /// pub unsafe fn get_next_valid_nonce_in_block_template( &self, - template_id: u64, + template: &BlockTemplate, address: H160, ) -> Result { - let state_root = self.block_templates.get_latest_state_root_in(template_id)?; + let state_root = template.get_latest_state_root(); let backend = self.get_backend(state_root)?; let nonce = backend.get_nonce(&address); - trace!( - "[get_next_valid_nonce_in_block_template] Account {address:x?} nonce {nonce:x?} in template_id {template_id}" - ); + trace!("[get_next_valid_nonce_in_block_template] Account {address:x?} nonce {nonce:x?}"); Ok(nonce) } } diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index bd6066d245..1105bd789f 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -16,9 +16,7 @@ use tokio::sync::{ use crate::{ backend::{EVMBackend, Vicinity}, block::BlockService, - blocktemplate::{ - BlockData, BlockTemplateData, ReceiptAndOptionalContractAddress, TemplateTxItem, - }, + blocktemplate::{BlockData, BlockTemplate, ReceiptAndOptionalContractAddress, TemplateTxItem}, contract::{ deploy_contract_tx, dfi_intrinsics_registry_deploy_info, dfi_intrinsics_v1_deploy_info, dst20_v1_deploy_info, get_dst20_migration_txs, reserve_dst20_namespace, @@ -140,12 +138,10 @@ impl EVMServices { /// pub unsafe fn construct_block_in_template( &self, - template_id: u64, + template: &mut BlockTemplate, ) -> Result { - let block_template = self.core.block_templates.get(template_id)?; - let state_root = block_template.get_latest_state_root(); - let logs_bloom = block_template.get_latest_logs_bloom(); - let mut template = block_template.data.lock(); + let state_root = template.get_latest_state_root(); + let logs_bloom = template.get_latest_logs_bloom(); let timestamp = template.timestamp; let parent_hash = template.parent_hash; @@ -160,7 +156,6 @@ impl EVMServices { let mut receipts_v3: Vec = Vec::with_capacity(txs_len); let mut total_gas_fees = U256::zero(); - debug!("[construct_block] template_id: {:?}", template_id); debug!("[construct_block] vicinity: {:?}", template.vicinity); let mut backend = EVMBackend::from_root( @@ -249,10 +244,8 @@ impl EVMServices { /// Result cannot be used safety unless cs_main lock is taken on C++ side /// across all usages. Note: To be replaced with a proper lock flow later. /// - pub unsafe fn commit_block(&self, template_id: u64) -> Result<()> { + pub unsafe fn commit_block(&self, template: &BlockTemplate) -> Result<()> { { - let block_template = self.core.block_templates.get(template_id)?; - let template = block_template.data.lock(); let Some(BlockData { block, receipts }) = template.block_data.clone() else { return Err(format_err!("no constructed EVM block exist in template id").into()); }; @@ -273,7 +266,7 @@ impl EVMServices { .send(Notification::Block(block.header.hash())) .map_err(|e| format_err!(e.to_string()))?; } - self.core.block_templates.remove(template_id); + // self.core.block_templates.remove(template); self.core.clear_account_nonce(); self.core.clear_transaction_cache(); @@ -282,18 +275,16 @@ impl EVMServices { unsafe fn update_block_template_state_from_tx( &self, - template_id: u64, + template: &BlockTemplate, tx: ExecuteTx, ) -> Result { - let block_template = self.core.block_templates.get(template_id)?; - let state_root = block_template.get_latest_state_root(); - let mut logs_bloom = block_template.get_latest_logs_bloom(); + let state_root = template.get_latest_state_root(); + let mut logs_bloom = template.get_latest_logs_bloom(); debug!( "[update_block_template_state_from_tx] state_root : {:#?}", state_root ); - let template = block_template.data.lock(); let mut backend = EVMBackend::from_root( state_root, Arc::clone(&self.core.trie_store), @@ -334,16 +325,14 @@ impl EVMServices { /// pub unsafe fn update_state_in_block_template( &self, - template_id: u64, + template: &mut BlockTemplate, mnview_ptr: usize, ) -> Result<()> { - // reserve DST20 namespace - let block_template = self.core.block_templates.get(template_id)?; - let is_evm_genesis_block = block_template.get_block_number() == U256::zero(); - let state_root = block_template.get_latest_state_root(); - let mut logs_bloom = block_template.get_latest_logs_bloom(); + // reserve DST20 namespace; + let is_evm_genesis_block = template.get_block_number() == U256::zero(); + let state_root = template.get_latest_state_root(); + let mut logs_bloom = template.get_latest_logs_bloom(); - let mut template = block_template.data.lock(); let mut backend = EVMBackend::from_root( state_root, Arc::clone(&self.core.trie_store), @@ -515,7 +504,7 @@ impl EVMServices { beneficiary: H160, difficulty: u32, timestamp: u64, - ) -> Result { + ) -> Result { let (target_block, initial_state_root) = match self.storage.get_latest_block()? { None => (U256::zero(), GENESIS_STATE_ROOT), // Genesis block Some(block) => ( @@ -536,11 +525,8 @@ impl EVMServices { let block_base_fee_per_gas = self.block.calculate_base_fee(parent_hash)?; let block_gas_limit = U256::from(self.storage.get_attributes_or_default()?.block_gas_limit); - let template_id = self.core.block_templates.create(BlockTemplateData { - transactions: Vec::new(), - block_data: None, - total_gas_used: U256::zero(), - vicinity: Vicinity { + let template = BlockTemplate::new( + Vicinity { beneficiary, block_number: target_block, timestamp: U256::from(timestamp), @@ -555,18 +541,17 @@ impl EVMServices { dvm_block, timestamp, initial_state_root, - }); - Ok(template_id) + ); + Ok(template) } unsafe fn verify_tx_fees_in_block_template( &self, - template_id: u64, + template: &BlockTemplate, tx: &ExecuteTx, ) -> Result<()> { if let ExecuteTx::SignedTx(signed_tx) = tx { - let block_template = self.core.block_templates.get(template_id)?; - let base_fee_per_gas = block_template.get_block_base_fee_per_gas(); + let base_fee_per_gas = template.get_block_base_fee_per_gas(); let tx_gas_price = signed_tx.gas_price(); if tx_gas_price < base_fee_per_gas { @@ -587,21 +572,19 @@ impl EVMServices { /// pub unsafe fn push_tx_in_block_template( &self, - template_id: u64, + template: &mut BlockTemplate, tx: ExecuteTx, hash: XHash, ) -> Result<()> { - self.verify_tx_fees_in_block_template(template_id, &tx)?; - let tx_update = self.update_block_template_state_from_tx(template_id, tx.clone())?; + self.verify_tx_fees_in_block_template(template, &tx)?; + let tx_update = self.update_block_template_state_from_tx(template, tx.clone())?; let tx_hash = tx_update.tx.hash(); debug!( - "[push_tx_in_block_template] Pushing new state_root {:x?} to template_id {}", - tx_update.state_root, template_id + "[push_tx_in_block_template] Pushing new state_root {:x?}", + tx_update.state_root ); - self.core - .block_templates - .push_in(template_id, tx_update, hash)?; + template.add_tx(tx_update, hash)?; self.filters.add_tx_to_filters(tx_hash); Ok(()) @@ -616,13 +599,9 @@ impl EVMServices { pub unsafe fn is_smart_contract_in_block_template( &self, address: H160, - template_id: u64, + template: &BlockTemplate, ) -> Result { - let backend = self.core.get_backend( - self.core - .block_templates - .get_latest_state_root_in(template_id)?, - )?; + let backend = self.core.get_backend(template.get_latest_state_root())?; Ok(match backend.get_account(&address) { None => false, diff --git a/lib/ain-evm/src/log.rs b/lib/ain-evm/src/log.rs index e5ce76c3f6..35b3821f25 100644 --- a/lib/ain-evm/src/log.rs +++ b/lib/ain-evm/src/log.rs @@ -1,6 +1,6 @@ -use anyhow::format_err; use std::{collections::HashMap, sync::Arc}; +use anyhow::format_err; use ethereum::ReceiptV3; use ethereum_types::{H160, H256, U256}; use log::debug; diff --git a/lib/ain-evm/src/receipt.rs b/lib/ain-evm/src/receipt.rs index 53841bad23..d84de38089 100644 --- a/lib/ain-evm/src/receipt.rs +++ b/lib/ain-evm/src/receipt.rs @@ -1,6 +1,6 @@ -use anyhow::format_err; use std::sync::Arc; +use anyhow::format_err; use ethereum::{util::ordered_trie_root, EnvelopedEncodable, ReceiptV3}; use ethereum_types::{H160, H256, U256}; use keccak_hash::keccak; diff --git a/lib/ain-evm/src/transaction/mod.rs b/lib/ain-evm/src/transaction/mod.rs index f5b6264391..4b3f93a0c8 100644 --- a/lib/ain-evm/src/transaction/mod.rs +++ b/lib/ain-evm/src/transaction/mod.rs @@ -1,6 +1,5 @@ pub mod system; -use crate::EVMError; use anyhow::format_err; use ethereum::{ AccessList, EnvelopedDecoderError, EnvelopedEncodable, LegacyTransaction, TransactionAction, @@ -10,7 +9,10 @@ use ethereum_types::{H160, H256, U256}; use rlp::RlpStream; use sha3::Digest; -use crate::ecrecover::{public_key_to_address, recover_public_key}; +use crate::{ + ecrecover::{public_key_to_address, recover_public_key}, + EVMError, +}; // Lowest acceptable value for r and s in sig. pub const LOWER_H256: H256 = H256([ diff --git a/lib/ain-grpc/src/rpc/debug.rs b/lib/ain-grpc/src/rpc/debug.rs index 01895a41e5..9430f85e4b 100644 --- a/lib/ain-grpc/src/rpc/debug.rs +++ b/lib/ain-grpc/src/rpc/debug.rs @@ -215,8 +215,8 @@ impl MetachainDebugRPCServer for MetachainDebugRPCModule { } fn log_block_templates(&self) -> RpcResult<()> { - let templates = &self.handler.core.block_templates; - debug!("templates : {:#?}", templates); + // let templates = &self.handler.core.block_templates; + // debug!("templates : {:#?}", templates); Ok(()) } } diff --git a/lib/ain-rs-exports/src/evm.rs b/lib/ain-rs-exports/src/evm.rs index 6a263eafe9..f32bf922ea 100644 --- a/lib/ain-rs-exports/src/evm.rs +++ b/lib/ain-rs-exports/src/evm.rs @@ -3,6 +3,7 @@ use ain_contracts::{ get_transferdomain_native_transfer_function, FixedContract, }; use ain_evm::{ + blocktemplate::BlockTemplate, core::{TransferDomainTxInfo, XHash}, evm::FinalizedBlockInfo, executor::ExecuteTx, @@ -25,8 +26,9 @@ use log::debug; use transaction::{LegacyUnsignedTransaction, LOWER_H256}; use crate::{ - ffi::{self, TxMinerInfo}, + ffi::{self, CrossBoundaryResult, TxMinerInfo}, prelude::*, + BlockTemplateWrapper, }; /// Creates and signs a transaction. @@ -207,44 +209,50 @@ fn evm_try_get_balance(address: &str) -> Result { Ok(amount) } -/// Updates the block template in a specific template_id as a `u64` +/// Updates the block template in a specific template /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `mnview_ptr` - The pointer to the DVM accounts view. /// /// # Returns /// /// The state update results. #[ffi_fallible] -fn evm_try_unsafe_update_state_in_template(template_id: u64, mnview_ptr: usize) -> Result<()> { +fn evm_try_unsafe_update_state_in_template( + template: &mut BlockTemplateWrapper, + mnview_ptr: usize, +) -> Result<()> { unsafe { SERVICES .evm - .update_state_in_block_template(template_id, mnview_ptr) + .update_state_in_block_template(&mut template.0, mnview_ptr) } } -/// Retrieves the next valid nonce of an EVM account in a specific template_id +/// Retrieves the next valid nonce of an EVM account in a specific template /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `address` - The EVM address of the account. /// /// # Returns /// -/// Returns the next valid nonce of the account in a specific template_id as a `u64` +/// Returns the next valid nonce of the account in a specific template #[ffi_fallible] -fn evm_try_unsafe_get_next_valid_nonce_in_template(template_id: u64, address: &str) -> Result { +fn evm_try_unsafe_get_next_valid_nonce_in_template( + template: &mut BlockTemplateWrapper, + address: &str, +) -> Result { let address = address.parse::().map_err(|_| "Invalid address")?; unsafe { let next_nonce = SERVICES .evm .core - .get_next_valid_nonce_in_block_template(template_id, address)?; + .get_next_valid_nonce_in_block_template(&template.0, address)?; let nonce = u64::try_from(next_nonce)?; Ok(nonce) @@ -255,18 +263,18 @@ fn evm_try_unsafe_get_next_valid_nonce_in_template(template_id: u64, address: &s /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `target_hash` - The native hash of the tx to be targeted and removed. #[ffi_fallible] fn evm_try_unsafe_remove_txs_above_hash_in_template( - template_id: u64, + template: &mut BlockTemplateWrapper, target_hash: String, ) -> Result> { unsafe { SERVICES .evm .core - .remove_txs_above_hash_in_block_template(template_id, target_hash) + .remove_txs_above_hash_in_block_template(&mut template.0, target_hash) } } @@ -274,12 +282,12 @@ fn evm_try_unsafe_remove_txs_above_hash_in_template( /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `raw_tx` - The raw transparent transferdomain tx. /// * `hash` - The native hash of the transferdomain tx. #[ffi_fallible] fn evm_try_unsafe_add_balance_in_template( - template_id: u64, + template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, ) -> Result<()> { @@ -294,11 +302,10 @@ fn evm_try_unsafe_add_balance_in_template( signed_tx: Box::new(signed_tx), direction: TransferDirection::EvmIn, })); - unsafe { SERVICES .evm - .push_tx_in_block_template(template_id, exec_tx, native_hash) + .push_tx_in_block_template(&mut template.0, exec_tx, native_hash) } } @@ -306,12 +313,12 @@ fn evm_try_unsafe_add_balance_in_template( /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `raw_tx` - The raw transparent transferdomain tx. /// * `hash` - The native hash of the transferdomain tx. #[ffi_fallible] fn evm_try_unsafe_sub_balance_in_template( - template_id: u64, + template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, ) -> Result { @@ -330,7 +337,7 @@ fn evm_try_unsafe_sub_balance_in_template( unsafe { SERVICES .evm - .push_tx_in_block_template(template_id, exec_tx, native_hash)?; + .push_tx_in_block_template(&mut template.0, exec_tx, native_hash)?; Ok(true) } } @@ -340,7 +347,7 @@ fn evm_try_unsafe_sub_balance_in_template( /// # Arguments /// /// * `result` - Result object -/// * `template_id` - The EVM template ID +/// * `template` - The EVM BlockTemplate /// * `tx` - The raw transaction string. /// /// # Errors @@ -359,10 +366,13 @@ fn evm_try_unsafe_sub_balance_in_template( /// /// Returns the validation result. #[ffi_fallible] -fn evm_try_unsafe_validate_raw_tx_in_template(template_id: u64, raw_tx: &str) -> Result<()> { +fn evm_try_unsafe_validate_raw_tx_in_template( + template: &mut BlockTemplateWrapper, + raw_tx: &str, +) -> Result<()> { debug!("[unsafe_validate_raw_tx_in_template]"); unsafe { - let _ = SERVICES.evm.core.validate_raw_tx(raw_tx, template_id)?; + let _ = SERVICES.evm.core.validate_raw_tx(raw_tx, &template.0)?; Ok(()) } } @@ -372,7 +382,7 @@ fn evm_try_unsafe_validate_raw_tx_in_template(template_id: u64, raw_tx: &str) -> /// # Arguments /// /// * `result` - Result object -/// * `template_id` - The EVM template ID +/// * `template` - The EVM BlockTemplate /// * `tx` - The raw transaction string. /// /// # Errors @@ -391,7 +401,7 @@ fn evm_try_unsafe_validate_raw_tx_in_template(template_id: u64, raw_tx: &str) -> /// Returns the validation result. #[ffi_fallible] fn evm_try_unsafe_validate_transferdomain_tx_in_template( - template_id: u64, + template: &mut BlockTemplateWrapper, raw_tx: &str, context: ffi::TransferDomainInfo, ) -> Result<()> { @@ -399,7 +409,7 @@ fn evm_try_unsafe_validate_transferdomain_tx_in_template( unsafe { let _ = SERVICES.evm.core.validate_raw_transferdomain_tx( raw_tx, - template_id, + &template.0, TransferDomainTxInfo { from: context.from, to: context.to, @@ -409,34 +419,60 @@ fn evm_try_unsafe_validate_transferdomain_tx_in_template( token_id: context.token_id, }, )?; - Ok(()) + } + Ok(()) +} + +fn block_template_err_wrapper() -> &'static mut BlockTemplateWrapper { + // We don't really care if multiple thread reinitialize or use it as long as the refs live + // So we just use unsafe mut pattern since it's purely for err condition that is intented + // to never be used + static mut CELL: std::cell::OnceCell = std::cell::OnceCell::new(); + unsafe { + let v = CELL.get_or_init(|| BlockTemplateWrapper(BlockTemplate::default())); + #[allow(mutable_transmutes)] + std::mem::transmute(v) } } -/// Retrieves the EVM template ID. +/// Creates an EVM block template. /// /// # Returns /// -/// Returns the EVM template ID as a `u64`. -#[ffi_fallible] -fn evm_try_unsafe_create_template( +/// Returns the EVM template. +pub fn evm_try_unsafe_create_template( + result: &mut CrossBoundaryResult, dvm_block: u64, miner_address: &str, difficulty: u32, timestamp: u64, -) -> Result { +) -> &'static mut BlockTemplateWrapper { let miner_address = if miner_address.is_empty() { H160::zero() } else { - miner_address - .parse::() - .map_err(|_| "Invalid address")? + match miner_address.parse::() { + Ok(a) => a, + Err(_) => { + cross_boundary_error(result, "Invalid address"); + return block_template_err_wrapper(); + } + } }; unsafe { - SERVICES + match SERVICES .evm .create_block_template(dvm_block, miner_address, difficulty, timestamp) + { + Ok(template) => cross_boundary_success_return( + result, + Box::leak(Box::new(BlockTemplateWrapper(template))), + ), + Err(e) => { + cross_boundary_error(result, e.to_string()); + return block_template_err_wrapper(); + } + } } } @@ -444,11 +480,14 @@ fn evm_try_unsafe_create_template( /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// #[ffi_fallible] -fn evm_try_unsafe_remove_template(template_id: u64) -> Result<()> { - unsafe { SERVICES.evm.core.remove_block_template(template_id) } +fn evm_try_unsafe_remove_template(template: &mut BlockTemplateWrapper) -> Result<()> { + // Will be dropped when Box out of scope (end of this fn) + unsafe { + let _ = Box::from_raw(template); + } Ok(()) } @@ -456,7 +495,7 @@ fn evm_try_unsafe_remove_template(template_id: u64) -> Result<()> { /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `raw_tx` - The raw transaction string. /// * `hash` - The native transaction hash. /// @@ -468,7 +507,7 @@ fn evm_try_unsafe_remove_template(template_id: u64) -> Result<()> { /// #[ffi_fallible] fn evm_try_unsafe_push_tx_in_template( - template_id: u64, + template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, ) -> Result { @@ -484,7 +523,7 @@ fn evm_try_unsafe_push_tx_in_template( let tx_hash = signed_tx.hash(); SERVICES .evm - .push_tx_in_block_template(template_id, signed_tx.into(), native_hash)?; + .push_tx_in_block_template(&mut template.0, signed_tx.into(), native_hash)?; Ok(ffi::ValidateTxCompletion { tx_hash: format!("{:?}", tx_hash), @@ -496,7 +535,7 @@ fn evm_try_unsafe_push_tx_in_template( /// /// # Arguments /// -/// * `template_id` - The template ID. +/// * `template` - The EVM BlockTemplate. /// * `difficulty` - The block's difficulty. /// * `miner_address` - The miner's EVM address as a byte array. /// * `timestamp` - The block's timestamp. @@ -506,7 +545,7 @@ fn evm_try_unsafe_push_tx_in_template( /// Returns a `FinalizeBlockResult` containing the block hash, failed transactions, burnt fees and priority fees (in satoshis) on success. #[ffi_fallible] fn evm_try_unsafe_construct_block_in_template( - template_id: u64, + template: &mut BlockTemplateWrapper, ) -> Result { unsafe { let FinalizedBlockInfo { @@ -514,7 +553,7 @@ fn evm_try_unsafe_construct_block_in_template( total_burnt_fees, total_priority_fees, block_number, - } = SERVICES.evm.construct_block_in_template(template_id)?; + } = SERVICES.evm.construct_block_in_template(&mut template.0)?; let total_burnt_fees = u64::try_from(WeiAmount(total_burnt_fees).to_satoshi()?)?; let total_priority_fees = u64::try_from(WeiAmount(total_priority_fees).to_satoshi()?)?; @@ -528,8 +567,8 @@ fn evm_try_unsafe_construct_block_in_template( } #[ffi_fallible] -fn evm_try_unsafe_commit_block(template_id: u64) -> Result<()> { - unsafe { SERVICES.evm.commit_block(template_id) } +fn evm_try_unsafe_commit_block(template: &mut BlockTemplateWrapper) -> Result<()> { + unsafe { SERVICES.evm.commit_block(&template.0) } } #[ffi_fallible] @@ -539,8 +578,8 @@ fn evm_try_disconnect_latest_block() -> Result<()> { } #[ffi_fallible] -fn evm_try_handle_attribute_apply( - _template_id: u64, +fn evm_try_unsafe_handle_attribute_apply( + _template: &mut BlockTemplateWrapper, _attribute_type: ffi::GovVarKeyDataStructure, _value: Vec, ) -> Result { @@ -682,8 +721,8 @@ fn evm_try_get_tx_by_hash(tx_hash: &str) -> Result { } #[ffi_fallible] -fn evm_try_create_dst20( - template_id: u64, +fn evm_try_unsafe_create_dst20( + template: &mut BlockTemplateWrapper, native_hash: &str, name: &str, symbol: &str, @@ -703,13 +742,13 @@ fn evm_try_create_dst20( unsafe { SERVICES .evm - .push_tx_in_block_template(template_id, system_tx, native_hash) + .push_tx_in_block_template(&mut template.0, system_tx, native_hash) } } #[ffi_fallible] fn evm_try_unsafe_bridge_dst20( - template_id: u64, + template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, token_id: u64, @@ -731,7 +770,7 @@ fn evm_try_unsafe_bridge_dst20( unsafe { SERVICES .evm - .push_tx_in_block_template(template_id, system_tx, native_hash) + .push_tx_in_block_template(&mut template.0, system_tx, native_hash) } } @@ -763,13 +802,16 @@ fn evm_try_get_tx_hash(raw_tx: &str) -> Result { /// /// Returns `true` if the address is a contract, `false` otherwise #[ffi_fallible] -fn evm_try_unsafe_is_smart_contract_in_template(address: &str, template_id: u64) -> Result { +fn evm_try_unsafe_is_smart_contract_in_template( + address: &str, + template: &mut BlockTemplateWrapper, +) -> Result { let address = address.parse::().map_err(|_| "Invalid address")?; unsafe { SERVICES .evm - .is_smart_contract_in_block_template(address, template_id) + .is_smart_contract_in_block_template(address, &template.0) } } @@ -815,27 +857,3 @@ fn evm_try_dispatch_pending_transactions_event(raw_tx: &str) -> Result<()> { .send(Notification::Transaction(signed_tx.hash())) .map_err(|e| format_err!(e.to_string()))?) } - -#[cfg(test)] -mod tests { - #[test] - fn test_hash_type_string() { - use ethereum_types::H160; - let num = 0b11010111_11010111_11010111_11010111_11010111_11010111_11010111_11010111; - let num_h160 = H160::from_low_u64_be(num); - let num_h160_string = format!("{:?}", num_h160); - println!("{}", num_h160_string); - - let num_h160_test: H160 = num_h160_string.parse().unwrap(); - assert_eq!(num_h160_test, num_h160); - - use ethereum_types::H256; - let num_h256: H256 = "0x3186715414c5fbd73586662d26b83b66b5754036379d56e896a560a90e409351" - .parse() - .unwrap(); - let num_h256_string = format!("{:?}", num_h256); - println!("{}", num_h256_string); - let num_h256_test: H256 = num_h256_string.parse().unwrap(); - assert_eq!(num_h256_test, num_h256); - } -} diff --git a/lib/ain-rs-exports/src/lib.rs b/lib/ain-rs-exports/src/lib.rs index facf766474..973506ba1b 100644 --- a/lib/ain-rs-exports/src/lib.rs +++ b/lib/ain-rs-exports/src/lib.rs @@ -3,6 +3,10 @@ mod evm; mod prelude; use crate::{core::*, evm::*}; +use ain_evm::blocktemplate::BlockTemplate; + +#[derive(Debug)] +pub struct BlockTemplateWrapper(BlockTemplate); #[cxx::bridge] pub mod ffi { @@ -134,19 +138,26 @@ pub mod ffi { } extern "Rust" { + type BlockTemplateWrapper; // In-fallible functions // // If they are fallible, it's a TODO to changed and move later // so errors are propogated up properly. fn evm_try_get_balance(result: &mut CrossBoundaryResult, address: &str) -> u64; + fn evm_try_unsafe_create_template( result: &mut CrossBoundaryResult, dvm_block: u64, miner_address: &str, difficulty: u32, timestamp: u64, - ) -> u64; - fn evm_try_unsafe_remove_template(result: &mut CrossBoundaryResult, template_id: u64); + ) -> &'static mut BlockTemplateWrapper; + + fn evm_try_unsafe_remove_template( + result: &mut CrossBoundaryResult, + block_template: &mut BlockTemplateWrapper, + ); + fn evm_try_disconnect_latest_block(result: &mut CrossBoundaryResult); // Failible functions @@ -154,81 +165,101 @@ pub mod ffi { // Has to start with try_ / evm_try fn evm_try_unsafe_update_state_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, mnview_ptr: usize, ); + fn evm_try_unsafe_get_next_valid_nonce_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, address: &str, ) -> u64; + fn evm_try_unsafe_remove_txs_above_hash_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, target_hash: String, ) -> Vec; + fn evm_try_unsafe_add_balance_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, ); + fn evm_try_unsafe_sub_balance_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, ) -> bool; + fn evm_try_unsafe_validate_raw_tx_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, raw_tx: &str, ); + fn evm_try_unsafe_validate_transferdomain_tx_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, raw_tx: &str, context: TransferDomainInfo, ); + fn evm_try_unsafe_push_tx_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, ) -> ValidateTxCompletion; + fn evm_try_unsafe_construct_block_in_template( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, ) -> FinalizeBlockCompletion; - fn evm_try_unsafe_commit_block(result: &mut CrossBoundaryResult, template_id: u64); - fn evm_try_handle_attribute_apply( + + fn evm_try_unsafe_commit_block( + result: &mut CrossBoundaryResult, + block_template: &mut BlockTemplateWrapper, + ); + + fn evm_try_unsafe_handle_attribute_apply( result: &mut CrossBoundaryResult, - template_id: u64, + block_template: &mut BlockTemplateWrapper, attribute_type: GovVarKeyDataStructure, value: Vec, ) -> bool; + fn evm_try_create_and_sign_tx( result: &mut CrossBoundaryResult, ctx: CreateTransactionContext, ) -> CreateTxResult; + fn evm_try_create_and_sign_transfer_domain_tx( result: &mut CrossBoundaryResult, ctx: CreateTransferDomainContext, ) -> CreateTxResult; + fn evm_try_store_account_nonce( result: &mut CrossBoundaryResult, from_address: &str, nonce: u64, ); + fn evm_try_get_block_hash_by_number( result: &mut CrossBoundaryResult, height: u64, ) -> String; + fn evm_try_get_block_number_by_hash(result: &mut CrossBoundaryResult, hash: &str) -> u64; + fn evm_try_get_block_header_by_hash( result: &mut CrossBoundaryResult, hash: &str, ) -> EVMBlockHeader; + fn evm_try_get_tx_by_hash( result: &mut CrossBoundaryResult, tx_hash: &str, @@ -236,31 +267,35 @@ pub mod ffi { fn evm_try_get_tx_hash(result: &mut CrossBoundaryResult, raw_tx: &str) -> String; - fn evm_try_create_dst20( + fn evm_try_unsafe_create_dst20( result: &mut CrossBoundaryResult, - context: u64, + block_template: &mut BlockTemplateWrapper, native_hash: &str, name: &str, symbol: &str, token_id: u64, ); + fn evm_try_unsafe_bridge_dst20( result: &mut CrossBoundaryResult, - context: u64, + block_template: &mut BlockTemplateWrapper, raw_tx: &str, native_hash: &str, token_id: u64, out: bool, ); + fn evm_try_unsafe_is_smart_contract_in_template( result: &mut CrossBoundaryResult, address: &str, - template_id: u64, + block_template: &mut BlockTemplateWrapper, ) -> bool; + fn evm_try_get_tx_miner_info_from_raw_tx( result: &mut CrossBoundaryResult, raw_tx: &str, ) -> TxMinerInfo; + fn evm_try_dispatch_pending_transactions_event( result: &mut CrossBoundaryResult, raw_tx: &str, diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 599ae6fd37..d2b5241f73 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -180,10 +180,10 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c if (IsBelowDakotaMintTokenOrAccountToUtxos(txType, nSpendHeight) || (nSpendHeight >= chainparams.GetConsensus().DF20GrandCentralHeight && txType == CustomTxType::UpdateMasternode)) { CCustomCSView discardCache(mnview, nullptr, nullptr, nullptr); - // Note: TXs are already filtered. So we pass isEVMEnabled to false, but for future proof, refactor this enough, + // Note: TXs are already filtered. So we pass isEVMEnabled to false, but for future proof, refactor this enough, // that it's propagated. - std::shared_ptr evmTemplateId{}; - auto res = ApplyCustomTx(discardCache, inputs, tx, chainparams.GetConsensus(), nSpendHeight, 0, &canSpend, 0, evmTemplateId, false, false); + std::shared_ptr evmTemplate{}; + auto res = ApplyCustomTx(discardCache, inputs, tx, chainparams.GetConsensus(), nSpendHeight, 0, &canSpend, 0, evmTemplate, false, false); if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) { return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-customtx", res.msg); } diff --git a/src/dfi/consensus/governance.cpp b/src/dfi/consensus/governance.cpp index b964be1b6f..7861e79a5e 100644 --- a/src/dfi/consensus/governance.cpp +++ b/src/dfi/consensus/governance.cpp @@ -28,7 +28,7 @@ Res CGovernanceConsensus::operator()(const CGovernanceMessage &obj) const { } govVar->time = time; - govVar->evmTemplateId = evmTemplateId; + govVar->evmTemplate = evmTemplate; auto newVar = std::dynamic_pointer_cast(var); if (!newVar) { diff --git a/src/dfi/consensus/loans.cpp b/src/dfi/consensus/loans.cpp index 16b4e964be..e515db2dc5 100644 --- a/src/dfi/consensus/loans.cpp +++ b/src/dfi/consensus/loans.cpp @@ -290,7 +290,7 @@ Res CLoansConsensus::operator()(const CLoanSetLoanTokenMessage &obj) const { : static_cast(CToken::TokenFlags::Tradeable); token.flags |= static_cast(CToken::TokenFlags::LoanToken) | static_cast(CToken::TokenFlags::DAT); - auto tokenId = mnview.CreateToken(token, false, isEvmEnabledForBlock, evmTemplateId); + auto tokenId = mnview.CreateToken(token, false, isEvmEnabledForBlock, evmTemplate); if (!tokenId) { return tokenId; } @@ -300,7 +300,7 @@ Res CLoansConsensus::operator()(const CLoanSetLoanTokenMessage &obj) const { auto attributes = mnview.GetAttributes(); attributes->time = time; - attributes->evmTemplateId = evmTemplateId; + attributes->evmTemplate = evmTemplate; CDataStructureV0 mintEnabled{AttributeTypes::Token, id, TokenKeys::LoanMintingEnabled}; CDataStructureV0 mintInterest{AttributeTypes::Token, id, TokenKeys::LoanMintingInterest}; diff --git a/src/dfi/consensus/tokens.cpp b/src/dfi/consensus/tokens.cpp index 2fce316ffc..b6897be0dd 100644 --- a/src/dfi/consensus/tokens.cpp +++ b/src/dfi/consensus/tokens.cpp @@ -104,7 +104,7 @@ Res CTokensConsensus::operator()(const CCreateTokenMessage &obj) const { } auto tokenId = mnview.CreateToken( - token, static_cast(height) < consensus.DF2BayfrontHeight, isEvmEnabledForBlock, evmTemplateId); + token, static_cast(height) < consensus.DF2BayfrontHeight, isEvmEnabledForBlock, evmTemplate); return tokenId; } diff --git a/src/dfi/consensus/txvisitor.cpp b/src/dfi/consensus/txvisitor.cpp index 1c3ae2a827..3c39ea4e90 100644 --- a/src/dfi/consensus/txvisitor.cpp +++ b/src/dfi/consensus/txvisitor.cpp @@ -96,7 +96,7 @@ CCustomTxVisitor::CCustomTxVisitor(const CTransaction &tx, const Consensus::Params &consensus, const uint64_t time, const uint32_t txn, - const std::shared_ptr &evmTemplateId, + const std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate) : height(height), @@ -106,7 +106,7 @@ CCustomTxVisitor::CCustomTxVisitor(const CTransaction &tx, consensus(consensus), time(time), txn(txn), - evmTemplateId(evmTemplateId), + evmTemplate(evmTemplate), isEvmEnabledForBlock(isEvmEnabledForBlock), evmPreValidate(evmPreValidate) {} diff --git a/src/dfi/consensus/txvisitor.h b/src/dfi/consensus/txvisitor.h index ed7a069ed6..46d79c1545 100644 --- a/src/dfi/consensus/txvisitor.h +++ b/src/dfi/consensus/txvisitor.h @@ -18,7 +18,7 @@ class CCustomCSView; struct CLoanSchemeData; class CPoolPair; class CScript; -class CScopedTemplateID; +class CScopedTemplate; class CTokenImplementation; class CTransaction; class CVaultAssets; @@ -56,7 +56,7 @@ class CCustomTxVisitor { const Consensus::Params &consensus; const uint64_t time; const uint32_t txn; - const std::shared_ptr &evmTemplateId; + const std::shared_ptr &evmTemplate; bool isEvmEnabledForBlock; bool evmPreValidate; @@ -68,7 +68,7 @@ class CCustomTxVisitor { const Consensus::Params &consensus, const uint64_t time, const uint32_t txn, - const std::shared_ptr &evmTemplateId, + const std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate); diff --git a/src/dfi/consensus/xvm.cpp b/src/dfi/consensus/xvm.cpp index aef0ad7110..351368bd14 100644 --- a/src/dfi/consensus/xvm.cpp +++ b/src/dfi/consensus/xvm.cpp @@ -253,8 +253,8 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } // Check if destination address is a contract - auto isSmartContract = evm_try_unsafe_is_smart_contract_in_template( - result, toAddress->GetHex(), evmTemplateId->GetTemplateID()); + auto isSmartContract = + evm_try_unsafe_is_smart_contract_in_template(result, toAddress->GetHex(), evmTemplate->GetTemplate()); if (!result.ok) { return Res::Err("Error checking contract address: %s", result.reason); } @@ -283,7 +283,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } const auto evmTx = HexStr(dst.data); evm_try_unsafe_validate_transferdomain_tx_in_template( - result, evmTemplateId->GetTemplateID(), evmTx, contexts[idx]); + result, evmTemplate->GetTemplate(), evmTx, contexts[idx]); if (!result.ok) { return Res::Err("transferdomain evm tx failed to pre-validate : %s", result.reason); } @@ -300,13 +300,13 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { auto tokenId = dst.amount.nTokenId; if (tokenId == DCT_ID{0}) { evm_try_unsafe_add_balance_in_template( - result, evmTemplateId->GetTemplateID(), evmTx, tx.GetHash().GetHex()); + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex()); if (!result.ok) { return Res::Err("Error bridging DFI: %s", result.reason); } } else { evm_try_unsafe_bridge_dst20( - result, evmTemplateId->GetTemplateID(), evmTx, tx.GetHash().GetHex(), tokenId.v, true); + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex(), tokenId.v, true); if (!result.ok) { return Res::Err("Error bridging DST20: %s", result.reason); } @@ -326,8 +326,8 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } // Check if source address is a contract - auto isSmartContract = evm_try_unsafe_is_smart_contract_in_template( - result, fromAddress->GetHex(), evmTemplateId->GetTemplateID()); + auto isSmartContract = + evm_try_unsafe_is_smart_contract_in_template(result, fromAddress->GetHex(), evmTemplate->GetTemplate()); if (!result.ok) { return Res::Err("Error checking contract address: %s", result.reason); } @@ -340,7 +340,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } const auto evmTx = HexStr(src.data); evm_try_unsafe_validate_transferdomain_tx_in_template( - result, evmTemplateId->GetTemplateID(), evmTx, contexts[idx]); + result, evmTemplate->GetTemplate(), evmTx, contexts[idx]); if (!result.ok) { return Res::Err("transferdomain evm tx failed to pre-validate %s", result.reason); } @@ -358,7 +358,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { auto tokenId = dst.amount.nTokenId; if (tokenId == DCT_ID{0}) { if (!evm_try_unsafe_sub_balance_in_template( - result, evmTemplateId->GetTemplateID(), evmTx, tx.GetHash().GetHex())) { + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex())) { return DeFiErrors::TransferDomainNotEnoughBalance(EncodeDestination(dest)); } if (!result.ok) { @@ -366,7 +366,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } } else { evm_try_unsafe_bridge_dst20( - result, evmTemplateId->GetTemplateID(), evmTx, tx.GetHash().GetHex(), tokenId.v, false); + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex(), tokenId.v, false); if (!result.ok) { return Res::Err("Error bridging DST20: %s", result.reason); } @@ -379,7 +379,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { res = mnview.AddBalance(dst.address, dst.amount); if (!res) { evm_try_unsafe_remove_txs_above_hash_in_template( - result, evmTemplateId->GetTemplateID(), tx.GetHash().GetHex()); + result, evmTemplate->GetTemplate(), tx.GetHash().GetHex()); return res; } stats.evmDvmTotal.Add(dst.amount); @@ -405,7 +405,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { attributes->SetValue(CTransferDomainStatsLive::Key, stats); res = mnview.SetVariable(*attributes); if (!res) { - evm_try_unsafe_remove_txs_above_hash_in_template(result, evmTemplateId->GetTemplateID(), tx.GetHash().GetHex()); + evm_try_unsafe_remove_txs_above_hash_in_template(result, evmTemplate->GetTemplate(), tx.GetHash().GetHex()); return res; } return Res::Ok(); @@ -422,7 +422,7 @@ Res CXVMConsensus::operator()(const CEvmTxMessage &obj) const { CrossBoundaryResult result; if (evmPreValidate) { - evm_try_unsafe_validate_raw_tx_in_template(result, evmTemplateId->GetTemplateID(), HexStr(obj.evmTx)); + evm_try_unsafe_validate_raw_tx_in_template(result, evmTemplate->GetTemplate(), HexStr(obj.evmTx)); if (!result.ok) { return Res::Err("evm tx failed to pre-validate %s", result.reason); } @@ -430,7 +430,7 @@ Res CXVMConsensus::operator()(const CEvmTxMessage &obj) const { } const auto validateResults = evm_try_unsafe_push_tx_in_template( - result, evmTemplateId->GetTemplateID(), HexStr(obj.evmTx), tx.GetHash().GetHex()); + result, evmTemplate->GetTemplate(), HexStr(obj.evmTx), tx.GetHash().GetHex()); if (!result.ok) { LogPrintf("[evm_try_push_tx_in_template] failed, reason : %s\n", result.reason); return Res::Err("evm tx failed to queue %s\n", result.reason); diff --git a/src/dfi/evm.cpp b/src/dfi/evm.cpp index c6e3f39699..dd0ac2634a 100644 --- a/src/dfi/evm.cpp +++ b/src/dfi/evm.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include Res CVMDomainGraphView::SetVMDomainBlockEdge(VMDomainEdge type, std::string blockHashKey, std::string blockHash) { @@ -54,29 +55,26 @@ void CVMDomainGraphView::ForEachVMDomainTxEdges( std::make_pair(static_cast(start.first), start.second)); } -CScopedTemplateID::CScopedTemplateID(uint64_t id) - : evmTemplateId(id) {} +CScopedTemplate::CScopedTemplate(BlockTemplateWrapper &evmTemplate) + : evmTemplate(evmTemplate) {} -std::shared_ptr CScopedTemplateID::Create(const uint64_t dvmBlockNumber, - const std::string minerAddress, - const unsigned int difficulty, - const uint64_t timestamp) { +std::shared_ptr CScopedTemplate::Create(const uint64_t dvmBlockNumber, + const std::string minerAddress, + const unsigned int difficulty, + const uint64_t timestamp) { CrossBoundaryResult result; - uint64_t templateId = evm_try_unsafe_create_template(result, dvmBlockNumber, minerAddress, difficulty, timestamp); + BlockTemplateWrapper &evmTemplate = + evm_try_unsafe_create_template(result, dvmBlockNumber, minerAddress, difficulty, timestamp); if (result.ok) { - return std::shared_ptr(new CScopedTemplateID(templateId)); + return std::shared_ptr(new CScopedTemplate(evmTemplate)); } return nullptr; } -CScopedTemplateID::~CScopedTemplateID() { - CrossBoundaryResult result; - evm_try_unsafe_remove_template(result, evmTemplateId); - if (!result.ok) { - LogPrintf("Failed to destroy queue %d\n", evmTemplateId); - } +CScopedTemplate::~CScopedTemplate() { + XResultStatusLogged(evm_try_unsafe_remove_template(result, evmTemplate)); } -uint64_t CScopedTemplateID::GetTemplateID() const { - return evmTemplateId; +BlockTemplateWrapper &CScopedTemplate::GetTemplate() const { + return evmTemplate; } diff --git a/src/dfi/evm.h b/src/dfi/evm.h index ececcf0988..5751911170 100644 --- a/src/dfi/evm.h +++ b/src/dfi/evm.h @@ -1,6 +1,7 @@ #ifndef DEFI_DFI_EVM_H #define DEFI_DFI_EVM_H +#include #include #include #include @@ -56,19 +57,19 @@ class CVMDomainGraphView : public virtual CStorageView { }; }; -class CScopedTemplateID { - explicit CScopedTemplateID(uint64_t id); +class CScopedTemplate { + explicit CScopedTemplate(BlockTemplateWrapper &blockTemplate); - uint64_t evmTemplateId; + BlockTemplateWrapper &evmTemplate; public: - static std::shared_ptr Create(const uint64_t dvmBlockNumber, - std::string minerAddress, - unsigned int difficulty, - const uint64_t timestamp); - ~CScopedTemplateID(); + static std::shared_ptr Create(const uint64_t dvmBlockNumber, + std::string minerAddress, + unsigned int difficulty, + const uint64_t timestamp); + ~CScopedTemplate(); - uint64_t GetTemplateID() const; + BlockTemplateWrapper &GetTemplate() const; }; #endif // DEFI_DFI_EVM_H diff --git a/src/dfi/govvariables/attributes.cpp b/src/dfi/govvariables/attributes.cpp index 92cf649806..24278415a1 100644 --- a/src/dfi/govvariables/attributes.cpp +++ b/src/dfi/govvariables/attributes.cpp @@ -2423,10 +2423,10 @@ Res ATTRIBUTES::Apply(CCustomCSView &mnview, const uint32_t height) { govVarValue.reserve(govVarVec.size()); std::copy(govVarVec.begin(), govVarVec.end(), govVarValue.begin()); - if (evmTemplateId) { + if (evmTemplate) { CrossBoundaryResult result; const auto rustKey = GovVarKeyDataStructure{attrV0->type, attrV0->typeId, attrV0->key, attrV0->keyId}; - if (!evm_try_handle_attribute_apply(result, evmTemplateId->GetTemplateID(), rustKey, govVarValue)) { + if (!evm_try_unsafe_handle_attribute_apply(result, evmTemplate->GetTemplate(), rustKey, govVarValue)) { return DeFiErrors::SettingEVMAttributeFailure(); } if (!result.ok) { diff --git a/src/dfi/govvariables/attributes.h b/src/dfi/govvariables/attributes.h index c0fd7dd209..13e0f17bb4 100644 --- a/src/dfi/govvariables/attributes.h +++ b/src/dfi/govvariables/attributes.h @@ -548,7 +548,7 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator evmTemplateId{}; + std::shared_ptr evmTemplate{}; // For formatting in export static const std::map &displayVersions(); diff --git a/src/dfi/mn_checks.cpp b/src/dfi/mn_checks.cpp index 3ae1092b11..0380ca1172 100644 --- a/src/dfi/mn_checks.cpp +++ b/src/dfi/mn_checks.cpp @@ -326,7 +326,7 @@ class CCustomTxApplyVisitor { const Consensus::Params &consensus; uint64_t time; uint32_t txn; - const std::shared_ptr &evmTemplateId; + const std::shared_ptr &evmTemplate; bool isEvmEnabledForBlock; bool evmPreValidate; @@ -336,7 +336,7 @@ class CCustomTxApplyVisitor { if constexpr (std::is_invocable_v) { return T1{ - tx, height, coins, mnview, consensus, time, txn, evmTemplateId, isEvmEnabledForBlock, evmPreValidate}( + tx, height, coins, mnview, consensus, time, txn, evmTemplate, isEvmEnabledForBlock, evmPreValidate}( obj); } else if constexpr (sizeof...(Args) != 0) { return ConsensusHandler(obj); @@ -355,7 +355,7 @@ class CCustomTxApplyVisitor { const Consensus::Params &consensus, uint64_t time, uint32_t txn, - const std::shared_ptr &evmTemplateId, + const std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate) @@ -366,7 +366,7 @@ class CCustomTxApplyVisitor { consensus(consensus), time(time), txn(txn), - evmTemplateId(evmTemplateId), + evmTemplate(evmTemplate), isEvmEnabledForBlock(isEvmEnabledForBlock), evmPreValidate(evmPreValidate) {} @@ -443,17 +443,17 @@ Res CustomTxVisit(CCustomCSView &mnview, const CCustomTxMessage &txMessage, const uint64_t time, const uint32_t txn, - std::shared_ptr &evmTemplateId, + std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate) { if (IsDisabledTx(height, tx, consensus)) { return Res::ErrCode(CustomTxErrCodes::Fatal, "Disabled custom transaction"); } - if (!evmTemplateId && isEvmEnabledForBlock) { + if (!evmTemplate && isEvmEnabledForBlock) { std::string minerAddress{}; - evmTemplateId = CScopedTemplateID::Create(height, minerAddress, 0u, time); - if (!evmTemplateId) { + evmTemplate = CScopedTemplate::Create(height, minerAddress, 0u, time); + if (!evmTemplate) { return Res::Err("Failed to create queue"); } } @@ -461,7 +461,7 @@ Res CustomTxVisit(CCustomCSView &mnview, try { auto res = std::visit( CCustomTxApplyVisitor( - tx, height, coins, mnview, consensus, time, txn, evmTemplateId, isEvmEnabledForBlock, evmPreValidate), + tx, height, coins, mnview, consensus, time, txn, evmTemplate, isEvmEnabledForBlock, evmPreValidate), txMessage); return res; } catch (const std::bad_variant_access &e) { @@ -549,7 +549,7 @@ Res ApplyCustomTx(CCustomCSView &mnview, uint64_t time, uint256 *canSpend, uint32_t txn, - std::shared_ptr &evmTemplateId, + std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate) { auto res = Res::Ok(); @@ -598,7 +598,7 @@ Res ApplyCustomTx(CCustomCSView &mnview, txMessage, time, txn, - evmTemplateId, + evmTemplate, isEvmEnabledForBlock, evmPreValidate); diff --git a/src/dfi/mn_checks.h b/src/dfi/mn_checks.h index 1df4b3e26f..38eca7cbd6 100644 --- a/src/dfi/mn_checks.h +++ b/src/dfi/mn_checks.h @@ -170,7 +170,7 @@ Res ApplyCustomTx(CCustomCSView &mnview, uint64_t time, uint256 *canSpend, uint32_t txn, - std::shared_ptr &evmTemplateId, + std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate); @@ -182,7 +182,7 @@ Res CustomTxVisit(CCustomCSView &mnview, const CCustomTxMessage &txMessage, const uint64_t time, const uint32_t txn, - std::shared_ptr &evmTemplateId, + std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock, const bool evmPreValidate); diff --git a/src/dfi/mn_rpc.cpp b/src/dfi/mn_rpc.cpp index e7854c9703..4ff65e76da 100644 --- a/src/dfi/mn_rpc.cpp +++ b/src/dfi/mn_rpc.cpp @@ -485,7 +485,7 @@ void execTestTx(const CTransaction &tx, uint32_t height, CTransactionRef optAuth CCustomCSView view(*pcustomcsview); auto consensus = Params().GetConsensus(); const auto isEvmEnabledForBlock = IsEVMEnabled(view, consensus); - std::shared_ptr evmTemplateId{}; + std::shared_ptr evmTemplate{}; res = CustomTxVisit(view, coins, tx, @@ -494,7 +494,7 @@ void execTestTx(const CTransaction &tx, uint32_t height, CTransactionRef optAuth txMessage, ::ChainActive().Tip()->nTime, 0, - evmTemplateId, + evmTemplate, isEvmEnabledForBlock, true); } diff --git a/src/dfi/rpc_tokens.cpp b/src/dfi/rpc_tokens.cpp index 62e79bf2cd..c26325b2a1 100644 --- a/src/dfi/rpc_tokens.cpp +++ b/src/dfi/rpc_tokens.cpp @@ -670,7 +670,7 @@ UniValue getcustomtx(const JSONRPCRequest &request) { const auto &consensus = Params().GetConsensus(); const auto isEvmEnabledForBlock = IsEVMEnabled(mnview, consensus); - std::shared_ptr evmTemplateId{}; + std::shared_ptr evmTemplate{}; auto res = ApplyCustomTx(mnview, view, *tx, @@ -679,7 +679,7 @@ UniValue getcustomtx(const JSONRPCRequest &request) { 0, nullptr, 0, - evmTemplateId, + evmTemplate, isEvmEnabledForBlock, false); diff --git a/src/dfi/tokens.cpp b/src/dfi/tokens.cpp index 93d7781a51..27ead3de39 100644 --- a/src/dfi/tokens.cpp +++ b/src/dfi/tokens.cpp @@ -71,7 +71,7 @@ Res CTokensView::CreateDFIToken() { ResVal CTokensView::CreateToken(const CTokensView::CTokenImpl &token, bool isPreBayfront, bool shouldCreateDst20, - const std::shared_ptr &evmTemplateId) { + const std::shared_ptr &evmTemplate) { if (GetTokenByCreationTx(token.creationTx)) { return Res::Err("token with creation tx %s already exists!", token.creationTx.ToString()); } @@ -105,12 +105,12 @@ ResVal CTokensView::CreateToken(const CTokensView::CTokenImpl &token, if (shouldCreateDst20) { CrossBoundaryResult result; - evm_try_create_dst20(result, - evmTemplateId->GetTemplateID(), - token.creationTx.GetHex(), - rust::string(token.name.c_str()), - rust::string(token.symbol.c_str()), - id.v); + evm_try_unsafe_create_dst20(result, + evmTemplate->GetTemplate(), + token.creationTx.GetHex(), + rust::string(token.name.c_str()), + rust::string(token.symbol.c_str()), + id.v); if (!result.ok) { return Res::Err("Error creating DST20 token: %s", result.reason); } diff --git a/src/dfi/tokens.h b/src/dfi/tokens.h index 808732fc98..cda8444b02 100644 --- a/src/dfi/tokens.h +++ b/src/dfi/tokens.h @@ -197,7 +197,7 @@ class CTokensView : public virtual CStorageView { ResVal CreateToken(const CTokenImpl &token, bool isPreBayfront = false, bool shouldCreateDst20 = false, - const std::shared_ptr &evmTemplateId = {}); + const std::shared_ptr &evmTemplate = {}); Res UpdateToken(const CTokenImpl &newToken, bool isPreBayfront = false, const bool tokenSplitUpdate = false); Res BayfrontFlagsCleanup(); diff --git a/src/dfi/validation.cpp b/src/dfi/validation.cpp index 8870c5e052..f023eefb0d 100644 --- a/src/dfi/validation.cpp +++ b/src/dfi/validation.cpp @@ -1073,7 +1073,7 @@ static void ProcessFutures(const CBlockIndex *pindex, CCustomCSView &cache, cons static void ProcessGovEvents(const CBlockIndex *pindex, CCustomCSView &cache, const CChainParams &chainparams, - const std::shared_ptr &evmTemplateId) { + const std::shared_ptr &evmTemplate) { if (pindex->nHeight < chainparams.GetConsensus().DF11FortCanningHeight) { return; } @@ -1087,7 +1087,7 @@ static void ProcessGovEvents(const CBlockIndex *pindex, if (var->GetName() == "ATTRIBUTES") { auto govVar = cache.GetAttributes(); govVar->time = pindex->GetBlockTime(); - govVar->evmTemplateId = evmTemplateId; + govVar->evmTemplate = evmTemplate; auto newVar = std::dynamic_pointer_cast(var); assert(newVar); @@ -2657,7 +2657,7 @@ static Res ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &cache, const CChainParams &chainparams, - const std::shared_ptr &evmTemplateId) { + const std::shared_ptr &evmTemplate) { CKeyID minter; assert(block.ExtractMinterKey(minter)); CScript minerAddress; @@ -2695,7 +2695,7 @@ static Res ProcessEVMQueue(const CBlock &block, } CrossBoundaryResult result; - const auto blockResult = evm_try_unsafe_construct_block_in_template(result, evmTemplateId->GetTemplateID()); + const auto blockResult = evm_try_unsafe_construct_block_in_template(result, evmTemplate->GetTemplate()); if (!result.ok) { return Res::Err(result.reason.c_str()); } @@ -2790,13 +2790,13 @@ Res ProcessDeFiEventFallible(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &mnview, const CChainParams &chainparams, - const std::shared_ptr &evmTemplateId, + const std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock) { CCustomCSView cache(mnview); if (isEvmEnabledForBlock) { // Process EVM block - auto res = ProcessEVMQueue(block, pindex, cache, chainparams, evmTemplateId); + auto res = ProcessEVMQueue(block, pindex, cache, chainparams, evmTemplate); if (!res) { return res; } @@ -2814,7 +2814,7 @@ void ProcessDeFiEvent(const CBlock &block, const CCoinsViewCache &view, const CChainParams &chainparams, const CreationTxs &creationTxs, - const std::shared_ptr &evmTemplateId) { + const std::shared_ptr &evmTemplate) { CCustomCSView cache(mnview); // calculate rewards to current block @@ -2841,7 +2841,7 @@ void ProcessDeFiEvent(const CBlock &block, ProcessFutures(pindex, cache, chainparams); // update governance variables - ProcessGovEvents(pindex, cache, chainparams, evmTemplateId); + ProcessGovEvents(pindex, cache, chainparams, evmTemplate); // Migrate loan and collateral tokens to Gov vars. ProcessTokenToGovVar(pindex, cache, chainparams); diff --git a/src/dfi/validation.h b/src/dfi/validation.h index 6c3d77ee8a..a599b3b9c0 100644 --- a/src/dfi/validation.h +++ b/src/dfi/validation.h @@ -23,13 +23,13 @@ void ProcessDeFiEvent(const CBlock &block, const CCoinsViewCache &view, const CChainParams &chainparams, const CreationTxs &creationTxs, - const std::shared_ptr &evmTemplateId); + const std::shared_ptr &evmTemplate); Res ProcessDeFiEventFallible(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &mnview, const CChainParams &chainparams, - const std::shared_ptr &evmTemplateId, + const std::shared_ptr &evmTemplate, const bool isEvmEnabledForBlock); std::vector CollectAuctionBatches(const CVaultAssets &vaultAssets, diff --git a/src/miner.cpp b/src/miner.cpp index 8b3502aa79..ba6f3f83ca 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -43,7 +43,7 @@ struct EvmTxPreApplyContext { const CTxMemPool::txiter& txIter; - const std::shared_ptr& evmTemplateId; + const std::shared_ptr& evmTemplate; std::multimap& failedNonces; std::map& failedNoncesLookup; CTxMemPool::setEntries& failedTxEntries; @@ -251,26 +251,26 @@ ResVal> BlockAssembler::CreateNewBlock(const CSc const auto attributes = mnview.GetAttributes(); const auto isEvmEnabledForBlock = IsEVMEnabled(attributes); - std::shared_ptr evmTemplateId{}; + std::shared_ptr evmTemplate{}; if (isEvmEnabledForBlock) { - evmTemplateId = CScopedTemplateID::Create(nHeight, evmBeneficiary, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), blockTime); - if (!evmTemplateId) { + evmTemplate = CScopedTemplate::Create(nHeight, evmBeneficiary, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), blockTime); + if (!evmTemplate) { return Res::Err("Failed to create block template"); } - XResultThrowOnErr(evm_try_unsafe_update_state_in_template(result, evmTemplateId->GetTemplateID(), static_cast(reinterpret_cast(&mnview)))); + XResultThrowOnErr(evm_try_unsafe_update_state_in_template(result, evmTemplate->GetTemplate(), static_cast(reinterpret_cast(&mnview)))); } std::map txFees; if (timeOrdering) { - addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmTemplateId, txFees, isEvmEnabledForBlock); + addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmTemplate, txFees, isEvmEnabledForBlock); } else { - addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmTemplateId, txFees, isEvmEnabledForBlock); + addPackageTxs(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmTemplate, txFees, isEvmEnabledForBlock); } XVM xvm{}; if (isEvmEnabledForBlock) { - auto res = XResultValueLogged(evm_try_unsafe_construct_block_in_template(result, evmTemplateId->GetTemplateID())); + auto res = XResultValueLogged(evm_try_unsafe_construct_block_in_template(result, evmTemplate->GetTemplate())); if (!res) return Res::Err("Failed to construct block"); auto blockResult = *res; xvm = XVM{0, {0, std::string(blockResult.block_hash.data(), blockResult.block_hash.length()).substr(2), blockResult.total_burnt_fees, blockResult.total_priority_fees, evmBeneficiary}}; @@ -596,14 +596,14 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, std::ve bool BlockAssembler::EvmTxPreapply(EvmTxPreApplyContext& ctx) { const auto& txIter = ctx.txIter; - const auto& evmTemplateId = ctx.evmTemplateId; + const auto& evmTemplate = ctx.evmTemplate; const auto& failedTxSet = ctx.failedTxEntries; auto& failedNonces = ctx.failedNonces; auto& failedNoncesLookup = ctx.failedNoncesLookup; auto& [txNonce, txSender] = txIter->GetEVMAddrAndNonce(); CrossBoundaryResult result; - const auto expectedNonce = evm_try_unsafe_get_next_valid_nonce_in_template(result, evmTemplateId->GetTemplateID(), txSender); + const auto expectedNonce = evm_try_unsafe_get_next_valid_nonce_in_template(result, evmTemplate->GetTemplate(), txSender); if (!result.ok) { return false; } @@ -633,7 +633,7 @@ bool BlockAssembler::EvmTxPreapply(EvmTxPreApplyContext& ctx) // 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, std::shared_ptr &evmTemplateId, std::map& txFees, const bool isEvmEnabledForBlock) +void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated, int nHeight, CCustomCSView& view, std::shared_ptr &evmTemplate, std::map& txFees, const bool isEvmEnabledForBlock) { // mapModifiedTxSet will store sorted packages after they are modified // because some of their txs are already in the block @@ -805,7 +805,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda } auto evmTxCtx = EvmTxPreApplyContext{ entry, - evmTemplateId, + evmTemplate, failedNonces, failedNoncesLookup, failedTxSet, @@ -821,7 +821,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda } } - const auto res = ApplyCustomTx(cache, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmTemplateId, isEvmEnabledForBlock, false); + const auto res = ApplyCustomTx(cache, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmTemplate, isEvmEnabledForBlock, false); // Not okay invalidate, undo and skip if (!res.ok) { failedTxSet.insert(entry); @@ -862,7 +862,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda // then remove from queue, otherwise it has not been added. if (entryHash != failedCustomTx) { CrossBoundaryResult result; - evm_try_unsafe_remove_txs_above_hash_in_template(result, evmTemplateId->GetTemplateID(), entryHash.ToString()); + evm_try_unsafe_remove_txs_above_hash_in_template(result, evmTemplate->GetTemplate(), entryHash.ToString()); if (!result.ok) { LogPrintf("%s: Unable to remove %s from queue. Will result in a block hash mismatch.\n", __func__, entryHash.ToString()); } diff --git a/src/miner.h b/src/miner.h index a73cf912c5..d7934bc101 100644 --- a/src/miner.h +++ b/src/miner.h @@ -22,7 +22,7 @@ class CBlockIndex; class CChainParams; -class CScopedTemplateID; +class CScopedTemplate; class CScript; class CAnchor; struct EvmTxPreApplyContext; @@ -201,7 +201,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, std::shared_ptr &evmTemplateId, std::map &txFees, const bool isEvmEnabledForBlock) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); + void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, std::shared_ptr &evmTemplate, std::map &txFees, const bool isEvmEnabledForBlock) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); // helper functions for addPackageTxs() /** Remove confirmed (inBlock) entries from given set */ diff --git a/src/test/applytx_tests.cpp b/src/test/applytx_tests.cpp index b537948bda..4e446fcd11 100644 --- a/src/test/applytx_tests.cpp +++ b/src/test/applytx_tests.cpp @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(apply_a2a_neg) rawTx.vout = { CTxOut(0, CScript()) }; rawTx.vin = { CTxIn(auth_out) }; - std::shared_ptr evmTemplateId{}; + std::shared_ptr evmTemplate{}; // try to send "A:-1@DFI" { @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(apply_a2a_neg) rawTx.vout[0].scriptPubKey = CreateMetaA2A(msg); - res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplateId, false, false); + res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplate, false, false); BOOST_CHECK(!res.ok); BOOST_CHECK_NE(res.msg.find("negative amount"), std::string::npos); // check that nothing changes: @@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(apply_a2a_neg) rawTx.vout[0].scriptPubKey = CreateMetaA2A(msg); - res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplateId, false, false); + res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplate, false, false); BOOST_CHECK(!res.ok); BOOST_CHECK_EQUAL(res.code, (uint32_t) CustomTxErrCodes::NotEnoughBalance); // check that nothing changes: @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(apply_a2a_neg) rawTx.vout[0].scriptPubKey = CreateMetaA2A(msg); - res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplateId, false, false); + res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplate, false, false); BOOST_CHECK(!res.ok); BOOST_CHECK_NE(res.msg.find("negative amount"), std::string::npos); // check that nothing changes: @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(apply_a2a_neg) rawTx.vout[0].scriptPubKey = CreateMetaA2A(msg); - res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplateId, false, false); + res = ApplyCustomTx(mnview, coinview, CTransaction(rawTx), amkCheated, 1, 0, nullptr, 0, evmTemplate, false, false); BOOST_CHECK(res.ok); // check result balances: auto const dfi90 = CTokenAmount{DFI, 90}; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d61ca3f93c..ef46b34130 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1247,8 +1247,8 @@ void CTxMemPool::rebuildAccountsView(int height, const CCoinsViewCache& coinsCac vtx.push_back(it->GetSharedTx()); continue; } - std::shared_ptr evmTemplateId{}; - auto res = ApplyCustomTx(viewDuplicate, coinsCache, tx, consensus, height, 0, nullptr, 0, evmTemplateId, isEvmEnabledForBlock, true); + std::shared_ptr evmTemplate{}; + auto res = ApplyCustomTx(viewDuplicate, coinsCache, tx, consensus, height, 0, nullptr, 0, evmTemplate, isEvmEnabledForBlock, true); if (!res && (res.code & CustomTxErrCodes::Fatal)) { LogPrintf("%s: Remove conflicting custom TX: %s\n", __func__, tx.GetHash().GetHex()); staged.insert(mapTx.project<0>(it)); diff --git a/src/validation.cpp b/src/validation.cpp index 9a0446dc30..a89d260833 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -652,8 +652,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool const auto& consensus = chainparams.GetConsensus(); const auto isEvmEnabledForBlock = IsEVMEnabled(mnview, consensus); - std::shared_ptr evmTemplateId{}; - auto res = ApplyCustomTx(mnview, view, tx, consensus, height, nAcceptTime, nullptr, 0, evmTemplateId, isEvmEnabledForBlock, true); + std::shared_ptr evmTemplate{}; + auto res = ApplyCustomTx(mnview, view, tx, consensus, height, nAcceptTime, nullptr, 0, evmTemplate, isEvmEnabledForBlock, true); if (!res.ok || (res.code & CustomTxErrCodes::Fatal)) { return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INVALID, res.msg); } @@ -2448,8 +2448,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl // Do not track burns in genesis mnview.GetHistoryWriters().GetBurnView() = nullptr; for (size_t i = 0; i < block.vtx.size(); ++i) { - std::shared_ptr evmTemplateId{}; - const auto res = ApplyCustomTx(mnview, view, *block.vtx[i], chainparams.GetConsensus(), pindex->nHeight, pindex->GetBlockTime(), nullptr, i, evmTemplateId, false, false); + std::shared_ptr evmTemplate{}; + const auto res = ApplyCustomTx(mnview, view, *block.vtx[i], chainparams.GetConsensus(), pindex->nHeight, pindex->GetBlockTime(), nullptr, i, evmTemplate, false, false); if (!res.ok) { return error("%s: Genesis block ApplyCustomTx failed. TX: %s Error: %s", __func__, block.vtx[i]->GetHash().ToString(), res.msg); @@ -2660,18 +2660,18 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl const auto& consensus = chainparams.GetConsensus(); const auto isEvmEnabledForBlock = IsEVMEnabled(attributes); - std::shared_ptr evmTemplateId{}; + std::shared_ptr evmTemplate{}; if (isEvmEnabledForBlock) { auto xvmRes = XVM::TryFrom(block.vtx[0]->vout[1].scriptPubKey); if (!xvmRes) { return Res::Err("Failed to process XVM in coinbase"); } - evmTemplateId = CScopedTemplateID::Create(pindex->nHeight, xvmRes->evm.beneficiary, block.nBits, pindex->GetBlockTime()); - if (!evmTemplateId) { + evmTemplate = CScopedTemplate::Create(pindex->nHeight, xvmRes->evm.beneficiary, block.nBits, pindex->GetBlockTime()); + if (!evmTemplate) { return Res::Err("Failed to create block template"); } - XResultThrowOnErr(evm_try_unsafe_update_state_in_template(result, evmTemplateId->GetTemplateID(), static_cast(reinterpret_cast(&mnview)))); + XResultThrowOnErr(evm_try_unsafe_update_state_in_template(result, evmTemplate->GetTemplate(), static_cast(reinterpret_cast(&mnview)))); } // Execute TXs @@ -2744,7 +2744,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl } const auto applyCustomTxTime = GetTimeMicros(); - const auto res = ApplyCustomTx(accountsView, view, tx, consensus, pindex->nHeight, pindex->GetBlockTime(), nullptr, i, evmTemplateId, isEvmEnabledForBlock, false); + const auto res = ApplyCustomTx(accountsView, view, tx, consensus, pindex->nHeight, pindex->GetBlockTime(), nullptr, i, evmTemplate, isEvmEnabledForBlock, false); LogApplyCustomTx(tx, applyCustomTxTime); if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) { @@ -2912,7 +2912,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl accountsView.Flush(); // Execute EVM Queue - res = ProcessDeFiEventFallible(block, pindex, mnview, chainparams, evmTemplateId, isEvmEnabledForBlock); + res = ProcessDeFiEventFallible(block, pindex, mnview, chainparams, evmTemplate, isEvmEnabledForBlock); if (!res.ok) { return state.Invalid(ValidationInvalidReason::CONSENSUS, error("%s: %s", __func__, res.msg), REJECT_INVALID, res.dbgMsg); } @@ -2929,7 +2929,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, evmTemplateId); + ProcessDeFiEvent(block, pindex, mnview, view, chainparams, creationTxs, evmTemplate); // Write any UTXO burns for (const auto& [key, value] : writeBurnEntries) @@ -2992,7 +2992,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl // Finalize items if (isEvmEnabledForBlock) { - XResultThrowOnErr(evm_try_unsafe_commit_block(result, evmTemplateId->GetTemplateID())); + XResultThrowOnErr(evm_try_unsafe_commit_block(result, evmTemplate->GetTemplate())); } int64_t nTime5 = GetTimeMicros(); nTimeIndex += nTime5 - nTime4;