From f6b7c02b63514f7c2162e58c86f0ea97549013da Mon Sep 17 00:00:00 2001 From: LouiseMedova Date: Tue, 3 Sep 2024 18:11:19 +0300 Subject: [PATCH] added function to vft-gateway to mint tokens --- .../vft-gateway/src/wasm/tests/utils.rs | 26 ++++++++++- .../vft-gateway/src/wasm/tests/vft_gateway.rs | 43 +++++++------------ .../vft-gateway/src/wasm/vft-gateway.idl | 15 ++++--- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/gear-programs/vft-gateway/src/wasm/tests/utils.rs b/gear-programs/vft-gateway/src/wasm/tests/utils.rs index 7752da1a..4eb6f202 100644 --- a/gear-programs/vft-gateway/src/wasm/tests/utils.rs +++ b/gear-programs/vft-gateway/src/wasm/tests/utils.rs @@ -6,6 +6,7 @@ use vft_gateway_app::services::{error::Error, msg_tracker::MessageInfo, Config, pub const ADMIN_ID: u64 = 1000; pub const TOKEN_ID: u64 = 200; pub const BRIDGE_BUILTIN_ID: u64 = 300; +pub const ETH_CLIENT_ID: u64 = 500; // Mocks for programs macro_rules! create_mock { @@ -134,6 +135,7 @@ pub trait VftGateway { from: u64, msg_id: MessageId, ) -> Result<(U256, H160), Error>; + fn mint_tokens(&self, from: u64, vara_token_id: ActorId, amount: U256, receiver: ActorId); fn get_msg_tracker_state(&self) -> Vec<(MessageId, MessageInfo)>; } @@ -143,8 +145,10 @@ impl VftGateway for Program<'_> { let init_config = InitConfig::new( [1; 20].into(), BRIDGE_BUILTIN_ID.into(), + ETH_CLIENT_ID.into(), Config::new( - 2_000_000_000, + 15_000_000_000, + 15_000_000_000, 15_000_000_000, 15_000_000_000, 15_000_000_000, @@ -231,6 +235,26 @@ impl VftGateway for Program<'_> { reply.2 } + fn mint_tokens(&self, from: u64, vara_token_id: ActorId, amount: U256, receiver: ActorId) { + let payload = [ + "VftGateway".encode(), + "MintTokens".encode(), + (vara_token_id, receiver, amount).encode(), + ] + .concat(); + let result = self.send_bytes(from, payload); + let log_entry = result + .log() + .iter() + .find(|log_entry| log_entry.destination() == from.into()) + .expect("Unable to get reply"); + + let reply = <(String, String, Result<(), Error>)>::decode(&mut log_entry.payload()) + .expect("Unable to decode reply"); + println!("{:?}", reply.2); + assert!(reply.2.is_ok()); + } + fn get_msg_tracker_state(&self) -> Vec<(MessageId, MessageInfo)> { let payload = ["VftGateway".encode(), "MsgTrackerState".encode()].concat(); diff --git a/gear-programs/vft-gateway/src/wasm/tests/vft_gateway.rs b/gear-programs/vft-gateway/src/wasm/tests/vft_gateway.rs index e3399b4e..b126d69c 100644 --- a/gear-programs/vft-gateway/src/wasm/tests/vft_gateway.rs +++ b/gear-programs/vft-gateway/src/wasm/tests/vft_gateway.rs @@ -7,10 +7,11 @@ mod utils; use blake2::{digest::typenum::U32, Blake2b, Digest}; use utils::{ FTMockError, FTMockReturnsFalse, GearBridgeBuiltinMock, GearBridgeBuiltinMockPanic, Token, - VftGateway, ADMIN_ID, BRIDGE_BUILTIN_ID, TOKEN_ID, + VftGateway, ADMIN_ID, BRIDGE_BUILTIN_ID, ETH_CLIENT_ID, TOKEN_ID, }; type Blake2b256 = Blake2b; use gear_core::ids::ProgramId; + #[test] fn test_successful_transfer_vara_to_eth() { let system = System::new(); @@ -217,43 +218,29 @@ fn test_transfer_vara_to_eth_insufficient_balance() { assert_eq!(balance, amount); // Balance should remain unchanged } -#[ignore] -#[tokio::test] -async fn test_transfer_fails_due_to_gas_depletion_after_bridge_reply() { +#[test] +fn test_mint_tokens_from_eth_client() { let system = System::new(); system.init_logger(); let vft = Program::token(&system, TOKEN_ID); - let bridge_build_in = Program::mock_with_id(&system, BRIDGE_BUILTIN_ID, GearBridgeBuiltinMock); - assert!(!bridge_build_in.send_bytes(ADMIN_ID, b"INIT").main_failed()); + let gear_bridge_builtin = + Program::mock_with_id(&system, BRIDGE_BUILTIN_ID, GearBridgeBuiltinMock); + assert!(!gear_bridge_builtin + .send_bytes(ADMIN_ID, b"INIT") + .main_failed()); + let vft_gateway = Program::vft_gateway(&system); - let account_id: u64 = 10001; + let receiver: u64 = 10000; let amount = U256::from(10_000_000_000_u64); - let gas = 50_000_000_000; - - vft.mint(ADMIN_ID, account_id.into(), amount); - vft.grant_burner_role(ADMIN_ID, vft_gateway.id()); - vft_gateway.map_vara_to_eth_address(ADMIN_ID, vft.id(), [2; 20].into()); + vft.grant_minter_role(ADMIN_ID, vft_gateway.id()); - // gas ended after contract receives reply from bridge builtin + vft_gateway.mint_tokens(ETH_CLIENT_ID, vft.id().into(), amount, receiver.into()); - let reply = - vft_gateway.transfer_vara_to_eth(account_id, vft.id(), amount, [3; 20].into(), gas, true); - assert_eq!(reply, Err(Error::MessageFailed)); - - let msg_tracker = vft_gateway.get_msg_tracker_state(); - assert_eq!( - msg_tracker[0].1.status, - MessageStatus::BridgeResponseReceived(Some(U256::one())) - ); - - let reply = vft_gateway.handle_interrupted_transfer(account_id, msg_tracker[0].0); - let exp_reply: Result<(U256, H160), Error> = Ok((U256::from(1), H160::from([2; 20]))); - assert_eq!(reply, exp_reply); - let msg_tracker = vft_gateway.get_msg_tracker_state(); - assert!(msg_tracker.is_empty()); + let balance = vft.balance_of(receiver.into()); + assert_eq!(balance, amount); } #[test] diff --git a/gear-programs/vft-gateway/src/wasm/vft-gateway.idl b/gear-programs/vft-gateway/src/wasm/vft-gateway.idl index 16781891..f39d1797 100644 --- a/gear-programs/vft-gateway/src/wasm/vft-gateway.idl +++ b/gear-programs/vft-gateway/src/wasm/vft-gateway.idl @@ -1,6 +1,7 @@ type InitConfig = struct { receiver_contract_address: h160, gear_bridge_builtin: actor_id, + eth_client: actor_id, config: Config, }; @@ -8,6 +9,7 @@ type Config = struct { 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, @@ -37,7 +39,7 @@ type Error = enum { type MessageInfo = struct { status: MessageStatus, - details: TransactionDetails, + details: TxDetails, }; type MessageStatus = enum { @@ -55,11 +57,9 @@ type MessageStatus = enum { MessageProcessedWithSuccess: u256, }; -type TransactionDetails = struct { - vara_token_id: actor_id, - sender: actor_id, - amount: u256, - receiver: h160, +type TxDetails = enum { + TransferVaraToEth: struct { vara_token_id: actor_id, sender: actor_id, amount: u256, receiver: h160 }, + MintTokens: struct { vara_token_id: actor_id, receiver: actor_id, amount: u256 }, }; constructor { @@ -69,9 +69,10 @@ constructor { service VftGateway { HandleInterruptedTransfer : (msg_id: message_id) -> result (struct { u256, h160 }, Error); MapVaraToEthAddress : (vara_token_id: actor_id, eth_token_id: h160) -> null; + MintTokens : (vara_token_id: actor_id, receiver: actor_id, amount: u256) -> result (null, Error); RemoveVaraToEthAddress : (vara_token_id: actor_id) -> null; TransferVaraToEth : (vara_token_id: actor_id, amount: u256, receiver: h160) -> result (struct { u256, h160 }, Error); - UpdateConfig : (gas_to_burn_tokens: opt u64, gas_to_mint_tokens: opt u64, gas_for_reply_deposit: opt u64, gas_to_send_request_to_builtin: opt u64, reply_timeout: opt u32, gas_for_transfer_to_eth_msg: opt u64) -> null; + UpdateConfig : (gas_to_burn_tokens: opt u64, gas_to_mint_tokens: opt u64, gas_to_process_mint_request: opt u64, gas_for_reply_deposit: opt u64, gas_to_send_request_to_builtin: opt u64, reply_timeout: opt u32, gas_for_transfer_to_eth_msg: opt u64) -> null; UpdateReceiverContractAddress : (new_receiver_contract_address: h160) -> null; query Admin : () -> actor_id; query GearBridgeBuiltin : () -> actor_id;