diff --git a/lib/ain-cpp-imports/src/bridge.rs b/lib/ain-cpp-imports/src/bridge.rs index cd61443302..f98ae51e5b 100644 --- a/lib/ain-cpp-imports/src/bridge.rs +++ b/lib/ain-cpp-imports/src/bridge.rs @@ -42,7 +42,7 @@ pub mod ffi { fn getPoolTransactions() -> Vec; fn getNativeTxSize(data: Vec) -> u64; fn getMinRelayTxFee() -> u64; - fn getEthPrivKey(key: String) -> [u8; 32]; + fn getEthPrivKey(key: [u8; 20]) -> [u8; 32]; fn getStateInputJSON() -> String; fn getEthSyncStatus() -> [i64; 2]; fn getAttributeValues(mnview_ptr: usize) -> Attributes; diff --git a/lib/ain-cpp-imports/src/lib.rs b/lib/ain-cpp-imports/src/lib.rs index 9c73d70499..5099ad9561 100644 --- a/lib/ain-cpp-imports/src/lib.rs +++ b/lib/ain-cpp-imports/src/lib.rs @@ -69,7 +69,7 @@ mod ffi { pub fn getMinRelayTxFee() -> u64 { unimplemented!("{}", UNIMPL_MSG) } - pub fn getEthPrivKey(_key: String) -> [u8; 32] { + pub fn getEthPrivKey(_key: [u8; 20]) -> [u8; 32] { unimplemented!("{}", UNIMPL_MSG) } pub fn getStateInputJSON() -> String { @@ -208,7 +208,7 @@ pub fn get_min_relay_tx_fee() -> Result> { } /// Gets the private key for the given pubkey string. -pub fn get_eth_priv_key(key: String) -> Result<[u8; 32], Box> { +pub fn get_eth_priv_key(key: [u8; 20]) -> Result<[u8; 32], Box> { let eth_key = ffi::getEthPrivKey(key); Ok(eth_key) } diff --git a/lib/ain-evm/src/core.rs b/lib/ain-evm/src/core.rs index ce7d8323c5..cb97d3dc1d 100644 --- a/lib/ain-evm/src/core.rs +++ b/lib/ain-evm/src/core.rs @@ -41,7 +41,8 @@ use crate::{ EVMError, Result, }; -pub type XHash = String; +pub type XHash = [u8; 32]; +pub type XAddress = [u8; 20]; #[derive(Clone, Debug)] pub struct ExecutionStep { @@ -71,8 +72,8 @@ pub struct EthCallArgs<'a> { } pub struct TransferDomainTxInfo { - pub from: String, - pub to: String, + pub from: XAddress, + pub to: XAddress, pub native_address: String, pub direction: bool, pub value: u64, @@ -396,10 +397,7 @@ impl EVMCoreService { } // Validate tx sender with transferdomain sender - let sender = context - .from - .parse::() - .map_err(|_| "Invalid address")?; + let sender = H160::from(context.from); if signed_tx.sender != sender { return Err(format_err!( "[validate_raw_transferdomain_tx] invalid sender, signed_tx.sender : {:#?}, transferdomain sender : {:#?}", @@ -449,17 +447,11 @@ impl EVMCoreService { let (from_address, to_address) = if context.direction { // EvmIn - let to_address = context - .to - .parse::() - .map_err(|_| "failed to parse to address")?; + let to_address = H160::from(context.to); (fixed_address, to_address) } else { // EvmOut - let from_address = context - .from - .parse::() - .map_err(|_| "failed to parse from address")?; + let from_address = H160::from(context.from); (from_address, fixed_address) }; let value = try_from_satoshi(U256::from(context.value))?.0; diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index 981bfa5814..e64c579fd4 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -227,7 +227,7 @@ impl EVMServices { .collect(), Vec::new(), ); - let block_hash = format!("{:?}", block.header.hash()); + let block_hash = block.header.hash().to_fixed_bytes(); let receipts = self.receipt.generate_receipts( &all_transactions, receipts_v3.clone(), diff --git a/lib/ain-grpc/src/lib.rs b/lib/ain-grpc/src/lib.rs index f414a01d9a..ec225b15c3 100644 --- a/lib/ain-grpc/src/lib.rs +++ b/lib/ain-grpc/src/lib.rs @@ -72,9 +72,9 @@ pub fn init_services() { let _ = &*SERVICES; } -pub fn init_network_json_rpc_service(addr: &str) -> Result<()> { +pub fn init_network_json_rpc_service(addr: String) -> Result<()> { info!("Starting JSON RPC server at {}", addr); - let addr = addr.parse::()?; + let addr = addr.as_str().parse::()?; let max_connections = ain_cpp_imports::get_max_connections(); let max_response_size = ain_cpp_imports::get_max_response_byte_size(); let runtime = &SERVICES; @@ -112,7 +112,7 @@ pub fn init_network_json_rpc_service(addr: &str) -> Result<()> { Ok(()) } -pub fn init_network_grpc_service(_addr: &str) -> Result<()> { +pub fn init_network_grpc_service(_addr: String) -> Result<()> { // log::info!("Starting gRPC server at {}", addr); // Commented out for now as nothing to serve // let runtime = &SERVICES; @@ -122,9 +122,9 @@ pub fn init_network_grpc_service(_addr: &str) -> Result<()> { Ok(()) } -pub fn init_network_subscriptions_service(addr: &str) -> Result<()> { +pub fn init_network_subscriptions_service(addr: String) -> Result<()> { info!("Starting WebSockets server at {}", addr); - let addr = addr.parse::()?; + let addr = addr.as_str().parse::()?; let max_connections = ain_cpp_imports::get_max_connections(); let max_response_size = ain_cpp_imports::get_max_response_byte_size(); let runtime = &SERVICES; diff --git a/lib/ain-grpc/src/rpc/eth.rs b/lib/ain-grpc/src/rpc/eth.rs index 79fa3a73f6..62e7d836e3 100644 --- a/lib/ain-grpc/src/rpc/eth.rs +++ b/lib/ain-grpc/src/rpc/eth.rs @@ -1137,8 +1137,8 @@ impl MetachainRPCServer for MetachainRPCModule { fn sign(address: H160, message: TransactionMessage) -> RpcResult { debug!(target: "rpc", "sign address {:#x}", address); - let key = format!("{address:?}"); - let priv_key = get_eth_priv_key(key).map_err(|_| to_custom_err("Invalid private key"))?; + let priv_key = get_eth_priv_key(address.to_fixed_bytes()) + .map_err(|_| to_custom_err("Invalid private key"))?; let secret_key = SecretKey::parse(&priv_key) .map_err(|e| to_custom_err(format!("Error parsing SecretKey {e}")))?; diff --git a/lib/ain-rs-exports/src/core.rs b/lib/ain-rs-exports/src/core.rs index 35e0aa176b..9b8ebf8ac9 100644 --- a/lib/ain-rs-exports/src/core.rs +++ b/lib/ain-rs-exports/src/core.rs @@ -20,21 +20,21 @@ pub fn ain_rs_stop_core_services(result: &mut CrossBoundaryResult) { cross_boundary_success(result); } -pub fn ain_rs_init_network_json_rpc_service(result: &mut CrossBoundaryResult, addr: &str) { +pub fn ain_rs_init_network_json_rpc_service(result: &mut CrossBoundaryResult, addr: String) { match ain_grpc::init_network_json_rpc_service(addr) { Ok(()) => cross_boundary_success(result), Err(e) => cross_boundary_error_return(result, e.to_string()), } } -pub fn ain_rs_init_network_grpc_service(result: &mut CrossBoundaryResult, addr: &str) { +pub fn ain_rs_init_network_grpc_service(result: &mut CrossBoundaryResult, addr: String) { match ain_grpc::init_network_grpc_service(addr) { Ok(()) => cross_boundary_success(result), Err(e) => cross_boundary_error_return(result, e.to_string()), } } -pub fn ain_rs_init_network_subscriptions_service(result: &mut CrossBoundaryResult, addr: &str) { +pub fn ain_rs_init_network_subscriptions_service(result: &mut CrossBoundaryResult, addr: String) { match ain_grpc::init_network_subscriptions_service(addr) { Ok(()) => cross_boundary_success(result), Err(e) => cross_boundary_error_return(result, e.to_string()), diff --git a/lib/ain-rs-exports/src/evm.rs b/lib/ain-rs-exports/src/evm.rs index 0f2c470e1b..46ac52b478 100644 --- a/lib/ain-rs-exports/src/evm.rs +++ b/lib/ain-rs-exports/src/evm.rs @@ -3,7 +3,7 @@ use ain_contracts::{ get_transferdomain_native_transfer_function, FixedContract, }; use ain_evm::{ - core::{TransferDomainTxInfo, XHash}, + core::{TransferDomainTxInfo, XAddress, XHash}, evm::FinalizedBlockInfo, executor::ExecuteTx, fee::{calculate_max_tip_gas_fee, calculate_min_rbf_tip_gas_fee}, @@ -49,8 +49,7 @@ fn evm_try_create_and_sign_tx(ctx: ffi::CreateTransactionContext) -> Result().map_err(|_| "Invalid address")?; - TransactionAction::Call(to_address) + TransactionAction::Call(H160::from(ctx.to)) }; let nonce = U256::from(ctx.nonce); let gas_price = try_from_gwei(U256::from(ctx.gas_price))?; @@ -98,14 +97,13 @@ fn evm_try_create_and_sign_transfer_domain_tx( let FixedContract { fixed_address, .. } = get_transfer_domain_contract(); let action = TransactionAction::Call(fixed_address); - let sender = ctx.from.parse::().map_err(|_| "Invalid address")?; - + let sender = H160::from(ctx.from); let (from_address, to_address) = if ctx.direction { - let to_address = ctx.to.parse::().map_err(|_| "Invalid address")?; + let to_address = H160::from(ctx.to); // Send EvmIn from contract address (fixed_address, to_address) } else { - let from_address = ctx.from.parse::().map_err(|_| "Invalid address")?; + let from_address = H160::from(ctx.from); // Send EvmOut to contract address (from_address, fixed_address) }; @@ -167,10 +165,8 @@ fn evm_try_create_and_sign_transfer_domain_tx( } #[ffi_fallible] -fn evm_try_store_account_nonce(from_address: &str, nonce: u64) -> Result<()> { - let from_address = from_address - .parse::() - .map_err(|_| "Invalid address")?; +fn evm_try_store_account_nonce(from_address: XAddress, nonce: u64) -> Result<()> { + let from_address = H160::from(from_address); let _ = SERVICES .evm .core @@ -192,10 +188,9 @@ fn evm_try_store_account_nonce(from_address: &str, nonce: u64) -> Result<()> { /// /// Returns the balance of the account as a `u64` on success. #[ffi_fallible] -fn evm_try_get_balance(address: &str) -> Result { - let address = address.parse::().map_err(|_| "Invalid address")?; +fn evm_try_get_balance(address: XAddress) -> Result { + let address = H160::from(address); let state_root = SERVICES.evm.block.get_latest_state_root()?; - let balance = SERVICES.evm.core.get_balance(address, state_root)?; let amount = WeiAmount(balance).to_satoshi()?.try_into()?; @@ -234,10 +229,9 @@ fn evm_try_unsafe_update_state_in_template(template: &mut BlockTemplateWrapper) #[ffi_fallible] fn evm_try_unsafe_get_next_valid_nonce_in_template( template: &BlockTemplateWrapper, - address: &str, + address: XAddress, ) -> Result { - let address = address.parse::().map_err(|_| "Invalid address")?; - + let address = H160::from(address); unsafe { let next_nonce = SERVICES .evm @@ -258,13 +252,14 @@ fn evm_try_unsafe_get_next_valid_nonce_in_template( #[ffi_fallible] fn evm_try_unsafe_remove_txs_above_hash_in_template( template: &mut BlockTemplateWrapper, - target_hash: String, -) -> Result> { + target_hash: XHash, +) -> Result<()> { unsafe { SERVICES .evm .core - .remove_txs_above_hash_in_block_template(template.get_inner_mut()?, target_hash) + .remove_txs_above_hash_in_block_template(template.get_inner_mut()?, target_hash)?; + Ok(()) } } @@ -279,15 +274,14 @@ fn evm_try_unsafe_remove_txs_above_hash_in_template( fn evm_try_unsafe_add_balance_in_template( template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: XHash, ) -> Result<()> { let signed_tx = SERVICES.evm.core.tx_cache.try_get_or_create(raw_tx)?; - let native_hash = XHash::from(native_hash); - let exec_tx = ExecuteTx::SystemTx(SystemTx::TransferDomain(TransferDomainData { signed_tx: Box::new(signed_tx), direction: TransferDirection::EvmIn, })); + unsafe { SERVICES .evm @@ -306,11 +300,9 @@ fn evm_try_unsafe_add_balance_in_template( fn evm_try_unsafe_sub_balance_in_template( template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: XHash, ) -> Result { let signed_tx = SERVICES.evm.core.tx_cache.try_get_or_create(raw_tx)?; - let native_hash = XHash::from(native_hash); - let exec_tx = ExecuteTx::SystemTx(SystemTx::TransferDomain(TransferDomainData { signed_tx: Box::new(signed_tx), direction: TransferDirection::EvmOut, @@ -498,10 +490,8 @@ fn evm_try_unsafe_remove_template(template: &mut BlockTemplateWrapper) -> Result fn evm_try_unsafe_push_tx_in_template( template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: XHash, ) -> Result { - let native_hash = native_hash.to_string(); - unsafe { let signed_tx = SERVICES.evm.core.tx_cache.try_get_or_create(raw_tx)?; @@ -513,7 +503,7 @@ fn evm_try_unsafe_push_tx_in_template( )?; Ok(ffi::ValidateTxCompletion { - tx_hash: format!("{:?}", tx_hash), + tx_hash: tx_hash.to_fixed_bytes(), }) } } @@ -592,7 +582,7 @@ fn evm_try_get_block_hash_by_number(height: u64) -> Result { .storage .get_block_by_number(&U256::from(height))? .ok_or("Invalid block number")?; - Ok(format!("{:?}", block.header.hash())) + Ok(block.header.hash().to_fixed_bytes()) } /// Return the block number for a given blockhash. @@ -605,9 +595,8 @@ fn evm_try_get_block_hash_by_number(height: u64) -> Result { /// /// Returns the block number associated with the given blockhash. #[ffi_fallible] -fn evm_try_get_block_number_by_hash(hash: &str) -> Result { - let hash = hash.parse::().map_err(|_| "Invalid hash")?; - +fn evm_try_get_block_number_by_hash(hash: XHash) -> Result { + let hash = H256::from(hash); let block = SERVICES .evm .storage @@ -618,9 +607,8 @@ fn evm_try_get_block_number_by_hash(hash: &str) -> Result { } #[ffi_fallible] -fn evm_try_get_block_header_by_hash(hash: &str) -> Result { - let hash = hash.parse::().map_err(|_| "Invalid hash")?; - +fn evm_try_get_block_header_by_hash(hash: XHash) -> Result { + let hash = H256::from(hash); let block = SERVICES .evm .storage @@ -633,16 +621,16 @@ fn evm_try_get_block_header_by_hash(hash: &str) -> Result { let base_fee = u64::try_from(WeiAmount(block.header.base_fee).to_satoshi()?)?; let out = ffi::EVMBlockHeader { - parent_hash: format!("{:?}", block.header.parent_hash), - beneficiary: format!("{:?}", block.header.beneficiary), - state_root: format!("{:?}", block.header.state_root), - receipts_root: format!("{:?}", block.header.receipts_root), + parent_hash: block.header.parent_hash.to_fixed_bytes(), + beneficiary: block.header.beneficiary.to_fixed_bytes(), + state_root: block.header.state_root.to_fixed_bytes(), + receipts_root: block.header.receipts_root.to_fixed_bytes(), number, gas_limit, gas_used, timestamp: block.header.timestamp, extra_data: block.header.extra_data.clone(), - mix_hash: format!("{:?}", block.header.mix_hash), + mix_hash: block.header.mix_hash.to_fixed_bytes(), nonce: block.header.nonce.to_low_u64_be(), base_fee, }; @@ -650,9 +638,8 @@ fn evm_try_get_block_header_by_hash(hash: &str) -> Result { } #[ffi_fallible] -fn evm_try_get_tx_by_hash(tx_hash: &str) -> Result { - let tx_hash = tx_hash.parse::().map_err(|_| "Invalid hash")?; - +fn evm_try_get_tx_by_hash(tx_hash: XHash) -> Result { + let tx_hash = H256::from(tx_hash); let tx = SERVICES .evm .storage @@ -685,8 +672,8 @@ fn evm_try_get_tx_by_hash(tx_hash: &str) -> Result { let out = ffi::EVMTransaction { tx_type, - hash: format!("{:?}", tx.hash()), - sender: format!("{:?}", tx.sender), + hash: tx.hash().to_fixed_bytes(), + sender: tx.sender.to_fixed_bytes(), nonce, gas_price, gas_limit, @@ -697,8 +684,8 @@ fn evm_try_get_tx_by_hash(tx_hash: &str) -> Result { TransactionAction::Create => true, }, to: match tx.to() { - Some(to) => format!("{to:?}"), - None => XHash::new(), + Some(to) => to.to_fixed_bytes(), + None => H160::zero().to_fixed_bytes(), }, value, data: tx.data().to_vec(), @@ -709,10 +696,9 @@ fn evm_try_get_tx_by_hash(tx_hash: &str) -> Result { #[ffi_fallible] fn evm_try_unsafe_create_dst20( template: &mut BlockTemplateWrapper, - native_hash: &str, + native_hash: XHash, token: ffi::DST20TokenInfo, ) -> Result<()> { - let native_hash = XHash::from(native_hash); let address = ain_contracts::dst20_address_from_token_id(token.id)?; debug!("Deploying to address {:#?}", address); @@ -734,11 +720,10 @@ fn evm_try_unsafe_create_dst20( fn evm_try_unsafe_bridge_dst20( template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: XHash, token_id: u64, out: bool, ) -> Result<()> { - let native_hash = XHash::from(native_hash); let contract_address = ain_contracts::dst20_address_from_token_id(token_id)?; let signed_tx = SERVICES.evm.core.tx_cache.try_get_or_create(raw_tx)?; let system_tx = ExecuteTx::SystemTx(SystemTx::DST20Bridge(DST20Data { @@ -763,9 +748,9 @@ fn evm_try_unsafe_bridge_dst20( /// /// Returns the transaction's hash #[ffi_fallible] -fn evm_try_get_tx_hash(raw_tx: &str) -> Result { +fn evm_try_get_tx_hash(raw_tx: &str) -> Result { let signed_tx = SERVICES.evm.core.tx_cache.try_get_or_create(raw_tx)?; - Ok(format!("{:?}", signed_tx.hash())) + Ok(signed_tx.hash().to_fixed_bytes()) } #[ffi_fallible] @@ -796,11 +781,10 @@ fn evm_try_unsafe_cache_signed_tx(raw_tx: &str, instance: usize) -> Result<()> { /// Returns `true` if the address is a contract, `false` otherwise #[ffi_fallible] fn evm_try_unsafe_is_smart_contract_in_template( - address: &str, + address: XAddress, template: &BlockTemplateWrapper, ) -> Result { - let address = address.parse::().map_err(|_| "Invalid address")?; - + let address = H160::from(address); unsafe { SERVICES .evm @@ -829,7 +813,7 @@ fn evm_try_get_tx_miner_info_from_raw_tx(raw_tx: &str, mnview_ptr: usize) -> Res Ok(TxMinerInfo { nonce, - address: format!("{:?}", signed_tx.sender), + address: signed_tx.sender.to_fixed_bytes(), tip_fee, min_rbf_tip_fee, }) diff --git a/lib/ain-rs-exports/src/lib.rs b/lib/ain-rs-exports/src/lib.rs index 2dc6f8138b..09a9fd2f23 100644 --- a/lib/ain-rs-exports/src/lib.rs +++ b/lib/ain-rs-exports/src/lib.rs @@ -44,25 +44,28 @@ pub mod ffi { fn ain_rs_stop_core_services(result: &mut CrossBoundaryResult); // Networking - fn ain_rs_init_network_json_rpc_service(result: &mut CrossBoundaryResult, addr: &str); - fn ain_rs_init_network_grpc_service(result: &mut CrossBoundaryResult, addr: &str); - fn ain_rs_init_network_subscriptions_service(result: &mut CrossBoundaryResult, addr: &str); + fn ain_rs_init_network_json_rpc_service(result: &mut CrossBoundaryResult, addr: String); + fn ain_rs_init_network_grpc_service(result: &mut CrossBoundaryResult, addr: String); + fn ain_rs_init_network_subscriptions_service( + result: &mut CrossBoundaryResult, + addr: String, + ); fn ain_rs_stop_network_services(result: &mut CrossBoundaryResult); } // ========== Block ========== #[derive(Default)] pub struct EVMBlockHeader { - pub parent_hash: String, - pub beneficiary: String, - pub state_root: String, - pub receipts_root: String, + pub parent_hash: [u8; 32], + pub beneficiary: [u8; 20], + pub state_root: [u8; 32], + pub receipts_root: [u8; 32], pub number: u64, pub gas_limit: u64, pub gas_used: u64, pub timestamp: u64, pub extra_data: Vec, - pub mix_hash: String, + pub mix_hash: [u8; 32], pub nonce: u64, pub base_fee: u64, } @@ -72,22 +75,22 @@ pub mod ffi { pub struct EVMTransaction { // EIP-2718 transaction type: legacy - 0x0, EIP2930 - 0x1, EIP1559 - 0x2 pub tx_type: u8, - pub hash: String, - pub sender: String, + pub hash: [u8; 32], + pub sender: [u8; 20], pub nonce: u64, pub gas_price: u64, pub gas_limit: u64, pub max_fee_per_gas: u64, pub max_priority_fee_per_gas: u64, pub create_tx: bool, - pub to: String, + pub to: [u8; 20], pub value: u64, pub data: Vec, } #[derive(Default)] pub struct TxMinerInfo { - pub address: String, + pub address: [u8; 20], pub nonce: u64, pub tip_fee: u64, pub min_rbf_tip_fee: u64, @@ -104,20 +107,20 @@ pub mod ffi { // ========== EVM ========== - pub struct CreateTransactionContext<'a> { + pub struct CreateTransactionContext { pub chain_id: u64, pub nonce: u64, pub gas_price: u64, pub gas_limit: u64, - pub to: &'a str, + pub to: [u8; 20], pub value: u64, pub input: Vec, pub priv_key: [u8; 32], } pub struct CreateTransferDomainContext { - pub from: String, - pub to: String, + pub from: [u8; 20], + pub to: [u8; 20], pub native_address: String, pub direction: bool, pub value: u64, @@ -129,8 +132,8 @@ pub mod ffi { } pub struct TransferDomainInfo { - pub from: String, - pub to: String, + pub from: [u8; 20], + pub to: [u8; 20], pub native_address: String, pub direction: bool, pub value: u64, @@ -151,7 +154,7 @@ pub mod ffi { #[derive(Default)] pub struct FinalizeBlockCompletion { - pub block_hash: String, + pub block_hash: [u8; 32], pub total_burnt_fees: u64, pub total_priority_fees: u64, pub block_number: u64, @@ -159,7 +162,7 @@ pub mod ffi { #[derive(Default)] pub struct ValidateTxCompletion { - pub tx_hash: String, + pub tx_hash: [u8; 32], } extern "Rust" { @@ -168,7 +171,7 @@ pub mod ffi { // // 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_get_balance(result: &mut CrossBoundaryResult, address: [u8; 20]) -> u64; fn evm_try_unsafe_create_template( result: &mut CrossBoundaryResult, @@ -197,27 +200,27 @@ pub mod ffi { fn evm_try_unsafe_get_next_valid_nonce_in_template( result: &mut CrossBoundaryResult, block_template: &BlockTemplateWrapper, - address: &str, + address: [u8; 20], ) -> u64; fn evm_try_unsafe_remove_txs_above_hash_in_template( result: &mut CrossBoundaryResult, block_template: &mut BlockTemplateWrapper, - target_hash: String, - ) -> Vec; + target_hash: [u8; 32], + ); fn evm_try_unsafe_add_balance_in_template( result: &mut CrossBoundaryResult, block_template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: [u8; 32], ); fn evm_try_unsafe_sub_balance_in_template( result: &mut CrossBoundaryResult, block_template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: [u8; 32], ) -> bool; fn evm_try_unsafe_validate_raw_tx_in_template( @@ -237,7 +240,7 @@ pub mod ffi { result: &mut CrossBoundaryResult, block_template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: [u8; 32], ) -> ValidateTxCompletion; fn evm_try_unsafe_construct_block_in_template( @@ -270,28 +273,31 @@ pub mod ffi { fn evm_try_store_account_nonce( result: &mut CrossBoundaryResult, - from_address: &str, + from_address: [u8; 20], nonce: u64, ); fn evm_try_get_block_hash_by_number( result: &mut CrossBoundaryResult, height: u64, - ) -> String; + ) -> [u8; 32]; - fn evm_try_get_block_number_by_hash(result: &mut CrossBoundaryResult, hash: &str) -> u64; + fn evm_try_get_block_number_by_hash( + result: &mut CrossBoundaryResult, + hash: [u8; 32], + ) -> u64; fn evm_try_get_block_header_by_hash( result: &mut CrossBoundaryResult, - hash: &str, + hash: [u8; 32], ) -> EVMBlockHeader; fn evm_try_get_tx_by_hash( result: &mut CrossBoundaryResult, - tx_hash: &str, + tx_hash: [u8; 32], ) -> EVMTransaction; - fn evm_try_get_tx_hash(result: &mut CrossBoundaryResult, raw_tx: &str) -> String; + fn evm_try_get_tx_hash(result: &mut CrossBoundaryResult, raw_tx: &str) -> [u8; 32]; fn evm_try_unsafe_make_signed_tx(result: &mut CrossBoundaryResult, raw_tx: &str) -> usize; @@ -304,7 +310,7 @@ pub mod ffi { fn evm_try_unsafe_create_dst20( result: &mut CrossBoundaryResult, block_template: &mut BlockTemplateWrapper, - native_hash: &str, + native_hash: [u8; 32], token: DST20TokenInfo, ); @@ -312,14 +318,14 @@ pub mod ffi { result: &mut CrossBoundaryResult, block_template: &mut BlockTemplateWrapper, raw_tx: &str, - native_hash: &str, + native_hash: [u8; 32], token_id: u64, out: bool, ); fn evm_try_unsafe_is_smart_contract_in_template( result: &mut CrossBoundaryResult, - address: &str, + address: [u8; 20], block_template: &BlockTemplateWrapper, ) -> bool; diff --git a/src/dfi/consensus/xvm.cpp b/src/dfi/consensus/xvm.cpp index 9524d69fc6..934eeb31da 100644 --- a/src/dfi/consensus/xvm.cpp +++ b/src/dfi/consensus/xvm.cpp @@ -64,7 +64,7 @@ static Res ValidateTransferDomainScripts(const CScript &srcScript, if (!config.dvmToEvmDestAddresses.count(destType)) { return DeFiErrors::TransferDomainETHDestAddress(); } - context.to = EncodeDestination(dest); + context.to = CKeyID::FromOrDefaultDestination(dest).GetByteArray(); context.native_address = EncodeDestination(src); return Res::Ok(); @@ -75,7 +75,7 @@ static Res ValidateTransferDomainScripts(const CScript &srcScript, if (!config.evmToDvmDestAddresses.count(destType)) { return DeFiErrors::TransferDomainDVMDestAddress(); } - context.from = EncodeDestination(src); + context.from = CKeyID::FromOrDefaultDestination(src).GetByteArray(); context.native_address = EncodeDestination(dest); return Res::Ok(); } @@ -149,7 +149,7 @@ static Res ValidateTransferDomainEdge(const CTransaction &tx, if (!ExtractDestination(from, dest)) { return DeFiErrors::ScriptUnexpected(from); } - context.from = EncodeDestination(dest); + context.from = CKeyID::FromOrDefaultDestination(dest).GetByteArray(); return HasAuth(tx, coins, src.address); @@ -260,8 +260,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(), evmTemplate->GetTemplate()); + auto isSmartContract = evm_try_unsafe_is_smart_contract_in_template( + result, toAddress->GetByteArray(), evmTemplate->GetTemplate()); if (!result.ok) { return Res::Err("Error checking contract address: %s", result.reason); } @@ -302,18 +302,18 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { if (!result.ok) { return Res::Err("Error getting tx hash: %s", result.reason); } - evmTxHash = std::string(hash.data(), hash.length()).substr(2); + evmTxHash = uint256::FromByteArray(hash).GetHex(); // Add balance to ERC55 address auto tokenId = dst.amount.nTokenId; if (tokenId == DCT_ID{0}) { evm_try_unsafe_add_balance_in_template( - result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex()); + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetByteArray()); if (!result.ok) { return Res::Err("Error bridging DFI: %s", result.reason); } } else { evm_try_unsafe_bridge_dst20( - result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex(), tokenId.v, true); + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetByteArray(), tokenId.v, true); if (!result.ok) { return Res::Err("Error bridging DST20: %s", result.reason); } @@ -333,8 +333,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(), evmTemplate->GetTemplate()); + auto isSmartContract = evm_try_unsafe_is_smart_contract_in_template( + result, fromAddress->GetByteArray(), evmTemplate->GetTemplate()); if (!result.ok) { return Res::Err("Error checking contract address: %s", result.reason); } @@ -359,13 +359,13 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { if (!result.ok) { return Res::Err("Error getting tx hash: %s", result.reason); } - evmTxHash = std::string(hash.data(), hash.length()).substr(2); + evmTxHash = uint256::FromByteArray(hash).GetHex(); // Subtract balance from ERC55 address auto tokenId = dst.amount.nTokenId; if (tokenId == DCT_ID{0}) { if (!evm_try_unsafe_sub_balance_in_template( - result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex())) { + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetByteArray())) { return DeFiErrors::TransferDomainNotEnoughBalance(EncodeDestination(dest)); } if (!result.ok) { @@ -373,7 +373,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } } else { evm_try_unsafe_bridge_dst20( - result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetHex(), tokenId.v, false); + result, evmTemplate->GetTemplate(), evmTx, tx.GetHash().GetByteArray(), tokenId.v, false); if (!result.ok) { return Res::Err("Error bridging DST20: %s", result.reason); } @@ -386,7 +386,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, evmTemplate->GetTemplate(), tx.GetHash().GetHex()); + result, evmTemplate->GetTemplate(), tx.GetHash().GetByteArray()); return res; } stats.evmDvmTotal.Add(dst.amount); @@ -412,7 +412,8 @@ 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, evmTemplate->GetTemplate(), tx.GetHash().GetHex()); + evm_try_unsafe_remove_txs_above_hash_in_template( + result, evmTemplate->GetTemplate(), tx.GetHash().GetByteArray()); return res; } return Res::Ok(); @@ -439,14 +440,14 @@ Res CXVMConsensus::operator()(const CEvmTxMessage &obj) const { } const auto validateResults = evm_try_unsafe_push_tx_in_template( - result, evmTemplate->GetTemplate(), HexStr(obj.evmTx), tx.GetHash().GetHex()); + result, evmTemplate->GetTemplate(), HexStr(obj.evmTx), tx.GetHash().GetByteArray()); 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); } auto txHash = tx.GetHash().GetHex(); - auto evmTxHash = std::string(validateResults.tx_hash.data(), validateResults.tx_hash.length()).substr(2); + auto evmTxHash = uint256::FromByteArray(validateResults.tx_hash).GetHex(); auto res = mnview.SetVMDomainTxEdge(VMDomainEdge::DVMToEVM, txHash, evmTxHash); if (!res) { LogPrintf("Failed to store DVMtoEVM TX hash for DFI TX %s\n", txHash); diff --git a/src/dfi/mn_checks.h b/src/dfi/mn_checks.h index 0904794fbd..ba21440082 100644 --- a/src/dfi/mn_checks.h +++ b/src/dfi/mn_checks.h @@ -27,7 +27,7 @@ struct EVM { std::string blockHash; uint64_t burntFee; uint64_t priorityFee; - EvmAddressData beneficiary; + std::string beneficiary; ADD_SERIALIZE_METHODS; diff --git a/src/dfi/rpc_accounts.cpp b/src/dfi/rpc_accounts.cpp index 407bac8331..72ab22c878 100644 --- a/src/dfi/rpc_accounts.cpp +++ b/src/dfi/rpc_accounts.cpp @@ -505,7 +505,7 @@ UniValue getaccount(const JSONRPCRequest &request) { CTxDestination dest; if (ExtractDestination(reqOwner, dest) && dest.index() == WitV16KeyEthHashType) { const auto keyID = std::get(dest); - auto r = XResultValue(evm_try_get_balance(result, keyID.GetHex())); + auto r = XResultValue(evm_try_get_balance(result, keyID.GetByteArray())); if (!r) { throw JSONRPCError(RPC_MISC_ERROR, r.msg); } @@ -651,7 +651,7 @@ UniValue gettokenbalances(const JSONRPCRequest &request) { if (evm_dfi_lookup) { for (const auto keyID : pwallet->GetKeys()) { // TODO: Use GetHex when eth key is fixed to be stored in LE - auto res = XResultValue(evm_try_get_balance(result, keyID.GetHex())); + auto res = XResultValue(evm_try_get_balance(result, keyID.GetByteArray())); if (res) { auto evmAmount = *res; totalBalances.Add({{}, static_cast(evmAmount)}); @@ -2214,7 +2214,7 @@ UniValue transferdomain(const JSONRPCRequest &request) { CrossBoundaryResult result; CTransferDomainMessage msg; std::set auths; - std::vector> nonce_cache; + std::vector> nonce_cache; for (unsigned int i = 0; i < srcDstArray.size(); i++) { const UniValue &elem = srcDstArray[i].get_obj(); @@ -2234,13 +2234,14 @@ UniValue transferdomain(const JSONRPCRequest &request) { const UniValue &singlekeycheckObj = elem["singlekeycheck"]; CTransferDomainItem src, dst; + CTxDestination srcDest, dstDest; if (!srcObj["address"].isNull()) { - const auto dest = DecodeDestination(srcObj["address"].getValStr()); - if (!IsValidDestination(dest)) { + srcDest = DecodeDestination(srcObj["address"].getValStr()); + if (!IsValidDestination(srcDest)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid src address provided"); } - src.address = GetScriptForDestination(dest); + src.address = GetScriptForDestination(srcDest); } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters, src argument \"address\" must not be null"); } @@ -2282,11 +2283,11 @@ UniValue transferdomain(const JSONRPCRequest &request) { // src.data.assign(srcObj["data"].getValStr().begin(), srcObj["data"].getValStr().end()); if (!dstObj["address"].isNull()) { - const auto dest = DecodeDestination(dstObj["address"].getValStr()); - if (!IsValidDestination(dest)) { + dstDest = DecodeDestination(dstObj["address"].getValStr()); + if (!IsValidDestination(dstDest)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid dst address provided"); } - dst.address = GetScriptForDestination(dest); + dst.address = GetScriptForDestination(dstDest); } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters, dst argument \"address\" must not be null"); } @@ -2328,17 +2329,16 @@ UniValue transferdomain(const JSONRPCRequest &request) { std::array privKey{}; std::copy(key.begin(), key.end(), privKey.begin()); - std::string to = ""; + EvmAddressData to{}; std::string nativeAddress = ""; if (isEVMIn) { - to = ScriptToString(dst.address); + to = CKeyID::FromOrDefaultDestination(dstDest).GetByteArray(); nativeAddress = ScriptToString(src.address); } else { nativeAddress = ScriptToString(dst.address); } auto dest = GetDestinationForKey(srcKey, OutputType::ERC55); - auto script = GetScriptForDestination(dest); - auto from = ScriptToString(script); + auto from = CKeyID::FromOrDefaultDestination(dest).GetByteArray(); uint64_t nonce = 0; bool useNonce = !nonceObj.isNull(); @@ -2412,8 +2412,7 @@ UniValue transferdomain(const JSONRPCRequest &request) { for (auto &nonce : nonce_cache) { evm_try_store_account_nonce(result, nonce.first, nonce.second); if (!result.ok) { - throw JSONRPCError(RPC_DATABASE_ERROR, - strprintf("Could not cache nonce %i for %s", nonce.first, nonce.second)); + throw JSONRPCError(RPC_DATABASE_ERROR, "Could not cache nonce"); } } diff --git a/src/dfi/rpc_customtx.cpp b/src/dfi/rpc_customtx.cpp index 65113b0510..f46c049aa2 100644 --- a/src/dfi/rpc_customtx.cpp +++ b/src/dfi/rpc_customtx.cpp @@ -595,12 +595,15 @@ class CCustomTxRpcVisitor { void operator()(const CEvmTxMessage &obj) const { auto txHash = tx.GetHash().GetHex(); if (auto evmTxHash = mnview.GetVMDomainTxEdge(VMDomainEdge::DVMToEVM, txHash)) { + const auto hash = uint256S(*evmTxHash); + CrossBoundaryResult result; - auto txInfo = evm_try_get_tx_by_hash(result, *evmTxHash); + auto txInfo = evm_try_get_tx_by_hash(result, hash.GetByteArray()); if (!result.ok) { LogPrintf("Failed to get EVM tx info for tx %s: %s\n", txHash, result.reason.c_str()); return; } + std::string tx_type; switch (txInfo.tx_type) { case CEVMTxType::LegacyTransaction: { @@ -619,16 +622,19 @@ class CCustomTxRpcVisitor { break; } } + const auto sender = ETH_ADDR_PREFIX + uint160::FromByteArray(txInfo.sender).GetHex(); + const auto to = ETH_ADDR_PREFIX + uint160::FromByteArray(txInfo.to).GetHex(); + rpcInfo.pushKV("type", tx_type); - rpcInfo.pushKV("hash", *evmTxHash); - rpcInfo.pushKV("sender", std::string(txInfo.sender.data(), txInfo.sender.length())); + rpcInfo.pushKV("hash", hash.GetHex()); + rpcInfo.pushKV("sender", sender); rpcInfo.pushKV("nonce", txInfo.nonce); rpcInfo.pushKV("gasPrice", txInfo.gas_price); rpcInfo.pushKV("gasLimit", txInfo.gas_limit); rpcInfo.pushKV("maxFeePerGas", txInfo.max_fee_per_gas); rpcInfo.pushKV("maxPriorityFeePerGas", txInfo.max_priority_fee_per_gas); rpcInfo.pushKV("createTx", txInfo.create_tx); - rpcInfo.pushKV("to", std::string(txInfo.to.data(), txInfo.to.length())); + rpcInfo.pushKV("to", to); rpcInfo.pushKV("value", txInfo.value); } } diff --git a/src/dfi/rpc_evm.cpp b/src/dfi/rpc_evm.cpp index a7f6070615..1b7eb834a2 100644 --- a/src/dfi/rpc_evm.cpp +++ b/src/dfi/rpc_evm.cpp @@ -78,7 +78,7 @@ UniValue evmtx(const JSONRPCRequest &request) { const auto fromEth = std::get(fromDest); const CKeyID keyId{fromEth}; - const auto from = fromEth.GetHex(); + const auto from = fromEth.GetByteArray(); CKey key; if (!pwallet->GetKey(keyId, key)) { @@ -103,7 +103,7 @@ UniValue evmtx(const JSONRPCRequest &request) { const uint64_t value = AmountFromValue(request.params[5]); // Amount in CAmount const auto toStr = request.params[4].get_str(); - std::string to = ""; + EvmAddressData to{}; if (!toStr.empty()) { const auto toDest = DecodeDestination(toStr); if (toDest.index() != WitV16KeyEthHashType) { @@ -111,7 +111,7 @@ UniValue evmtx(const JSONRPCRequest &request) { } const auto toEth = std::get(toDest); - to = toEth.GetHex(); + to = toEth.GetByteArray(); } rust::Vec input{}; @@ -159,7 +159,7 @@ UniValue evmtx(const JSONRPCRequest &request) { execTestTx(CTransaction(rawTx), targetHeight, optAuthTx); evm_try_store_account_nonce(result, from, createResult.nonce); if (!result.ok) { - throw JSONRPCError(RPC_DATABASE_ERROR, strprintf("Could not cache nonce %i for %s", from, createResult.nonce)); + throw JSONRPCError(RPC_DATABASE_ERROR, "Could not cache nonce"); } return send(MakeTransactionRef(std::move(rawTx)), optAuthTx)->GetHash().ToString(); @@ -317,31 +317,31 @@ UniValue vmmap(const JSONRPCRequest &request) { if (!evmBlockHash.val.has_value()) { throwInvalidParam(evmBlockHash.msg); } + auto hash = uint256S(evmBlockHash); CrossBoundaryResult result; - uint64_t blockNumber = evm_try_get_block_number_by_hash(result, *evmBlockHash.val); + uint64_t blockNumber = evm_try_get_block_number_by_hash(result, hash.GetByteArray()); crossBoundaryOkOrThrow(result); return ResVal(std::to_string(blockNumber), Res::Ok()); }; - auto handleMapBlockNumberEVMToDVMRequest = - [&throwInvalidParam, &ensureEVMHashStripped, &crossBoundaryOkOrThrow](const std::string &input) { - uint64_t height; - bool success = ParseUInt64(input, &height); - if (!success || height < 0) { - throwInvalidParam(DeFiErrors::InvalidBlockNumberString(input).msg); - } - CrossBoundaryResult result; - auto evmHash = evm_try_get_block_hash_by_number(result, height); - auto evmBlockHash = ensureEVMHashStripped(std::string(evmHash.data(), evmHash.length())); - crossBoundaryOkOrThrow(result); - auto dvmBlockHash = pcustomcsview->GetVMDomainBlockEdge(VMDomainEdge::EVMToDVM, evmBlockHash); - if (!dvmBlockHash.val.has_value()) { - throwInvalidParam(dvmBlockHash.msg); - } - CBlockIndex *pindex = LookupBlockIndex(uint256S(*dvmBlockHash.val)); - uint64_t blockNumber = pindex->GetBlockHeader().deprecatedHeight; - return ResVal(std::to_string(blockNumber), Res::Ok()); - }; + auto handleMapBlockNumberEVMToDVMRequest = [&throwInvalidParam, &crossBoundaryOkOrThrow](const std::string &input) { + uint64_t height; + bool success = ParseUInt64(input, &height); + if (!success || height < 0) { + throwInvalidParam(DeFiErrors::InvalidBlockNumberString(input).msg); + } + CrossBoundaryResult result; + auto hash = evm_try_get_block_hash_by_number(result, height); + auto evmBlockHash = uint256::FromByteArray(hash).GetHex(); + crossBoundaryOkOrThrow(result); + auto dvmBlockHash = pcustomcsview->GetVMDomainBlockEdge(VMDomainEdge::EVMToDVM, evmBlockHash); + if (!dvmBlockHash.val.has_value()) { + throwInvalidParam(dvmBlockHash.msg); + } + CBlockIndex *pindex = LookupBlockIndex(uint256S(*dvmBlockHash.val)); + uint64_t blockNumber = pindex->GetBlockHeader().deprecatedHeight; + return ResVal(std::to_string(blockNumber), Res::Ok()); + }; if (type == VMDomainRPCMapType::Auto) { auto [mapType, isResolved] = handleAutoInfer(); diff --git a/src/dfi/tokens.cpp b/src/dfi/tokens.cpp index f3dc7244f0..35f3450b5e 100644 --- a/src/dfi/tokens.cpp +++ b/src/dfi/tokens.cpp @@ -128,7 +128,7 @@ ResVal CTokensView::CreateToken(const CTokensView::CTokenImpl &token, } evm_try_unsafe_create_dst20(result, evmTemplate->GetTemplate(), - token.creationTx.GetHex(), + token.creationTx.GetByteArray(), DST20TokenInfo{ id.v, token_name, diff --git a/src/dfi/validation.cpp b/src/dfi/validation.cpp index 1e84fa11e3..a6a5da5bee 100644 --- a/src/dfi/validation.cpp +++ b/src/dfi/validation.cpp @@ -2620,8 +2620,7 @@ static void ProcessGrandCentralEvents(const CBlockIndex *pindex, } static Res ValidateCoinbaseXVMOutput(const XVM &xvm, const FinalizeBlockCompletion &blockResult) { - const auto blockResultBlockHash = - std::string(blockResult.block_hash.data(), blockResult.block_hash.length()).substr(2); + auto blockResultBlockHash = uint256::FromByteArray(blockResult.block_hash).GetHex(); if (xvm.evm.blockHash != blockResultBlockHash) { return Res::Err("Incorrect EVM block hash in coinbase output"); @@ -2697,7 +2696,7 @@ static Res ProcessEVMQueue(const CBlock &block, return res; } - auto evmBlockHash = std::string(blockResult.block_hash.data(), blockResult.block_hash.length()).substr(2); + auto evmBlockHash = uint256::FromByteArray(blockResult.block_hash).GetHex(); res = cache.SetVMDomainBlockEdge(VMDomainEdge::DVMToEVM, block.GetHash().GetHex(), evmBlockHash); if (!res) { return res; diff --git a/src/ffi/ffiexports.cpp b/src/ffi/ffiexports.cpp index 6f68b3b00a..1269d81bed 100644 --- a/src/ffi/ffiexports.cpp +++ b/src/ffi/ffiexports.cpp @@ -238,15 +238,9 @@ uint64_t getMinRelayTxFee() { return ::minRelayTxFee.GetFeePerK() * 10000000; } -std::array getEthPrivKey(rust::string key) { - const auto dest = DecodeDestination(std::string(key.begin(), key.length())); - if (dest.index() != WitV16KeyEthHashType) { - return {}; - } - const auto keyID = std::get(dest); - const CKeyID ethKeyID{keyID}; - +std::array getEthPrivKey(EvmAddressData key) { CKey ethPrivKey; + const auto ethKeyID = CKeyID(uint160::FromByteArray(key)); for (const auto &wallet : GetWallets()) { if (wallet->GetKey(ethKeyID, ethPrivKey)) { std::array privKeyArray{}; diff --git a/src/ffi/ffiexports.h b/src/ffi/ffiexports.h index d1dd6c7c6b..9d52e40258 100644 --- a/src/ffi/ffiexports.h +++ b/src/ffi/ffiexports.h @@ -74,7 +74,7 @@ std::array getChainWork(std::array blockHash); rust::vec getPoolTransactions(); uint64_t getNativeTxSize(rust::Vec rawTransaction); uint64_t getMinRelayTxFee(); -std::array getEthPrivKey(rust::string key); +std::array getEthPrivKey(EvmAddressData key); rust::string getStateInputJSON(); std::array getEthSyncStatus(); Attributes getAttributeValues(std::size_t mnview_ptr); diff --git a/src/init.cpp b/src/init.cpp index 383965b082..385f4b5d14 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2319,11 +2319,17 @@ bool AppInitMain(InitInterfaces& interfaces) { std::vector eth_endpoints, g_endpoints, ws_endpoints; SetupRPCPorts(eth_endpoints, g_endpoints, ws_endpoints); + CrossBoundaryResult result; // Bind ETH RPC addresses for (auto it = eth_endpoints.begin(); it != eth_endpoints.end(); ++it) { LogPrint(BCLog::HTTP, "Binding ETH RPC server on endpoint %s\n", *it); - auto res = XResultStatusLogged(ain_rs_init_network_json_rpc_service(result, *it)) + const auto addr = rs_try_from_utf8(result, ffi_from_string_to_slice(*it)); + if (!result.ok) { + LogPrint(BCLog::HTTP, "Invalid ETH RPC address, not UTF-8 valid\n"); + return false; + } + auto res = XResultStatusLogged(ain_rs_init_network_json_rpc_service(result, addr)) if (!res) { LogPrintf("Binding ETH RPC server on endpoint %s failed.\n", *it); return false; @@ -2333,7 +2339,12 @@ bool AppInitMain(InitInterfaces& interfaces) // Bind gRPC addresses for (auto it = g_endpoints.begin(); it != g_endpoints.end(); ++it) { LogPrint(BCLog::HTTP, "Binding gRPC server on endpoint %s\n", *it); - auto res = XResultStatusLogged(ain_rs_init_network_grpc_service(result, *it)) + const auto addr = rs_try_from_utf8(result, ffi_from_string_to_slice(*it)); + if (!result.ok) { + LogPrint(BCLog::HTTP, "Invalid gRPC address, not UTF-8 valid\n"); + return false; + } + auto res = XResultStatusLogged(ain_rs_init_network_grpc_service(result, addr)) if (!res) { LogPrintf("Binding gRPC server on endpoint %s failed.\n", *it); return false; @@ -2343,7 +2354,12 @@ bool AppInitMain(InitInterfaces& interfaces) // bind websocket addresses for (auto it = ws_endpoints.begin(); it != ws_endpoints.end(); ++it) { LogPrint(BCLog::HTTP, "Binding websocket server on endpoint %s\n", *it); - auto res = XResultStatusLogged(ain_rs_init_network_subscriptions_service(result, *it)) + const auto addr = rs_try_from_utf8(result, ffi_from_string_to_slice(*it)); + if (!result.ok) { + LogPrint(BCLog::HTTP, "Invalid websocket address, not UTF-8 valid\n"); + return false; + } + auto res = XResultStatusLogged(ain_rs_init_network_subscriptions_service(result, addr)) if (!res) { LogPrintf("Binding websocket server on endpoint %s failed.\n", *it); return false; diff --git a/src/key.h b/src/key.h index 0857fa6639..26699ab05e 100644 --- a/src/key.h +++ b/src/key.h @@ -15,8 +15,7 @@ #include #include -// typedef std::array EvmAddressData; -typedef std::string EvmAddressData; +typedef std::array EvmAddressData; /** * secure_allocator is defined in allocators.h diff --git a/src/miner.cpp b/src/miner.cpp index 7aab355a1c..8c9be00607 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -109,7 +109,7 @@ void BlockAssembler::resetBlock() { ResVal> BlockAssembler::CreateNewBlock(const CScript &scriptPubKeyIn, int64_t blockTime, - const EvmAddressData &evmBeneficiary) { + const std::string &evmBeneficiary) { int64_t nTimeStart = GetTimeMicros(); resetBlock(); @@ -293,13 +293,9 @@ ResVal> BlockAssembler::CreateNewBlock(const CSc return Res::Err("Failed to construct block"); } auto blockResult = *res; + auto blockHash = uint256::FromByteArray(blockResult.block_hash).GetHex(); 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} + 0, {0, blockHash, blockResult.total_burnt_fees, blockResult.total_priority_fees, evmBeneficiary} }; } @@ -928,7 +924,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, if (entryHash != failedCustomTx) { CrossBoundaryResult result; evm_try_unsafe_remove_txs_above_hash_in_template( - result, evmTemplate->GetTemplate(), entryHash.ToString()); + result, evmTemplate->GetTemplate(), entryHash.GetByteArray()); if (!result.ok) { LogPrintf("%s: Unable to remove %s from queue. Will result in a block hash mismatch.\n", __func__, diff --git a/src/miner.h b/src/miner.h index 0c4b202409..8f2f33efa6 100644 --- a/src/miner.h +++ b/src/miner.h @@ -169,7 +169,7 @@ class BlockAssembler { /** Construct a new block template with coinbase to scriptPubKeyIn */ ResVal> CreateNewBlock(const CScript &scriptPubKeyIn, int64_t blockTime = 0, - const EvmAddressData &beneficiary = {}); + const std::string &beneficiary = {}); inline static std::optional m_last_block_num_txs{}; inline static std::optional m_last_block_weight{}; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 39f5706c57..464d4c91d6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -278,11 +278,16 @@ struct RewardInfo { std::optional VmInfoUniv(const CTransaction& tx, bool isEvmEnabledForBlock) { auto evmBlockHeaderToUniValue = [](const EVMBlockHeader& header) { + const auto parent_hash = uint256::FromByteArray(header.parent_hash).GetHex(); + const auto beneficiary = uint160::FromByteArray(header.beneficiary).GetHex(); + const auto state_root = uint256::FromByteArray(header.state_root).GetHex(); + const auto receipts_root = uint256::FromByteArray(header.receipts_root).GetHex(); + UniValue r(UniValue::VOBJ); - r.pushKV("parenthash", std::string(header.parent_hash.data(), header.parent_hash.length())); - r.pushKV("beneficiary", std::string(header.beneficiary.data(), header.beneficiary.length())); - r.pushKV("stateRoot", std::string(header.state_root.data(), header.state_root.length())); - r.pushKV("receiptRoot", std::string(header.receipts_root.data(), header.receipts_root.length())); + r.pushKV("parenthash", parent_hash); + r.pushKV("beneficiary", beneficiary); + r.pushKV("stateRoot", state_root); + r.pushKV("receiptRoot", receipts_root); r.pushKV("number", header.number); r.pushKV("gasLimit", header.gas_limit); r.pushKV("gasUsed", header.gas_used); @@ -307,8 +312,10 @@ std::optional VmInfoUniv(const CTransaction& tx, bool isEvmEnabledForB result.pushKV("vmtype", "coinbase"); result.pushKV("txtype", "coinbase"); result.pushKV("msg", xvm->ToUniValue()); + + auto blockHash = uint256S(xvm->evm.blockHash); CrossBoundaryResult res; - auto evmBlockHeader = evm_try_get_block_header_by_hash(res, xvm->evm.blockHash); + auto evmBlockHeader = evm_try_get_block_header_by_hash(res, blockHash.GetByteArray()); if (!res.ok) return {}; result.pushKV("xvmHeader", evmBlockHeaderToUniValue(evmBlockHeader)); return result; diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index e0734b6062..eafae1ef29 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -778,9 +778,14 @@ BOOST_AUTO_TEST_CASE(test_CreateEthTx) { uint64_t nonce = 0; const uint64_t gasPrice = 449; // 449 GWei const uint64_t gasLimit = 21000; // 21_000 - std::string to = "34c1ca09a2dc717d89baef2f30ff6a6b2975e17e"; uint64_t value = 1000000; // 0.01 DFI + std::string toStr = "0x34c1ca09a2dc717d89baef2f30ff6a6b2975e17e"; + const auto toDest = DecodeDestination(toStr); + BOOST_CHECK_EQUAL(toDest.index(), WitV16KeyEthHashType); + const auto toEth = std::get(toDest); + EvmAddressData to = toEth.GetByteArray(); + const std::vector privKeyVec{ParseHex("1a8ec29c671461a375ee1fb193ab3b64ab5449837e060362daadd4b299ae5571")}; std::array privKey{}; std::copy(privKeyVec.begin(), privKeyVec.end(), privKey.begin()); diff --git a/src/uint256.h b/src/uint256.h index 84a16e521c..16346183ca 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -123,6 +123,10 @@ class uint160 : public base_blob<160> { public: uint160() {} explicit uint160(const std::vector& vch) : base_blob<160>(vch) {} + + static uint160 FromByteArray(const std::array& data) { + return uint160(std::vector(data.rbegin(), data.rend())); + } }; /** 256-bit opaque blob. @@ -134,6 +138,10 @@ class uint256 : public base_blob<256> { public: uint256() {} explicit uint256(const std::vector& vch) : base_blob<256>(vch) {} + + static uint256 FromByteArray(const std::array& data) { + return uint256(std::vector(data.rbegin(), data.rend())); + } }; /* uint256 from const char *. diff --git a/src/validation.cpp b/src/validation.cpp index 0153a53806..733348709d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1073,17 +1073,16 @@ static bool AcceptToMemoryPoolWorker(const CChainParams &chainparams, return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, "evm-sender-info"); } - EvmAddressWithNonce evmAddrAndNonce{txResult.nonce, txResult.address.c_str()}; + EvmAddressWithNonce evmAddrAndNonce{txResult.nonce, txResult.address}; const auto entryTipFee = isEVMTx ? txResult.tip_fee : std::numeric_limits::max(); const auto minRbfFee = isEVMTx ? txResult.min_rbf_tip_fee : std::numeric_limits::max(); - const auto txResultSender = std::string(txResult.address.data(), txResult.address.length()); entry.SetEVMAddrAndNonce(evmAddrAndNonce); entry.SetEVMRbfMinTipFee(minRbfFee); auto senderLimitFlag{false}; - if (!pool.checkAddressNonceAndFee(entry, entryTipFee, txResultSender, senderLimitFlag)) { + if (!pool.checkAddressNonceAndFee(entry, entryTipFee, txResult.address, senderLimitFlag)) { if (senderLimitFlag) { LogPrint(BCLog::MEMPOOL, "Too many replace-by-fee EVM tx from the same sender in mempool. Limit %d.\n", @@ -1096,14 +1095,14 @@ static bool AcceptToMemoryPoolWorker(const CChainParams &chainparams, } } - const auto sender = pool.evmTxsBySender.find(txResultSender); + const auto sender = pool.evmTxsBySender.find(txResult.address); if (sender != pool.evmTxsBySender.end() && sender->second.size() >= MEMPOOL_MAX_ETH_TXS) { LogPrint(BCLog::MEMPOOL, "Too many EVM tx from the same sender in mempool. Limit %d.\n", MEMPOOL_MAX_ETH_TXS); return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "too-many-evm-txs-by-sender"); } else { - ethSender = txResultSender; + ethSender = txResult.address; } evm_try_dispatch_pending_transactions_event(result, rawEVMTx); diff --git a/test/functional/feature_evm_transferdomain.py b/test/functional/feature_evm_transferdomain.py index 70147f6c9a..cee67f7525 100755 --- a/test/functional/feature_evm_transferdomain.py +++ b/test/functional/feature_evm_transferdomain.py @@ -468,8 +468,8 @@ def invalid_values_dvm_evm(self): self.rollback_to(self.start_height) assert_raises_rpc_error( - -1, - "Invalid address", + -32600, + 'Dst address must be an ERC55 address in case of "EVM" domain', lambda: transfer_domain( self.nodes[0], self.address, self.address, "100@DFI", 2, 3 ),