From 07fc9a1177418414e1da07a14d6427dfeb35ad5b Mon Sep 17 00:00:00 2001 From: mertwole Date: Tue, 17 Dec 2024 09:14:04 +0000 Subject: [PATCH] Start refactoring request_bridging --- .../bridge_builtin_operations.rs | 1 - .../app/src/services/request_bridging/mod.rs | 80 +++++++++++++---- .../services/request_bridging/msg_tracker.rs | 27 +++--- .../request_bridging/token_operations.rs | 40 +-------- .../src/services/request_bridging/utils.rs | 87 ++----------------- 5 files changed, 88 insertions(+), 147 deletions(-) diff --git a/gear-programs/vft-manager/app/src/services/request_bridging/bridge_builtin_operations.rs b/gear-programs/vft-manager/app/src/services/request_bridging/bridge_builtin_operations.rs index 70a4f5a2..30c5e28d 100644 --- a/gear-programs/vft-manager/app/src/services/request_bridging/bridge_builtin_operations.rs +++ b/gear-programs/vft-manager/app/src/services/request_bridging/bridge_builtin_operations.rs @@ -23,7 +23,6 @@ pub async fn send_message_to_bridge_builtin( } .encode(); - utils::set_critical_hook(msg_id); utils::send_message_with_gas_for_reply( gear_bridge_builtin, bytes, diff --git a/gear-programs/vft-manager/app/src/services/request_bridging/mod.rs b/gear-programs/vft-manager/app/src/services/request_bridging/mod.rs index 0be2025a..235c713a 100644 --- a/gear-programs/vft-manager/app/src/services/request_bridging/mod.rs +++ b/gear-programs/vft-manager/app/src/services/request_bridging/mod.rs @@ -8,7 +8,7 @@ mod token_operations; mod utils; use bridge_builtin_operations::Payload; -use msg_tracker::{MessageStatus, TxDetails}; +use msg_tracker::{msg_tracker_mut, MessageStatus, TxDetails}; pub use msg_tracker::{msg_tracker_state, MessageInfo as MsgTrackerMessageInfo}; @@ -29,21 +29,27 @@ pub async fn request_bridging( let supply_type = service.state().token_map.get_supply_type(&vara_token_id)?; let config = service.config(); - if gstd::exec::gas_available() - < config.gas_for_token_ops - + config.gas_to_send_request_to_builtin - + config.gas_for_request_bridging - + 3 * config.gas_for_reply_deposit - { - panic!("Please attach more gas"); - } + let transaction_details = TxDetails { + vara_token_id, + sender, + amount, + receiver, + token_supply: TokenSupply::Ethereum, + }; + + msg_tracker_mut().insert_message_info( + msg_id, + MessageStatus::SendingMessageToDepositTokens, + transaction_details, + ); + set_critical_hook(msg_id); match supply_type { TokenSupply::Ethereum => { - token_operations::burn(vara_token_id, sender, receiver, amount, config, msg_id).await?; + token_operations::burn(vara_token_id, sender, amount, config, msg_id).await?; } TokenSupply::Gear => { - token_operations::lock(vara_token_id, sender, amount, receiver, config, msg_id).await?; + token_operations::lock(vara_token_id, sender, amount, config, msg_id).await?; } } @@ -52,15 +58,17 @@ pub async fn request_bridging( token_id: eth_token_id, amount, }; - let nonce = match bridge_builtin_operations::send_message_to_bridge_builtin( + + let bridge_builtin_reply = bridge_builtin_operations::send_message_to_bridge_builtin( state.gear_bridge_builtin, state.erc20_manager_address, payload, config, msg_id, ) - .await - { + .await; + + let nonce = match bridge_builtin_reply { Ok(nonce) => nonce, Err(e) => { match supply_type { @@ -117,7 +125,7 @@ pub async fn handle_interrupted_transfer( .expect("Failed to get ethereum token id"); match msg_info.status { - MessageStatus::TokenDepositCompleted(true) | MessageStatus::BridgeBuiltinStep => { + MessageStatus::TokenDepositCompleted(true) => { let payload = Payload { receiver, token_id: eth_token_id, @@ -155,7 +163,8 @@ pub async fn handle_interrupted_transfer( msg_tracker::msg_tracker_mut().remove_message_info(&msg_id); Ok((nonce, eth_token_id)) } - MessageStatus::WithdrawTokensStep => { + MessageStatus::SendingMessageToReturnTokens | MessageStatus::TokenReturnFailed => { + // TODO: Or unlock. token_operations::mint(vara_token_id, sender, amount, config, msg_id).await?; Err(Error::TokensRefunded) } @@ -164,3 +173,42 @@ pub async fn handle_interrupted_transfer( } } } + +fn set_critical_hook(msg_id: MessageId) { + gstd::critical::set_hook(move || { + let msg_tracker = msg_tracker_mut(); + let msg_info = msg_tracker + .get_message_info(&msg_id) + .expect("Unexpected: msg info does not exist"); + + match msg_info.status { + MessageStatus::SendingMessageToDepositTokens => { + // If still sending, transition to `WaitingReplyFromBurn`. + msg_tracker.update_message_status( + msg_id, + MessageStatus::WaitingReplyFromTokenDepositMessage, + ); + } + // MessageStatus::TokenDepositCompleted(false) => { + // // If the token burn fails, cancel the transaction. + // msg_tracker.remove_message_info(&msg_id); + // } + MessageStatus::SendingMessageToBridgeBuiltin => { + // If still sending, transition to `WaitingReplyFromBuiltin`. + msg_tracker.update_message_status(msg_id, MessageStatus::WaitingReplyFromBuiltin); + } + // MessageStatus::BridgeResponseReceived(None) => { + // // If error occurs during builtin message, go to mint step + // msg_tracker.update_message_status(msg_id, MessageStatus::ReturnTokensStep) + // } + MessageStatus::SendingMessageToReturnTokens => { + msg_tracker.update_message_status( + msg_id, + MessageStatus::WaitingReplyFromTokenReturnMessage, + ); + } + + _ => {} + }; + }); +} diff --git a/gear-programs/vft-manager/app/src/services/request_bridging/msg_tracker.rs b/gear-programs/vft-manager/app/src/services/request_bridging/msg_tracker.rs index 5ab1a652..d8fd443c 100644 --- a/gear-programs/vft-manager/app/src/services/request_bridging/msg_tracker.rs +++ b/gear-programs/vft-manager/app/src/services/request_bridging/msg_tracker.rs @@ -84,8 +84,8 @@ impl MessageTracker { pub fn check_withdraw_result(&mut self, msg_id: &MessageId) -> Result<(), Error> { if let Some(info) = self.message_info.get(msg_id) { match info.status { - MessageStatus::TokenWithdrawCompleted => Ok(()), - MessageStatus::WithdrawTokensStep => Err(Error::MessageFailed), + MessageStatus::TokensReturned => Ok(()), + MessageStatus::TokenReturnFailed => Err(Error::MessageFailed), _ => Err(Error::InvalidMessageStatus), } } else { @@ -96,22 +96,21 @@ impl MessageTracker { #[derive(Debug, Clone, PartialEq, Encode, Decode, TypeInfo)] pub enum MessageStatus { - // Send message to bridge builtin - SendingMessageToBridgeBuiltin, - BridgeResponseReceived(Option), - WaitingReplyFromBuiltin, - BridgeBuiltinStep, - // Deposit tokens statuses SendingMessageToDepositTokens, - TokenDepositCompleted(bool), WaitingReplyFromTokenDepositMessage, + TokenDepositCompleted(bool), + + // Send message to bridge builtin + SendingMessageToBridgeBuiltin, + WaitingReplyFromBuiltin, + BridgeResponseReceived(Option), - // Withdraw tokens statuses. - SendingMessageToWithdrawTokens, - TokenWithdrawCompleted, - WaitingReplyFromTokenWithdrawMessage, - WithdrawTokensStep, + // Return tokens statuses. + SendingMessageToReturnTokens, + WaitingReplyFromTokenReturnMessage, + TokensReturned, + TokenReturnFailed, MessageProcessedWithSuccess(U256), } diff --git a/gear-programs/vft-manager/app/src/services/request_bridging/token_operations.rs b/gear-programs/vft-manager/app/src/services/request_bridging/token_operations.rs index b7c98d4c..6feba125 100644 --- a/gear-programs/vft-manager/app/src/services/request_bridging/token_operations.rs +++ b/gear-programs/vft-manager/app/src/services/request_bridging/token_operations.rs @@ -2,35 +2,19 @@ use sails_rs::prelude::*; use extended_vft_client::vft::io as vft_io; -use super::super::{Config, Error, TokenSupply}; -use super::msg_tracker::{msg_tracker_mut, MessageStatus, TxDetails}; +use super::super::{Config, Error}; +use super::msg_tracker::{msg_tracker_mut, MessageStatus}; use super::utils; pub async fn burn( vara_token_id: ActorId, sender: ActorId, - receiver: H160, amount: U256, config: &Config, msg_id: MessageId, ) -> Result<(), Error> { let bytes: Vec = vft_io::Burn::encode_call(sender, amount); - let transaction_details = TxDetails { - vara_token_id, - sender, - amount, - receiver, - token_supply: TokenSupply::Ethereum, - }; - - msg_tracker_mut().insert_message_info( - msg_id, - MessageStatus::SendingMessageToDepositTokens, - transaction_details, - ); - - utils::set_critical_hook(msg_id); utils::send_message_with_gas_for_reply( vara_token_id, bytes, @@ -47,28 +31,12 @@ pub async fn lock( vara_token_id: ActorId, sender: ActorId, amount: U256, - eth_receiver: H160, config: &Config, msg_id: MessageId, ) -> Result<(), Error> { let receiver = gstd::exec::program_id(); let bytes: Vec = vft_io::TransferFrom::encode_call(sender, receiver, amount); - let transaction_details = TxDetails { - vara_token_id, - sender, - amount, - receiver: eth_receiver, - token_supply: TokenSupply::Gear, - }; - - msg_tracker_mut().insert_message_info( - msg_id, - MessageStatus::SendingMessageToDepositTokens, - transaction_details, - ); - - utils::set_critical_hook(msg_id); utils::send_message_with_gas_for_reply( vara_token_id, bytes, @@ -89,7 +57,7 @@ pub async fn mint( config: &Config, msg_id: MessageId, ) -> Result<(), Error> { - msg_tracker_mut().update_message_status(msg_id, MessageStatus::SendingMessageToWithdrawTokens); + msg_tracker_mut().update_message_status(msg_id, MessageStatus::SendingMessageToReturnTokens); let bytes: Vec = vft_io::Mint::encode_call(receiver, amount); utils::send_message_with_gas_for_reply( @@ -112,7 +80,7 @@ pub async fn unlock( config: &Config, msg_id: MessageId, ) -> Result<(), Error> { - msg_tracker_mut().update_message_status(msg_id, MessageStatus::SendingMessageToWithdrawTokens); + msg_tracker_mut().update_message_status(msg_id, MessageStatus::SendingMessageToReturnTokens); let sender = gstd::exec::program_id(); let bytes: Vec = vft_io::TransferFrom::encode_call(sender, recepient, amount); diff --git a/gear-programs/vft-manager/app/src/services/request_bridging/utils.rs b/gear-programs/vft-manager/app/src/services/request_bridging/utils.rs index 8b818c60..1f005557 100644 --- a/gear-programs/vft-manager/app/src/services/request_bridging/utils.rs +++ b/gear-programs/vft-manager/app/src/services/request_bridging/utils.rs @@ -7,51 +7,6 @@ use gstd::{msg, MessageId}; use sails_rs::calls::ActionIo; use sails_rs::prelude::*; -pub fn set_critical_hook(msg_id: MessageId) { - gstd::critical::set_hook(move || { - let msg_tracker = msg_tracker_mut(); - let msg_info = msg_tracker - .get_message_info(&msg_id) - .expect("Unexpected: msg info does not exist"); - - match msg_info.status { - MessageStatus::SendingMessageToDepositTokens => { - // If still sending, transition to `WaitingReplyFromBurn`. - msg_tracker.update_message_status( - msg_id, - MessageStatus::WaitingReplyFromTokenDepositMessage, - ); - } - MessageStatus::TokenDepositCompleted(true) => { - // If the token transfer is successful, continue to bridge builtin step. - msg_tracker.update_message_status(msg_id, MessageStatus::BridgeBuiltinStep); - } - MessageStatus::TokenDepositCompleted(false) => { - // If the token burn fails, cancel the transaction. - msg_tracker.remove_message_info(&msg_id); - } - - MessageStatus::SendingMessageToBridgeBuiltin => { - // If still sending, transition to `WaitingReplyFromBuiltin`. - msg_tracker.update_message_status(msg_id, MessageStatus::WaitingReplyFromBuiltin); - } - MessageStatus::BridgeResponseReceived(None) => { - // If error occurs during builtin message, go to mint step - msg_tracker.update_message_status(msg_id, MessageStatus::WithdrawTokensStep) - } - - MessageStatus::SendingMessageToWithdrawTokens => { - msg_tracker.update_message_status( - msg_id, - MessageStatus::WaitingReplyFromTokenWithdrawMessage, - ); - } - - _ => {} - }; - }); -} - pub async fn send_message_with_gas_for_reply( destination: ActorId, message: Vec, @@ -81,7 +36,8 @@ fn handle_reply_hook(msg_id: MessageId) { let reply_bytes = msg::load_bytes().expect("Unable to load bytes"); match msg_info.status { - MessageStatus::SendingMessageToDepositTokens => { + MessageStatus::SendingMessageToDepositTokens + | MessageStatus::WaitingReplyFromTokenDepositMessage => { let reply = match msg_info.details.token_supply { TokenSupply::Ethereum => decode_burn_reply(&reply_bytes), TokenSupply::Gear => decode_lock_reply(&reply_bytes), @@ -97,21 +53,7 @@ fn handle_reply_hook(msg_id: MessageId) { } }; } - MessageStatus::WaitingReplyFromTokenDepositMessage => { - let reply = match msg_info.details.token_supply { - TokenSupply::Ethereum => decode_burn_reply(&reply_bytes), - TokenSupply::Gear => decode_lock_reply(&reply_bytes), - } - .unwrap_or(false); - - if reply { - msg_tracker.update_message_status(msg_id, MessageStatus::BridgeBuiltinStep); - } else { - msg_tracker.remove_message_info(&msg_id); - } - } - - MessageStatus::SendingMessageToBridgeBuiltin => { + MessageStatus::SendingMessageToBridgeBuiltin | MessageStatus::WaitingReplyFromBuiltin => { let reply = decode_bridge_reply(&reply_bytes); let result = match reply { Ok(Some(nonce)) => Some(nonce), @@ -120,23 +62,8 @@ fn handle_reply_hook(msg_id: MessageId) { msg_tracker .update_message_status(msg_id, MessageStatus::BridgeResponseReceived(result)); } - MessageStatus::WaitingReplyFromBuiltin => { - let reply = decode_bridge_reply(&reply_bytes); - match reply { - Ok(Some(nonce)) => { - msg_tracker.update_message_status( - msg_id, - MessageStatus::MessageProcessedWithSuccess(nonce), - ); - } - _ => { - msg_tracker.update_message_status(msg_id, MessageStatus::WithdrawTokensStep); - } - }; - } - - MessageStatus::WaitingReplyFromTokenWithdrawMessage - | MessageStatus::SendingMessageToWithdrawTokens => { + MessageStatus::WaitingReplyFromTokenReturnMessage + | MessageStatus::SendingMessageToReturnTokens => { let reply = match msg_info.details.token_supply { TokenSupply::Ethereum => decode_mint_reply(&reply_bytes), TokenSupply::Gear => decode_unlock_reply(&reply_bytes), @@ -144,9 +71,9 @@ fn handle_reply_hook(msg_id: MessageId) { .unwrap_or(false); if !reply { - msg_tracker.update_message_status(msg_id, MessageStatus::WithdrawTokensStep); + msg_tracker.update_message_status(msg_id, MessageStatus::TokenReturnFailed); } else { - msg_tracker.update_message_status(msg_id, MessageStatus::TokenWithdrawCompleted); + msg_tracker.update_message_status(msg_id, MessageStatus::TokensReturned); } }