diff --git a/gear-programs/vft-gateway/src/services/mod.rs b/gear-programs/vft-gateway/src/services/mod.rs index 197839c4..1680f09b 100644 --- a/gear-programs/vft-gateway/src/services/mod.rs +++ b/gear-programs/vft-gateway/src/services/mod.rs @@ -7,7 +7,7 @@ pub mod msg_tracker; mod utils; mod vft; use error::Error; -use msg_tracker::{MessageInfo, MessageStatus, MessageTracker}; +use msg_tracker::{MessageInfo, MessageStatus, MessageTracker, TxDetails}; mod token_operations; pub struct VftGateway { @@ -31,12 +31,14 @@ pub struct VftGatewayData { admin: ActorId, receiver_contract_address: H160, vara_to_eth_token_id: HashMap, + eth_client: ActorId, } #[derive(Debug, Decode, Encode, TypeInfo)] pub struct InitConfig { pub receiver_contract_address: H160, pub gear_bridge_builtin: ActorId, + pub eth_client: ActorId, pub config: Config, } @@ -44,11 +46,13 @@ impl InitConfig { pub fn new( receiver_contract_address: H160, gear_bridge_builtin: ActorId, + eth_client: ActorId, config: Config, ) -> Self { Self { receiver_contract_address, gear_bridge_builtin, + eth_client, config, } } @@ -59,6 +63,7 @@ pub struct Config { gas_to_burn_tokens: u64, gas_for_reply_deposit: u64, gas_to_mint_tokens: u64, + gas_to_process_mint_request: u64, gas_to_send_request_to_builtin: u64, reply_timeout: u32, gas_for_transfer_to_eth_msg: u64, @@ -69,6 +74,7 @@ impl Config { gas_to_burn_tokens: u64, gas_for_reply_deposit: u64, gas_to_mint_tokens: u64, + gas_to_process_mint_request: u64, gas_to_send_request_to_builtin: u64, reply_timeout: u32, gas_for_transfer_to_eth_msg: u64, @@ -77,6 +83,7 @@ impl Config { gas_to_burn_tokens, gas_for_reply_deposit, gas_to_mint_tokens, + gas_to_process_mint_request, gas_to_send_request_to_builtin, reply_timeout, gas_for_transfer_to_eth_msg, @@ -116,6 +123,7 @@ where &mut self, gas_to_burn_tokens: Option, gas_to_mint_tokens: Option, + gas_to_process_mint_request: Option, gas_for_reply_deposit: Option, gas_to_send_request_to_builtin: Option, reply_timeout: Option, @@ -132,6 +140,10 @@ where self.config_mut().gas_to_mint_tokens = gas_to_mint_tokens; } + if let Some(gas_to_process_mint_request) = gas_to_process_mint_request { + self.config_mut().gas_to_process_mint_request = gas_to_process_mint_request; + } + if let Some(gas_to_send_request_to_builtin) = gas_to_send_request_to_builtin { self.config_mut().gas_to_send_request_to_builtin = gas_to_send_request_to_builtin; } @@ -149,6 +161,41 @@ where } } + pub async fn mint_tokens( + &mut self, + vara_token_id: ActorId, + receiver: ActorId, + amount: U256, + ) -> Result<(), Error> { + let data = self.data(); + let sender = self.exec_context.actor_id(); + + assert_eq!(sender, data.eth_client, "Only eth client can mint tokens"); + + let config = self.config(); + if gstd::exec::gas_available() + < config.gas_to_mint_tokens + + config.gas_to_process_mint_request + + config.gas_for_reply_deposit + { + panic!("Please attach more gas"); + } + + let msg_id = gstd::msg::id(); + let transaction_details = TxDetails::MintTokens { + vara_token_id, + receiver, + amount, + }; + msg_tracker_mut().insert_message_info( + msg_id, + MessageStatus::SendingMessageToMintTokens, + transaction_details, + ); + utils::set_critical_hook(msg_id); + token_operations::mint_tokens(vara_token_id, receiver, amount, config, msg_id).await + } + pub async fn transfer_vara_to_eth( &mut self, vara_token_id: ActorId, @@ -158,7 +205,6 @@ where let data = self.data(); let sender = self.exec_context.actor_id(); let msg_id = gstd::msg::id(); - let eth_token_id = self.get_eth_token_id(&vara_token_id)?; let config = self.config(); @@ -170,6 +216,7 @@ where { panic!("Please attach more gas"); } + token_operations::burn_tokens(vara_token_id, sender, receiver, amount, config, msg_id) .await?; let nonce = match bridge_builtin_operations::send_message_to_bridge_builtin( @@ -207,7 +254,18 @@ where .get_message_info(&msg_id) .expect("Unexpected: msg status does not exist"); - let (sender, amount, receiver, vara_token_id) = msg_info.details.data(); + let (sender, amount, receiver, vara_token_id) = if let TxDetails::TransferVaraToEth { + vara_token_id, + sender, + amount, + receiver, + } = msg_info.details + { + (sender, amount, receiver, vara_token_id) + } else { + panic!("Wrong message type") + }; + let eth_token_id = data .vara_to_eth_token_id .get(&vara_token_id) @@ -295,6 +353,7 @@ where gear_bridge_builtin: config.gear_bridge_builtin, receiver_contract_address: config.receiver_contract_address, admin: exec_context.actor_id(), + eth_client: config.eth_client, ..Default::default() }); CONFIG = Some(config.config); diff --git a/gear-programs/vft-gateway/src/services/msg_tracker.rs b/gear-programs/vft-gateway/src/services/msg_tracker.rs index a111f00e..82a22955 100644 --- a/gear-programs/vft-gateway/src/services/msg_tracker.rs +++ b/gear-programs/vft-gateway/src/services/msg_tracker.rs @@ -10,15 +10,22 @@ pub struct MessageTracker { #[derive(Debug, Clone, Encode, Decode, TypeInfo)] pub struct MessageInfo { pub status: MessageStatus, - pub details: TransactionDetails, + pub details: TxDetails, } #[derive(Debug, Clone, Encode, Decode, TypeInfo)] -pub struct TransactionDetails { - vara_token_id: ActorId, - sender: ActorId, - amount: U256, - receiver: H160, +pub enum TxDetails { + TransferVaraToEth { + vara_token_id: ActorId, + sender: ActorId, + amount: U256, + receiver: H160, + }, + MintTokens { + vara_token_id: ActorId, + receiver: ActorId, + amount: U256, + }, } impl MessageTracker { @@ -26,7 +33,7 @@ impl MessageTracker { &mut self, msg_id: MessageId, status: MessageStatus, - details: TransactionDetails, + details: TxDetails, ) { self.message_info .insert(msg_id, MessageInfo { status, details }); @@ -111,18 +118,3 @@ pub enum MessageStatus { MessageProcessedWithSuccess(U256), } - -impl TransactionDetails { - pub fn new(sender: ActorId, amount: U256, receiver: H160, vara_token_id: ActorId) -> Self { - Self { - vara_token_id, - sender, - amount, - receiver, - } - } - - pub fn data(&self) -> (ActorId, U256, H160, ActorId) { - (self.sender, self.amount, self.receiver, self.vara_token_id) - } -} diff --git a/gear-programs/vft-gateway/src/services/token_operations.rs b/gear-programs/vft-gateway/src/services/token_operations.rs index ca78ead1..4bfc5585 100644 --- a/gear-programs/vft-gateway/src/services/token_operations.rs +++ b/gear-programs/vft-gateway/src/services/token_operations.rs @@ -1,10 +1,10 @@ -use super::msg_tracker::TransactionDetails; +use super::msg_tracker::TxDetails; use super::{msg_tracker_mut, utils, vft::vft::io as vft_io, Config, Error, MessageStatus}; use sails_rs::prelude::*; pub async fn burn_tokens( - token_id: ActorId, + vara_token_id: ActorId, sender: ActorId, receiver: H160, amount: U256, @@ -13,7 +13,12 @@ pub async fn burn_tokens( ) -> Result<(), Error> { let bytes: Vec = vft_io::Burn::encode_call(sender, amount); - let transaction_details = TransactionDetails::new(sender, amount, receiver, token_id); + let transaction_details = TxDetails::TransferVaraToEth { + vara_token_id, + sender, + amount, + receiver, + }; msg_tracker_mut().insert_message_info( msg_id, @@ -23,7 +28,7 @@ pub async fn burn_tokens( utils::set_critical_hook(msg_id); utils::send_message_with_gas_for_reply( - token_id, + vara_token_id, bytes, config.gas_to_burn_tokens, config.gas_for_reply_deposit, @@ -36,15 +41,14 @@ pub async fn burn_tokens( pub async fn mint_tokens( token_id: ActorId, - sender: ActorId, + receiver: ActorId, amount: U256, config: &Config, msg_id: MessageId, ) -> Result<(), Error> { msg_tracker_mut().update_message_status(msg_id, MessageStatus::SendingMessageToMintTokens); - let bytes: Vec = vft_io::Mint::encode_call(sender, amount); - + let bytes: Vec = vft_io::Mint::encode_call(receiver, amount); utils::send_message_with_gas_for_reply( token_id, bytes,