From 34bea1ee5b39dc53f23e36761f409196ccce3b51 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Thu, 20 May 2021 22:49:55 +0300 Subject: [PATCH 1/7] Added get_accounts_counter & tests --- src/connector.rs | 5 +++++ src/fungible_token.rs | 24 +++++++++++++++++++++++- src/lib.rs | 5 +++++ src/storage.rs | 1 + tests/test_connector.rs | 13 +++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/connector.rs b/src/connector.rs index 6a8559f10..aaa868e1a 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -584,6 +584,11 @@ impl EthConnectorContract { sdk::return_output(0.to_string().as_bytes()); } + /// Get accounts counter for statistics + pub fn get_accounts_counter(&self) { + sdk::return_output(self.ft.get_accounts_counter().to_string().as_bytes()); + } + /// Save eth-connector contract data fn save_ft_contract(&mut self) { sdk::save_contract( diff --git a/src/fungible_token.rs b/src/fungible_token.rs index e97d7550d..53d9906ae 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -434,7 +434,21 @@ impl FungibleToken { } pub fn accounts_insert(&self, account_id: &str, amount: Balance) { - sdk::save_contract(&Self::account_to_key(account_id), &amount) + if self.accounts_contains_key(account_id) { + let key = Self::get_statistic_key(); + sdk::log(&format!("accounts_insert: {}", account_id)); + let accounts_counter = sdk::read_u64(&key) + .unwrap_or(0) + .checked_add(1) + .expect("ERR_ACCOUNTS_COUNTER_OVERFLOW"); + sdk::write_storage(&key, &accounts_counter.to_le_bytes()); + } + sdk::save_contract(&Self::account_to_key(account_id), &amount); + } + + /// Get accounts counter for statistics + pub fn get_accounts_counter(&self) -> u64 { + sdk::read_u64(&Self::get_statistic_key()).unwrap_or(0) } fn accounts_contains_key(&self, account_id: &str) -> bool { @@ -458,4 +472,12 @@ impl FungibleToken { key.extend_from_slice(account_id.as_bytes()); key } + + /// Key for store contract statistics data + fn get_statistic_key() -> Vec { + storage::bytes_to_key( + storage::KeyPrefix::EthConnector, + &[storage::EthConnectorStorageId::Statistic as u8], + ) + } } diff --git a/src/lib.rs b/src/lib.rs index e3054c838..01a24dfc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -447,6 +447,11 @@ mod contract { EthConnectorContract::get_instance().ft_on_transfer(&engine) } + #[no_mangle] + pub extern "C" fn get_accounts_counter() { + EthConnectorContract::get_instance().get_accounts_counter() + } + #[cfg(feature = "integration-test")] #[no_mangle] pub extern "C" fn verify_log_entry() { diff --git a/src/storage.rs b/src/storage.rs index 10dab42bf..19270f107 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -25,6 +25,7 @@ pub enum EthConnectorStorageId { Contract = 0x0, FungibleToken = 0x1, UsedEvent = 0x2, + Statistic = 0x3, } /// We can't use const generic over Enum, but we can do it over integral type diff --git a/tests/test_connector.rs b/tests/test_connector.rs index 34db27ded..5b2ccd133 100644 --- a/tests/test_connector.rs +++ b/tests/test_connector.rs @@ -585,3 +585,16 @@ fn test_ft_transfer_call_fee_greater_than_amount() { let balance = total_supply_eth(&master_account, CONTRACT_ACC); assert_eq!(balance, 0); } + +#[test] +fn test_get_accounts_counter() { + let (master_account, contract) = init(CUSTODIAN_ADDRESS); + call_deposit_near(&contract, CONTRACT_ACC); + + let counter = master_account.view(CONTRACT_ACC.into(), "get_accounts_counter", &[]); + let counter: u128 = String::from_utf8(counter.unwrap()) + .unwrap() + .parse() + .unwrap(); + assert_eq!(counter, 2); +} From 78b9b01d0dbab8a40742e376936ec95fd4a5082d Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Thu, 20 May 2021 22:54:54 +0300 Subject: [PATCH 2/7] Clippy fix --- src/fungible_token.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fungible_token.rs b/src/fungible_token.rs index 53d9906ae..fcfbd44ab 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -436,7 +436,6 @@ impl FungibleToken { pub fn accounts_insert(&self, account_id: &str, amount: Balance) { if self.accounts_contains_key(account_id) { let key = Self::get_statistic_key(); - sdk::log(&format!("accounts_insert: {}", account_id)); let accounts_counter = sdk::read_u64(&key) .unwrap_or(0) .checked_add(1) From e9af627ee459e7fe5cfeb109723499a09490b410 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 21 May 2021 00:32:06 +0300 Subject: [PATCH 3/7] Fixed: check accounts_contains_key & added comments --- src/connector.rs | 3 ++- src/fungible_token.rs | 5 ++++- tests/test_connector.rs | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index aaa868e1a..72cd0a300 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -584,7 +584,8 @@ impl EthConnectorContract { sdk::return_output(0.to_string().as_bytes()); } - /// Get accounts counter for statistics + /// Get accounts counter for statistics. + /// It represents total unique accounts. pub fn get_accounts_counter(&self) { sdk::return_output(self.ft.get_accounts_counter().to_string().as_bytes()); } diff --git a/src/fungible_token.rs b/src/fungible_token.rs index 8bbfeca0c..487ef1268 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -420,8 +420,10 @@ impl FungibleToken { } } + /// Insert account. + /// Calculate total unique accounts pub fn accounts_insert(&self, account_id: &str, amount: Balance) { - if self.accounts_contains_key(account_id) { + if !self.accounts_contains_key(account_id) { let key = Self::get_statistic_key(); let accounts_counter = sdk::read_u64(&key) .unwrap_or(0) @@ -433,6 +435,7 @@ impl FungibleToken { } /// Get accounts counter for statistics + /// It represents total unique accounts. pub fn get_accounts_counter(&self) -> u64 { sdk::read_u64(&Self::get_statistic_key()).unwrap_or(0) } diff --git a/tests/test_connector.rs b/tests/test_connector.rs index 5b2ccd133..35aa05ac4 100644 --- a/tests/test_connector.rs +++ b/tests/test_connector.rs @@ -590,7 +590,7 @@ fn test_ft_transfer_call_fee_greater_than_amount() { fn test_get_accounts_counter() { let (master_account, contract) = init(CUSTODIAN_ADDRESS); call_deposit_near(&contract, CONTRACT_ACC); - + let counter = master_account.view(CONTRACT_ACC.into(), "get_accounts_counter", &[]); let counter: u128 = String::from_utf8(counter.unwrap()) .unwrap() From aadbec6360d3ec8169be0ddbfa5e076ec332773b Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 21 May 2021 00:33:30 +0300 Subject: [PATCH 4/7] Lint: cargo fmt --- src/fungible_token.rs | 2 +- tests/test_connector.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fungible_token.rs b/src/fungible_token.rs index 487ef1268..d518f629c 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -421,7 +421,7 @@ impl FungibleToken { } /// Insert account. - /// Calculate total unique accounts + /// Calculate total unique accounts pub fn accounts_insert(&self, account_id: &str, amount: Balance) { if !self.accounts_contains_key(account_id) { let key = Self::get_statistic_key(); diff --git a/tests/test_connector.rs b/tests/test_connector.rs index 35aa05ac4..5b2ccd133 100644 --- a/tests/test_connector.rs +++ b/tests/test_connector.rs @@ -590,7 +590,7 @@ fn test_ft_transfer_call_fee_greater_than_amount() { fn test_get_accounts_counter() { let (master_account, contract) = init(CUSTODIAN_ADDRESS); call_deposit_near(&contract, CONTRACT_ACC); - + let counter = master_account.view(CONTRACT_ACC.into(), "get_accounts_counter", &[]); let counter: u128 = String::from_utf8(counter.unwrap()) .unwrap() From 454f937f8b304915caf795f68c401b215ae5f2ec Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 21 May 2021 13:05:36 +0300 Subject: [PATCH 5/7] Chanched key for Statistics --- src/fungible_token.rs | 2 +- src/storage.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fungible_token.rs b/src/fungible_token.rs index d518f629c..d70a96337 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -466,7 +466,7 @@ impl FungibleToken { fn get_statistic_key() -> Vec { storage::bytes_to_key( storage::KeyPrefix::EthConnector, - &[storage::EthConnectorStorageId::Statistic as u8], + &[storage::EthConnectorStorageId::StatisticsAuroraAccountsCounter as u8], ) } } diff --git a/src/storage.rs b/src/storage.rs index 19270f107..a0e53c89b 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -25,7 +25,7 @@ pub enum EthConnectorStorageId { Contract = 0x0, FungibleToken = 0x1, UsedEvent = 0x2, - Statistic = 0x3, + StatisticsAuroraAccountsCounter = 0x3, } /// We can't use const generic over Enum, but we can do it over integral type From 9427dcfb7bf2ed61329d1fba8b2fe91536b35d2f Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 23 May 2021 23:06:42 +0300 Subject: [PATCH 6/7] Update src/connector.rs Imptove comments Co-authored-by: Michael Birch --- src/connector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connector.rs b/src/connector.rs index f406bc43d..0829a761a 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -583,7 +583,7 @@ impl EthConnectorContract { } /// Get accounts counter for statistics. - /// It represents total unique accounts. + /// It represents total unique accounts (all-time, including accounts which now have zero balance). pub fn get_accounts_counter(&self) { sdk::return_output(self.ft.get_accounts_counter().to_string().as_bytes()); } From 49780be02b6b41bc72e503f0826ec6f26107a5fe Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 24 May 2021 12:58:45 +0300 Subject: [PATCH 7/7] Changed: - get_accounts_counter - return le_bytes Added: - test_get_accounts_counter_and_transfer - check recalculation accounts --- src/connector.rs | 2 +- tests/test_connector.rs | 58 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 0829a761a..a675fb8f7 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -585,7 +585,7 @@ impl EthConnectorContract { /// Get accounts counter for statistics. /// It represents total unique accounts (all-time, including accounts which now have zero balance). pub fn get_accounts_counter(&self) { - sdk::return_output(self.ft.get_accounts_counter().to_string().as_bytes()); + sdk::return_output(&self.ft.get_accounts_counter().to_le_bytes()); } /// Save eth-connector contract data diff --git a/tests/test_connector.rs b/tests/test_connector.rs index 5b2ccd133..922eacb05 100644 --- a/tests/test_connector.rs +++ b/tests/test_connector.rs @@ -591,10 +591,58 @@ fn test_get_accounts_counter() { let (master_account, contract) = init(CUSTODIAN_ADDRESS); call_deposit_near(&contract, CONTRACT_ACC); - let counter = master_account.view(CONTRACT_ACC.into(), "get_accounts_counter", &[]); - let counter: u128 = String::from_utf8(counter.unwrap()) - .unwrap() - .parse() + let counter = master_account + .view(CONTRACT_ACC.into(), "get_accounts_counter", &[]) + .unwrap(); + assert_eq!(u64::try_from_slice(&counter[..]).unwrap(), 2); +} + +#[test] +fn test_get_accounts_counter_and_transfer() { + let (master_account, contract) = init(CUSTODIAN_ADDRESS); + call_deposit_near(&contract, CONTRACT_ACC); + + let counter = master_account + .view(CONTRACT_ACC.into(), "get_accounts_counter", &[]) + .unwrap(); + assert_eq!(u64::try_from_slice(&counter[..]).unwrap(), 2); + + let transfer_amount = 70; + let res = contract.call( + CONTRACT_ACC.to_string(), + "ft_transfer", + json!({ + "receiver_id": DEPOSITED_RECIPIENT, + "amount": transfer_amount, + "memo": "transfer memo" + }) + .to_string() + .as_bytes(), + DEFAULT_GAS, + 1, + ); + res.assert_success(); + + let balance = get_near_balance(&master_account, DEPOSITED_RECIPIENT, CONTRACT_ACC); + assert_eq!( + balance, + DEPOSITED_AMOUNT - DEPOSITED_FEE + transfer_amount as u128 + ); + + let balance = get_near_balance(&master_account, CONTRACT_ACC, CONTRACT_ACC); + assert_eq!(balance, DEPOSITED_FEE - transfer_amount as u128); + + let balance = total_supply(&master_account, CONTRACT_ACC); + assert_eq!(balance, DEPOSITED_EVM_AMOUNT); + + let balance = total_supply_eth(&master_account, CONTRACT_ACC); + assert_eq!(balance, 0); + + let balance = total_supply_near(&master_account, CONTRACT_ACC); + assert_eq!(balance, DEPOSITED_AMOUNT); + + let counter = master_account + .view(CONTRACT_ACC.into(), "get_accounts_counter", &[]) .unwrap(); - assert_eq!(counter, 2); + assert_eq!(u64::try_from_slice(&counter[..]).unwrap(), 2); }