From 4b57a01e5a53ac9ca19c4f6b75797444e7c97bd4 Mon Sep 17 00:00:00 2001 From: karim-en Date: Wed, 21 Feb 2024 00:40:27 +0000 Subject: [PATCH 1/7] Add api to get ft balances for multiple accounts --- .../src/contract_methods/connector/internal.rs | 17 +++++++++++++++++ engine/src/contract_methods/connector/mod.rs | 6 ++++++ engine/src/lib.rs | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/engine/src/contract_methods/connector/internal.rs b/engine/src/contract_methods/connector/internal.rs index 91c13754c..2c26e6bca 100644 --- a/engine/src/contract_methods/connector/internal.rs +++ b/engine/src/contract_methods/connector/internal.rs @@ -379,6 +379,13 @@ pub fn ft_balance_of(io: I) -> Result<(), ContractError> { Ok(()) } +#[cfg(not(feature = "ext-connector"))] +pub fn ft_balance_of_accounts(io: I) -> Result<(), ContractError> { + let accounts: Vec = io.read_input_borsh()?; + EthConnectorContract::init(io)?.ft_balance_of_accounts(accounts); + Ok(()) +} + #[named] pub fn finish_deposit( io: I, @@ -822,6 +829,16 @@ impl EthConnectorContract { self.io.return_output(format!("\"{balance}\"").as_bytes()); } + /// Return `nETH` balances for accounts (ETH on NEAR). + pub fn ft_balance_of_accounts(&mut self, accounts: Vec) { + let mut balances = aurora_engine_types::HashMap::new(); + for account_id in accounts { + let balance = self.ft.ft_balance_of(&account_id); + balances.insert(account_id, balance); + } + self.io.return_output(&balances.try_to_vec().unwrap()); + } + /// Return `ETH` balance (ETH on Aurora). pub fn ft_balance_of_eth_on_aurora( &mut self, diff --git a/engine/src/contract_methods/connector/mod.rs b/engine/src/contract_methods/connector/mod.rs index c5cd3804a..0c4117a7d 100644 --- a/engine/src/contract_methods/connector/mod.rs +++ b/engine/src/contract_methods/connector/mod.rs @@ -349,6 +349,12 @@ pub fn ft_balance_of(io: I) -> Result<(), Contrac Ok(()) } +#[cfg(not(feature = "ext-connector"))] +pub fn ft_balance_of_accounts(io: I) -> Result<(), ContractError> { + internal::ft_balance_of_accounts(io)?; + Ok(()) +} + pub fn ft_balance_of_eth(io: I) -> Result<(), ContractError> { let args = io.read_input_borsh()?; EthConnectorContract::init(io)?.ft_balance_of_eth_on_aurora(&args)?; diff --git a/engine/src/lib.rs b/engine/src/lib.rs index b110eb812..d9c268746 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -649,6 +649,15 @@ mod contract { .sdk_unwrap(); } + #[no_mangle] + #[cfg(not(feature = "ext-connector"))] + pub extern "C" fn ft_balance_of_accounts() { + let io = Runtime; + contract_methods::connector::ft_balance_of_accounts(io) + .map_err(ContractError::msg) + .sdk_unwrap(); + } + #[no_mangle] pub extern "C" fn ft_balance_of_eth() { let io = Runtime; From c05b4aabe1234ea64868dce64ea424ac610d9b9d Mon Sep 17 00:00:00 2001 From: karim-en Date: Fri, 23 Feb 2024 02:09:42 +0000 Subject: [PATCH 2/7] Rename `ft_balance_of_accounts` --- engine/src/contract_methods/connector/internal.rs | 6 +++--- engine/src/contract_methods/connector/mod.rs | 4 ++-- engine/src/lib.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/engine/src/contract_methods/connector/internal.rs b/engine/src/contract_methods/connector/internal.rs index 2c26e6bca..648ef926a 100644 --- a/engine/src/contract_methods/connector/internal.rs +++ b/engine/src/contract_methods/connector/internal.rs @@ -380,9 +380,9 @@ pub fn ft_balance_of(io: I) -> Result<(), ContractError> { } #[cfg(not(feature = "ext-connector"))] -pub fn ft_balance_of_accounts(io: I) -> Result<(), ContractError> { +pub fn ft_balances_of(io: I) -> Result<(), ContractError> { let accounts: Vec = io.read_input_borsh()?; - EthConnectorContract::init(io)?.ft_balance_of_accounts(accounts); + EthConnectorContract::init(io)?.ft_balances_of(accounts); Ok(()) } @@ -830,7 +830,7 @@ impl EthConnectorContract { } /// Return `nETH` balances for accounts (ETH on NEAR). - pub fn ft_balance_of_accounts(&mut self, accounts: Vec) { + pub fn ft_balances_of(&mut self, accounts: Vec) { let mut balances = aurora_engine_types::HashMap::new(); for account_id in accounts { let balance = self.ft.ft_balance_of(&account_id); diff --git a/engine/src/contract_methods/connector/mod.rs b/engine/src/contract_methods/connector/mod.rs index 0c4117a7d..ca98b88a1 100644 --- a/engine/src/contract_methods/connector/mod.rs +++ b/engine/src/contract_methods/connector/mod.rs @@ -350,8 +350,8 @@ pub fn ft_balance_of(io: I) -> Result<(), Contrac } #[cfg(not(feature = "ext-connector"))] -pub fn ft_balance_of_accounts(io: I) -> Result<(), ContractError> { - internal::ft_balance_of_accounts(io)?; +pub fn ft_balances_of(io: I) -> Result<(), ContractError> { + internal::ft_balances_of(io)?; Ok(()) } diff --git a/engine/src/lib.rs b/engine/src/lib.rs index d9c268746..657e228ba 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -651,9 +651,9 @@ mod contract { #[no_mangle] #[cfg(not(feature = "ext-connector"))] - pub extern "C" fn ft_balance_of_accounts() { + pub extern "C" fn ft_balances_of() { let io = Runtime; - contract_methods::connector::ft_balance_of_accounts(io) + contract_methods::connector::ft_balances_of(io) .map_err(ContractError::msg) .sdk_unwrap(); } From 34b5adb92bb3cfd930acc7192e648ca1e22f30ea Mon Sep 17 00:00:00 2001 From: karim-en Date: Fri, 23 Feb 2024 22:26:11 +0000 Subject: [PATCH 3/7] Add test for `ft_balances_of` --- engine-tests/src/tests/erc20_connector.rs | 61 +++++++++++++++++++++-- engine-workspace/src/contract.rs | 6 ++- engine-workspace/src/operation.rs | 5 +- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/engine-tests/src/tests/erc20_connector.rs b/engine-tests/src/tests/erc20_connector.rs index e35ae8250..1b913cb39 100644 --- a/engine-tests/src/tests/erc20_connector.rs +++ b/engine-tests/src/tests/erc20_connector.rs @@ -394,7 +394,6 @@ pub mod workspace { nep_141_balance_of, transfer_nep_141, transfer_nep_141_to_erc_20, }; use aurora_engine::parameters::{CallArgs, FunctionCallArgsV2}; - #[cfg(feature = "ext-connector")] use aurora_engine::proof::Proof; use aurora_engine_types::parameters::engine::TransactionStatus; use aurora_engine_workspace::account::Account; @@ -408,6 +407,8 @@ pub mod workspace { const FT_ACCOUNT: &str = "test_token"; const INITIAL_ETH_BALANCE: u64 = 777_777_777; const ETH_EXIT_AMOUNT: u64 = 111_111_111; + const ETH_CUSTODIAN_ADDRESS: &str = "096de9c2b8a5b8c22cee3289b101f6960d68e51e"; + const ONE_YOCTO: NearToken = NearToken::from_yoctonear(1); #[tokio::test] async fn test_ghsa_5c82_x4m4_hcj6_exploit() { @@ -770,6 +771,48 @@ pub mod workspace { ); } + #[cfg(not(feature = "ext-connector"))] + #[tokio::test] + async fn test_ft_balances_of() { + use aurora_engine_types::account_id::AccountId; + use aurora_engine_types::HashMap; + + let aurora = deploy_engine().await; + let metadata = Default::default(); + aurora + .set_eth_connector_contract_data( + aurora.id(), + ETH_CUSTODIAN_ADDRESS.to_string(), + metadata, + ) + .transact() + .await + .unwrap(); + + deposit_balance(&aurora).await; + + let balances: HashMap = HashMap::from([ + (AccountId::new("account1").unwrap(), 10), + (AccountId::new("account2").unwrap(), 20), + (AccountId::new("account3").unwrap(), 30), + ]); + + for (account_id, amount) in &balances { + aurora + .ft_transfer(account_id, (*amount).into(), None) + .deposit(ONE_YOCTO) + .transact() + .await + .unwrap(); + let blanace = aurora.ft_balance_of(account_id).await.unwrap().result; + assert_eq!(blanace.0, *amount); + } + + let accounts = balances.keys().cloned().collect(); + let result = aurora.ft_balances_of(&accounts).await.unwrap().result; + assert_eq!(result, balances); + } + async fn test_exit_to_near_eth_common() -> anyhow::Result { let aurora = deploy_engine().await; let chain_id = aurora.get_chain_id().await?.result.as_u64(); @@ -975,17 +1018,28 @@ pub mod workspace { } } - #[cfg(feature = "ext-connector")] async fn deposit_balance(aurora: &EngineContract) { let proof = create_test_proof( INITIAL_ETH_BALANCE, aurora.id().as_ref(), - "096de9c2b8a5b8c22cee3289b101f6960d68e51e", + ETH_CUSTODIAN_ADDRESS, ); let result = aurora.deposit(proof).max_gas().transact().await.unwrap(); assert!(result.is_success()); } + // #[cfg(not(feature = "ext-connector"))] + // async fn deposit_balance_for( + // aurora: &EngineContract, + // recipient_id: &str, + // amount: u64, + // eth_custodian_address: &str, + // ) { + // let proof = create_test_proof(amount, recipient_id, eth_custodian_address); + // let result = aurora.deposit(proof).max_gas().transact().await.unwrap(); + // assert!(result.is_success()); + // } + struct TestExitToNearContext { ft_owner: Account, ft_owner_address: Address, @@ -1004,7 +1058,6 @@ pub mod workspace { aurora: EngineContract, } - #[cfg(feature = "ext-connector")] fn create_test_proof( deposit_amount: u64, recipient_id: &str, diff --git a/engine-workspace/src/contract.rs b/engine-workspace/src/contract.rs index 8c9ba30ca..c5a18178d 100644 --- a/engine-workspace/src/contract.rs +++ b/engine-workspace/src/contract.rs @@ -13,7 +13,7 @@ use crate::operation::{ CallStageUpgrade, CallStateMigration, CallStorageDeposit, CallStorageUnregister, CallStorageWithdraw, CallSubmit, CallUpgrade, CallWithdraw, ViewAccountsCounter, ViewBalance, ViewBlockHash, ViewBridgeProver, ViewChainId, ViewCode, ViewErc20FromNep141, - ViewFactoryWnearAddress, ViewFtBalanceOf, ViewFtBalanceOfEth, ViewFtMetadata, + ViewFactoryWnearAddress, ViewFtBalanceOf, ViewFtBalanceOfEth, ViewFtBalancesOf, ViewFtMetadata, ViewFtTotalEthSupplyOnAurora, ViewFtTotalEthSupplyOnNear, ViewFtTotalSupply, ViewGetErc20Metadata, ViewGetEthConnectorContractAccount, ViewGetFixedGas, ViewGetSiloParams, ViewGetWhitelistStatus, ViewIsUsedProof, ViewNep141FromErc20, ViewNonce, ViewOwner, @@ -377,6 +377,10 @@ impl EngineContract { ViewFtBalanceOf::view(&self.contract).args_json(json!({ "account_id": account_id })) } + pub fn ft_balances_of(&self, accounts: &Vec) -> ViewFtBalancesOf { + ViewFtBalancesOf::view(&self.contract).args_borsh(accounts) + } + pub fn storage_balance_of(&self, account_id: &AccountId) -> ViewStorageBalanceOf { ViewStorageBalanceOf::view(&self.contract).args_json(json!({ "account_id": account_id })) } diff --git a/engine-workspace/src/operation.rs b/engine-workspace/src/operation.rs index f25e7924f..a16266c95 100644 --- a/engine-workspace/src/operation.rs +++ b/engine-workspace/src/operation.rs @@ -5,7 +5,7 @@ use aurora_engine_types::parameters::connector::{ use aurora_engine_types::parameters::engine::{StorageBalance, SubmitResult, TransactionStatus}; use aurora_engine_types::parameters::silo::{FixedGasArgs, SiloParamsArgs, WhitelistStatusArgs}; use aurora_engine_types::types::Address; -use aurora_engine_types::{H256, U256}; +use aurora_engine_types::{HashMap, H256, U256}; use near_sdk::json_types::U128; use near_sdk::PromiseOrValue; @@ -77,6 +77,7 @@ impl_call_return![ impl_view_return![ (ViewFtTotalSupply => U128, View::FtTotalSupply, json), (ViewFtBalanceOf => U128, View::FtBalanceOf, json), + (ViewFtBalancesOf => HashMap, View::FtBalancesOf, borsh), (ViewStorageBalanceOf => StorageBalance, View::StorageBalanceOf, json), (ViewFtMetadata => FungibleTokenMetadata, View::FtMetadata, json), (ViewVersion => String, View::Version, borsh), @@ -226,6 +227,7 @@ pub enum View { IsUsedProof, FtTotalSupply, FtBalanceOf, + FtBalancesOf, FtBalanceOfEth, FtTotalEthSupplyOnAurora, FtTotalEthSupplyOnNear, @@ -261,6 +263,7 @@ impl AsRef for View { View::IsUsedProof => "is_used_proof", View::FtTotalSupply => "ft_total_supply", View::FtBalanceOf => "ft_balance_of", + View::FtBalancesOf => "ft_balances_of", View::FtBalanceOfEth => "ft_balance_of_eth", View::FtTotalEthSupplyOnAurora => "ft_total_eth_supply_on_aurora", View::FtTotalEthSupplyOnNear => "ft_total_eth_supply_on_near", From 4c6eeaa5fb5fe7a40e949954b42d40418e8e16a3 Mon Sep 17 00:00:00 2001 From: karim-en Date: Fri, 23 Feb 2024 22:37:22 +0000 Subject: [PATCH 4/7] Apply clippy --- engine-tests/src/tests/erc20_connector.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/engine-tests/src/tests/erc20_connector.rs b/engine-tests/src/tests/erc20_connector.rs index 1b913cb39..984cf896e 100644 --- a/engine-tests/src/tests/erc20_connector.rs +++ b/engine-tests/src/tests/erc20_connector.rs @@ -408,6 +408,7 @@ pub mod workspace { const INITIAL_ETH_BALANCE: u64 = 777_777_777; const ETH_EXIT_AMOUNT: u64 = 111_111_111; const ETH_CUSTODIAN_ADDRESS: &str = "096de9c2b8a5b8c22cee3289b101f6960d68e51e"; + #[cfg(not(feature = "ext-connector"))] const ONE_YOCTO: NearToken = NearToken::from_yoctonear(1); #[tokio::test] @@ -774,11 +775,12 @@ pub mod workspace { #[cfg(not(feature = "ext-connector"))] #[tokio::test] async fn test_ft_balances_of() { + use aurora_engine::parameters::FungibleTokenMetadata; use aurora_engine_types::account_id::AccountId; use aurora_engine_types::HashMap; let aurora = deploy_engine().await; - let metadata = Default::default(); + let metadata = FungibleTokenMetadata::default(); aurora .set_eth_connector_contract_data( aurora.id(), @@ -1028,18 +1030,6 @@ pub mod workspace { assert!(result.is_success()); } - // #[cfg(not(feature = "ext-connector"))] - // async fn deposit_balance_for( - // aurora: &EngineContract, - // recipient_id: &str, - // amount: u64, - // eth_custodian_address: &str, - // ) { - // let proof = create_test_proof(amount, recipient_id, eth_custodian_address); - // let result = aurora.deposit(proof).max_gas().transact().await.unwrap(); - // assert!(result.is_success()); - // } - struct TestExitToNearContext { ft_owner: Account, ft_owner_address: Address, From 9229b37abc05dc6f34fb328e03e48fcde9a916e3 Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Mon, 26 Feb 2024 10:58:26 +0000 Subject: [PATCH 5/7] borsh::to_vec instead of the try_to_vec --- engine/src/contract_methods/connector/internal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/contract_methods/connector/internal.rs b/engine/src/contract_methods/connector/internal.rs index c34a83823..3bfd1e61a 100644 --- a/engine/src/contract_methods/connector/internal.rs +++ b/engine/src/contract_methods/connector/internal.rs @@ -832,7 +832,7 @@ impl EthConnectorContract { let balance = self.ft.ft_balance_of(&account_id); balances.insert(account_id, balance); } - self.io.return_output(&balances.try_to_vec().unwrap()); + self.io.return_output(&borsh::to_vec(&balances).unwrap()); } /// Return `ETH` balance (ETH on Aurora). From faff9947d7746fdb9ad59d768f5959ae86033c2d Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 27 Feb 2024 14:15:19 +0000 Subject: [PATCH 6/7] chore: remove redundant mutable reference Co-authored-by: Michael Birch --- engine/src/contract_methods/connector/internal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/contract_methods/connector/internal.rs b/engine/src/contract_methods/connector/internal.rs index 3bfd1e61a..fa0e4663a 100644 --- a/engine/src/contract_methods/connector/internal.rs +++ b/engine/src/contract_methods/connector/internal.rs @@ -826,7 +826,7 @@ impl EthConnectorContract { } /// Return `nETH` balances for accounts (ETH on NEAR). - pub fn ft_balances_of(&mut self, accounts: Vec) { + pub fn ft_balances_of(&self, accounts: Vec) { let mut balances = aurora_engine_types::HashMap::new(); for account_id in accounts { let balance = self.ft.ft_balance_of(&account_id); From 7281e2955ef07bbcb7d07edea57fea7303845362 Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 27 Feb 2024 14:28:56 +0000 Subject: [PATCH 7/7] chore: rollback mutable reference --- engine/src/contract_methods/connector/internal.rs | 2 +- engine/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/src/contract_methods/connector/internal.rs b/engine/src/contract_methods/connector/internal.rs index fa0e4663a..3bfd1e61a 100644 --- a/engine/src/contract_methods/connector/internal.rs +++ b/engine/src/contract_methods/connector/internal.rs @@ -826,7 +826,7 @@ impl EthConnectorContract { } /// Return `nETH` balances for accounts (ETH on NEAR). - pub fn ft_balances_of(&self, accounts: Vec) { + pub fn ft_balances_of(&mut self, accounts: Vec) { let mut balances = aurora_engine_types::HashMap::new(); for account_id in accounts { let balance = self.ft.ft_balance_of(&account_id); diff --git a/engine/src/lib.rs b/engine/src/lib.rs index bd6d51ce2..96319b777 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -251,8 +251,8 @@ mod contract { .sdk_unwrap(); } - /// Returns an unsigned integer where each 1-bit means that a precompile corresponding to that bit is paused and - /// 0-bit means not paused. + /// Returns an unsigned integer where each bit set to 1 means that corresponding precompile + /// to that bit is paused and 0-bit means not paused. #[no_mangle] pub extern "C" fn paused_precompiles() { let io = Runtime;