From 9e8ad7ba6d2fdb7a76380626bc6a3eb35481e498 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 28 Nov 2022 22:50:47 +0100 Subject: [PATCH 01/44] Added near-standaed NEP141 - and basic refactoring --- Cargo.lock | 15 +- eth-connector/Cargo.toml | 5 +- eth-connector/src/connector_impl.rs | 158 +++++++++++++++- eth-connector/src/lib.rs | 276 ++++++---------------------- eth-connector/src/migration.rs | 11 +- 5 files changed, 233 insertions(+), 232 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7cf7c7..ab3134f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,8 +200,9 @@ dependencies = [ "byte-slice-cast", "ethabi", "hex 0.4.3", + "near-contract-standards", "near-sdk", - "rand 0.7.3", + "rand 0.8.5", "rlp", "serde", "serde_json", @@ -1550,6 +1551,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "near-contract-standards" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bacc932e79b26472797adfb21689294b6f90960d1570daaf1e0b682b59fcb35" +dependencies = [ + "near-sdk", + "schemars", + "serde", + "serde_json", +] + [[package]] name = "near-crypto" version = "0.5.0" diff --git a/eth-connector/Cargo.toml b/eth-connector/Cargo.toml index 632a793..04877dc 100644 --- a/eth-connector/Cargo.toml +++ b/eth-connector/Cargo.toml @@ -16,7 +16,8 @@ autobenches = false crate-type = ["cdylib", "rlib"] [dependencies] -near-sdk = "4.0.0" +near-sdk = "4.1" +near-contract-standards = "4.1" aurora-engine-types = { git = "https://github.com/aurora-is-near/aurora-engine.git", branch = "develop", default-features = false, features = ["impl-serde"] } serde = "1" serde_json = "1" @@ -26,7 +27,7 @@ byte-slice-cast = "1.0" ethabi = { version = "17.1", default-features = false } [dev-dependencies] -rand = "0.7.3" +rand = "0.8.5" [features] log = [] diff --git a/eth-connector/src/connector_impl.rs b/eth-connector/src/connector_impl.rs index bb38afd..2f08e2c 100644 --- a/eth-connector/src/connector_impl.rs +++ b/eth-connector/src/connector_impl.rs @@ -1,4 +1,3 @@ -use crate::fungible_token::core_impl::error::FtDepositError; use crate::{ admin_controlled::PAUSE_DEPOSIT, connector::{ext_funds_finish, ext_proof_verifier, ConnectorDeposit}, @@ -111,11 +110,11 @@ impl ConnectorDeposit for EthConnector { ); if event.eth_custodian_address != self.eth_custodian_address { - panic_err(FtDepositError::CustodianAddressMismatch); + panic_err(error::FtDepositError::CustodianAddressMismatch); } if NEP141Wei::new(event.fee.as_u128()) >= event.amount { - panic_err(FtDepositError::InsufficientAmountForFee); + panic_err(error::FtDepositError::InsufficientAmountForFee); } // Verify proof data with cross-contract call to prover account @@ -180,3 +179,156 @@ impl ConnectorDeposit for EthConnector { ) } } + +pub mod error { + use crate::deposit_event::error::ParseOnTransferMessageError; + use crate::errors::{ + ERR_BALANCE_OVERFLOW, ERR_NOT_ENOUGH_BALANCE, ERR_NOT_ENOUGH_BALANCE_FOR_FEE, + ERR_PROOF_EXIST, ERR_SENDER_EQUALS_RECEIVER, ERR_TOTAL_SUPPLY_OVERFLOW, + ERR_TOTAL_SUPPLY_UNDERFLOW, ERR_WRONG_EVENT_ADDRESS, ERR_ZERO_AMOUNT, + }; + use aurora_engine_types::types::balance::error::BalanceOverflowError; + use aurora_engine_types::types::ERR_FAILED_PARSE; + + pub struct ProofUsed; + + impl AsRef<[u8]> for ProofUsed { + fn as_ref(&self) -> &[u8] { + ERR_PROOF_EXIST + } + } + + #[derive(Debug)] + pub enum DepositError { + TotalSupplyOverflow, + BalanceOverflow, + } + + impl AsRef<[u8]> for DepositError { + fn as_ref(&self) -> &[u8] { + match self { + Self::TotalSupplyOverflow => ERR_TOTAL_SUPPLY_OVERFLOW.as_bytes(), + Self::BalanceOverflow => ERR_BALANCE_OVERFLOW, + } + } + } + + impl From for TransferError { + fn from(err: DepositError) -> Self { + match err { + DepositError::BalanceOverflow => Self::BalanceOverflow, + DepositError::TotalSupplyOverflow => Self::TotalSupplyOverflow, + } + } + } + + pub enum FtDepositError { + ProofParseFailed, + CustodianAddressMismatch, + InsufficientAmountForFee, + } + + impl AsRef<[u8]> for FtDepositError { + fn as_ref(&self) -> &[u8] { + match self { + Self::ProofParseFailed => ERR_FAILED_PARSE.as_bytes(), + Self::CustodianAddressMismatch => ERR_WRONG_EVENT_ADDRESS, + Self::InsufficientAmountForFee => ERR_NOT_ENOUGH_BALANCE_FOR_FEE.as_bytes(), + } + } + } + + #[derive(Debug)] + pub enum WithdrawError { + TotalSupplyUnderflow, + InsufficientFunds, + BalanceOverflow(BalanceOverflowError), + } + + impl AsRef<[u8]> for WithdrawError { + fn as_ref(&self) -> &[u8] { + match self { + Self::TotalSupplyUnderflow => ERR_TOTAL_SUPPLY_UNDERFLOW, + Self::InsufficientFunds => ERR_NOT_ENOUGH_BALANCE, + Self::BalanceOverflow(e) => e.as_ref(), + } + } + } + + impl From for TransferError { + fn from(err: WithdrawError) -> Self { + match err { + WithdrawError::InsufficientFunds => Self::InsufficientFunds, + WithdrawError::TotalSupplyUnderflow => Self::TotalSupplyUnderflow, + WithdrawError::BalanceOverflow(_) => Self::BalanceOverflow, + } + } + } + + pub enum FinishDepositError { + TransferCall(FtTransferCallError), + ProofUsed, + } + + impl From for FtTransferCallError { + fn from(e: DepositError) -> Self { + Self::Transfer(e.into()) + } + } + + impl From for FtTransferCallError { + fn from(e: ParseOnTransferMessageError) -> Self { + Self::MessageParseFailed(e) + } + } + + impl AsRef<[u8]> for FinishDepositError { + fn as_ref(&self) -> &[u8] { + match self { + Self::ProofUsed => ERR_PROOF_EXIST, + Self::TransferCall(e) => e.as_ref(), + } + } + } + + pub enum FtTransferCallError { + BalanceOverflow(BalanceOverflowError), + MessageParseFailed(ParseOnTransferMessageError), + InsufficientAmountForFee, + Transfer(TransferError), + } + + impl AsRef<[u8]> for FtTransferCallError { + fn as_ref(&self) -> &[u8] { + match self { + Self::MessageParseFailed(e) => e.as_ref(), + Self::InsufficientAmountForFee => ERR_NOT_ENOUGH_BALANCE_FOR_FEE.as_bytes(), + Self::Transfer(e) => e.as_ref(), + Self::BalanceOverflow(e) => e.as_ref(), + } + } + } + + #[derive(Debug)] + pub enum TransferError { + TotalSupplyUnderflow, + TotalSupplyOverflow, + InsufficientFunds, + BalanceOverflow, + ZeroAmount, + SelfTransfer, + } + + impl AsRef<[u8]> for TransferError { + fn as_ref(&self) -> &[u8] { + match self { + Self::TotalSupplyUnderflow => ERR_TOTAL_SUPPLY_UNDERFLOW, + Self::TotalSupplyOverflow => ERR_TOTAL_SUPPLY_OVERFLOW.as_bytes(), + Self::InsufficientFunds => ERR_NOT_ENOUGH_BALANCE, + Self::BalanceOverflow => ERR_BALANCE_OVERFLOW, + Self::ZeroAmount => ERR_ZERO_AMOUNT, + Self::SelfTransfer => ERR_SENDER_EQUALS_RECEIVER, + } + } + } +} diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index bb2d491..1c6e702 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -1,8 +1,7 @@ use crate::admin_controlled::{AdminControlled, PausedMask, PAUSE_WITHDRAW, UNPAUSE_ALL}; -use crate::connector::{ConnectorDeposit, ConnectorFundsFinish, ConnectorWithdraw}; -use crate::connector_impl::{ - EthConnector, FinishDepositCallArgs, TransferCallCallArgs, WithdrawResult, -}; +use crate::connector::{ConnectorDeposit, ConnectorWithdraw}; +use crate::connector_impl::{EthConnector, WithdrawResult}; +/* use crate::fungible_token::engine::EngineFungibleToken; use crate::fungible_token::{ core::FungibleTokenCore, @@ -12,15 +11,20 @@ use crate::fungible_token::{ statistic::FungibleTokeStatistic, storage_management::{StorageBalance, StorageBalanceBounds, StorageManagement}, }; +*/ use crate::proof::Proof; use crate::types::{panic_err, SdkUnwrap}; -use aurora_engine_types::types::{Address, NEP141Wei, ZERO_NEP141_WEI}; +use aurora_engine_types::types::{Address, NEP141Wei}; +use near_contract_standards::fungible_token::metadata::{ + FungibleTokenMetadata, FungibleTokenMetadataProvider, +}; +use near_contract_standards::fungible_token::FungibleToken; use near_sdk::{ assert_one_yocto, borsh::{self, BorshDeserialize, BorshSerialize}, collections::LazyOption, env, - json_types::{U128, U64}, + json_types::U128, near_bindgen, require, AccountId, BorshStorageKey, PanicOnDefault, Promise, PromiseOrValue, }; @@ -29,7 +33,7 @@ pub mod connector; pub mod connector_impl; pub mod deposit_event; pub mod errors; -pub mod fungible_token; +// pub mod fungible_token; pub mod log_entry; pub mod migration; pub mod proof; @@ -51,8 +55,8 @@ pub struct EthConnectorContract { #[derive(BorshSerialize, BorshStorageKey)] enum StorageKey { - FungibleTokenEth = 0x1, - Proof = 0x2, + // FungibleTokenEth = 0x1, + // Proof = 0x2, Metadata = 0x3, } @@ -78,27 +82,19 @@ impl EthConnectorContract { }; let owner_id = env::current_account_id(); let mut this = Self { - ft: FungibleToken::new(StorageKey::FungibleTokenEth, StorageKey::Proof), + ft: FungibleToken::new(b"t".to_vec()), connector: connector_data, metadata: LazyOption::new(StorageKey::Metadata, Some(&metadata)), }; - this.ft.accounts_insert(&owner_id, ZERO_NEP141_WEI); + // TODO + this.ft.accounts.insert(&owner_id, &0); this } - #[cfg_attr(not(feature = "log"), allow(unused_variables))] - fn on_account_closed(&self, _account_id: AccountId, _balance: NEP141Wei) { - crate::log!("Closed @{} with {}", _account_id, _balance); - } - - #[cfg_attr(not(feature = "log"), allow(unused_variables))] - fn on_tokens_burned(&self, account_id: AccountId, amount: NEP141Wei) { - crate::log!("Account @{} burned {}", account_id, amount); - } - #[result_serializer(borsh)] - pub fn is_used_proof(&self, #[serializer(borsh)] proof: Proof) -> bool { - self.ft.is_used_event(&proof.get_key()) + pub fn is_used_proof(&self, #[serializer(borsh)] _proof: Proof) -> bool { + // self.ft.is_used_event(&proof.get_key()) + true } #[cfg(feature = "integration-test")] @@ -113,190 +109,25 @@ impl EthConnectorContract { } } -#[near_bindgen] -impl EngineFungibleToken for EthConnectorContract { - #[payable] - fn engine_ft_transfer( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - memo: Option, - ) { - self.assert_access_right().sdk_unwrap(); - self.ft - .engine_ft_transfer(sender_id, receiver_id, amount, memo) - } - - #[payable] - fn engine_ft_transfer_call( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue { - self.assert_access_right().sdk_unwrap(); - assert_one_yocto(); - self.ft - .engine_ft_transfer_call(sender_id, receiver_id, amount, memo, msg) - } - - #[payable] - fn engine_storage_deposit( - &mut self, - sender_id: AccountId, - account_id: Option, - registration_only: Option, - ) -> StorageBalance { - self.assert_access_right().sdk_unwrap(); - self.ft - .engine_storage_deposit(sender_id, account_id, registration_only) - } - - #[payable] - fn engine_storage_withdraw( - &mut self, - sender_id: AccountId, - amount: Option, - ) -> StorageBalance { - self.assert_access_right().sdk_unwrap(); - self.ft.engine_storage_withdraw(sender_id, amount) - } - - #[payable] - fn engine_storage_unregister(&mut self, sender_id: AccountId, force: Option) -> bool { - self.assert_access_right().sdk_unwrap(); - if let Some((account_id, balance)) = self.ft.internal_storage_unregister(sender_id, force) { - self.on_account_closed(account_id, balance); - true - } else { - false - } - } -} - -#[near_bindgen] -impl FungibleTokenCore for EthConnectorContract { - #[payable] - fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option) { - self.assert_access_right().sdk_unwrap(); - self.ft.ft_transfer(receiver_id, amount, memo) - } - - #[payable] - fn ft_transfer_call( - &mut self, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue { - self.assert_access_right().sdk_unwrap(); - assert_one_yocto(); - self.ft.ft_transfer_call(receiver_id, amount, memo, msg) - } - - fn ft_total_supply(&self) -> U128 { - self.ft.ft_total_supply() - } - - fn ft_balance_of(&self, account_id: AccountId) -> U128 { - self.ft.ft_balance_of(account_id) - } - - fn ft_total_eth_supply_on_near(&self) -> U128 { - log!( - "Total ETH supply on NEAR: {}", - self.ft.ft_total_eth_supply_on_near().0 - ); - self.ft.ft_total_eth_supply_on_near() - } -} - -#[near_bindgen] -impl FungibleTokenResolver for EthConnectorContract { - #[private] - fn ft_resolve_transfer( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - ) -> U128 { - let (used_amount, burned_amount) = self.ft.internal_ft_resolve_transfer( - &sender_id, - &receiver_id, - NEP141Wei::new(amount.0), - ); - if burned_amount > ZERO_NEP141_WEI { - self.on_tokens_burned(sender_id.clone(), burned_amount); - } - log!( - "Resolve transfer from {} to {}, used token amount {:?} success", - sender_id, - receiver_id, - used_amount.as_u128() - ); - used_amount.as_u128().into() - } -} - -#[near_bindgen] -impl StorageManagement for EthConnectorContract { - #[payable] - fn storage_deposit( - &mut self, - account_id: Option, - registration_only: Option, - ) -> StorageBalance { - self.assert_access_right().sdk_unwrap(); - self.ft.storage_deposit(account_id, registration_only) - } - - #[payable] - fn storage_withdraw(&mut self, amount: Option) -> StorageBalance { - self.assert_access_right().sdk_unwrap(); - self.ft.storage_withdraw(amount) - } - - #[payable] - fn storage_unregister(&mut self, force: Option) -> bool { - self.assert_access_right().sdk_unwrap(); - if let Some((account_id, balance)) = self - .ft - .internal_storage_unregister(env::predecessor_account_id(), force) - { - self.on_account_closed(account_id, balance); - true - } else { - false - } - } - - fn storage_balance_bounds(&self) -> StorageBalanceBounds { - self.ft.storage_balance_bounds() - } - - fn storage_balance_of(&self, account_id: AccountId) -> StorageBalance { - self.ft.storage_balance_of(account_id) - } -} +near_contract_standards::impl_fungible_token_core!(EthConnectorContract, ft); +near_contract_standards::impl_fungible_token_storage!(EthConnectorContract, ft); #[near_bindgen] impl FungibleTokenMetadataProvider for EthConnectorContract { fn ft_metadata(&self) -> FungibleTokenMetadata { - self.metadata.get().unwrap_or_default() + // TODO + self.metadata.get().sdk_unwrap() } } +/* #[near_bindgen] impl FungibleTokeStatistic for EthConnectorContract { #[result_serializer(borsh)] fn get_accounts_counter(&self) -> U64 { self.ft.get_accounts_counter() } -} +}*/ #[near_bindgen] impl AdminControlled for EthConnectorContract { @@ -326,7 +157,7 @@ impl ConnectorWithdraw for EthConnectorContract { #[result_serializer(borsh)] fn withdraw( &mut self, - #[serializer(borsh)] sender_id: AccountId, + #[serializer(borsh)] _sender_id: AccountId, #[serializer(borsh)] recipient_address: Address, #[serializer(borsh)] amount: NEP141Wei, ) -> WithdrawResult { @@ -341,9 +172,9 @@ impl ConnectorWithdraw for EthConnectorContract { .map_err(|_| "WithdrawErrorPaused") .sdk_unwrap(); // Burn tokens to recipient - self.ft - .internal_withdraw_eth_from_near(&sender_id, amount) - .sdk_unwrap(); + // self.ft + // .internal_withdraw_eth_from_near(&sender_id, amount) + // .sdk_unwrap(); WithdrawResult { recipient_id: recipient_address, amount, @@ -359,7 +190,7 @@ impl ConnectorDeposit for EthConnectorContract { self.connector.deposit(raw_proof) } } - +/* #[near_bindgen] impl ConnectorFundsFinish for EthConnectorContract { #[private] @@ -418,6 +249,7 @@ impl ConnectorFundsFinish for EthConnectorContract { } } } +*/ #[cfg(feature = "migration")] use crate::migration::{Migration, MigrationCheckResult, MigrationInputData}; @@ -430,16 +262,16 @@ impl Migration for EthConnectorContract { fn migrate(&mut self, #[serializer(borsh)] data: MigrationInputData) { // Insert account for (account, amount) in &data.accounts_eth { - self.ft.accounts_eth.insert(account, amount); + self.ft.accounts.insert(account, amount); } crate::log!("Inserted accounts_eth: {:?}", data.accounts_eth.len()); // Insert total_eth_supply_on_near if let Some(total_eth_supply_on_near) = data.total_eth_supply_on_near { - self.ft.total_eth_supply_on_near = total_eth_supply_on_near; + self.ft.total_supply = total_eth_supply_on_near; crate::log!( "Inserted total_eth_supply_on_near: {:?}", - total_eth_supply_on_near.as_u128() + total_eth_supply_on_near ); } @@ -454,7 +286,8 @@ impl Migration for EthConnectorContract { // Insert statistics_aurora_accounts_counter if let Some(statistics_aurora_accounts_counter) = data.statistics_aurora_accounts_counter { - self.ft.statistics_aurora_accounts_counter = statistics_aurora_accounts_counter; + // TODO: + //self.ft.statistics_aurora_accounts_counter = statistics_aurora_accounts_counter; crate::log!( "Inserted statistics_aurora_accounts_counter: {:?}", statistics_aurora_accounts_counter @@ -462,8 +295,9 @@ impl Migration for EthConnectorContract { } // Insert Proof - for proof_key in &data.used_proofs { - self.ft.used_proofs.insert(proof_key, &true); + for _proof_key in &data.used_proofs { + // TODO + //self.ft.used_proofs.insert(proof_key, &true); } crate::log!("Inserted used_proofs: {:?}", data.used_proofs.len()); } @@ -475,7 +309,7 @@ impl Migration for EthConnectorContract { ) -> MigrationCheckResult { // Check accounts for (account, amount) in &data.accounts_eth { - match self.ft.accounts_eth.get(account) { + match self.ft.accounts.get(account) { Some(ref value) => { if value != amount { return MigrationCheckResult::AccountAmount((account.clone(), *value)); @@ -486,11 +320,12 @@ impl Migration for EthConnectorContract { } // Check proofs - for proof in &data.used_proofs { - match self.ft.used_proofs.get(proof) { - Some(_) => (), - _ => return MigrationCheckResult::Proof(proof.clone()), - } + for _proof in &data.used_proofs { + // TODO + // match self.ft.used_proofs.get(proof) { + // Some(_) => (), + // _ => return MigrationCheckResult::Proof(proof.clone()), + // } } if let Some(account_storage_usage) = data.account_storage_usage { @@ -499,17 +334,18 @@ impl Migration for EthConnectorContract { } } if let Some(total_eth_supply_on_near) = data.total_eth_supply_on_near { - if self.ft.total_eth_supply_on_near != total_eth_supply_on_near { - return MigrationCheckResult::TotalSupply(self.ft.total_eth_supply_on_near); - } - } - if let Some(statistics_aurora_accounts_counter) = data.statistics_aurora_accounts_counter { - if self.ft.statistics_aurora_accounts_counter != statistics_aurora_accounts_counter { - return MigrationCheckResult::StatisticsCounter( - self.ft.statistics_aurora_accounts_counter, - ); + if self.ft.total_supply != total_eth_supply_on_near { + return MigrationCheckResult::TotalSupply(self.ft.total_supply); } } + // TODO + // if let Some(statistics_aurora_accounts_counter) = data.statistics_aurora_accounts_counter { + // if self.ft.statistics_aurora_accounts_counter != statistics_aurora_accounts_counter { + // return MigrationCheckResult::StatisticsCounter( + // self.ft.statistics_aurora_accounts_counter, + // ); + // } + // } MigrationCheckResult::Success } } diff --git a/eth-connector/src/migration.rs b/eth-connector/src/migration.rs index 53d8a5a..f504662 100644 --- a/eth-connector/src/migration.rs +++ b/eth-connector/src/migration.rs @@ -1,12 +1,11 @@ -use aurora_engine_types::types::NEP141Wei; use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize}; -use near_sdk::{ext_contract, AccountId, StorageUsage}; +use near_sdk::{ext_contract, AccountId, Balance, StorageUsage}; use std::collections::HashMap; #[derive(BorshDeserialize, BorshSerialize)] pub struct MigrationInputData { - pub accounts_eth: HashMap, - pub total_eth_supply_on_near: Option, + pub accounts_eth: HashMap, + pub total_eth_supply_on_near: Option, pub account_storage_usage: Option, pub statistics_aurora_accounts_counter: Option, pub used_proofs: Vec, @@ -16,8 +15,8 @@ pub struct MigrationInputData { pub enum MigrationCheckResult { Success, AccountNotExist(AccountId), - AccountAmount((AccountId, NEP141Wei)), - TotalSupply(NEP141Wei), + AccountAmount((AccountId, Balance)), + TotalSupply(Balance), StorageUsage(StorageUsage), StatisticsCounter(u64), Proof(String), From d27e775424c2f45bf2b886a41023089b69737040 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 28 Nov 2022 23:47:29 +0100 Subject: [PATCH 02/44] Refactored Finish Deposit --- eth-connector/src/connector_impl.rs | 8 ++-- eth-connector/src/deposit_event.rs | 5 +-- eth-connector/src/lib.rs | 62 +++++++++++++++-------------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/eth-connector/src/connector_impl.rs b/eth-connector/src/connector_impl.rs index 2f08e2c..2718f50 100644 --- a/eth-connector/src/connector_impl.rs +++ b/eth-connector/src/connector_impl.rs @@ -10,7 +10,7 @@ use crate::{ use aurora_engine_types::types::{Address, Fee, NEP141Wei}; use near_sdk::{ borsh::{self, BorshDeserialize, BorshSerialize}, - env, AccountId, Gas, Promise, + env, AccountId, Balance, Gas, Promise, }; /// NEAR Gas for calling `fininsh_deposit` promise. Used in the `deposit` logic. @@ -23,7 +23,7 @@ const GAS_FOR_VERIFY_LOG_ENTRY: Gas = Gas(40_000_000_000_000); #[derive(Debug, Clone, BorshSerialize, BorshDeserialize, PartialEq, Eq)] pub struct TransferCallCallArgs { pub receiver_id: AccountId, - pub amount: NEP141Wei, + pub amount: Balance, pub memo: Option, pub msg: String, } @@ -32,7 +32,7 @@ pub struct TransferCallCallArgs { #[derive(Debug, Clone, BorshSerialize, BorshDeserialize, PartialEq, Eq)] pub struct FinishDepositCallArgs { pub new_owner_id: AccountId, - pub amount: NEP141Wei, + pub amount: Balance, pub proof_key: String, pub relayer_id: AccountId, pub fee: Fee, @@ -113,7 +113,7 @@ impl ConnectorDeposit for EthConnector { panic_err(error::FtDepositError::CustodianAddressMismatch); } - if NEP141Wei::new(event.fee.as_u128()) >= event.amount { + if event.fee.as_u128() >= event.amount { panic_err(error::FtDepositError::InsufficientAmountForFee); } diff --git a/eth-connector/src/deposit_event.rs b/eth-connector/src/deposit_event.rs index 589375c..101496a 100644 --- a/eth-connector/src/deposit_event.rs +++ b/eth-connector/src/deposit_event.rs @@ -7,7 +7,7 @@ use byte_slice_cast::AsByteSlice; use ethabi::{Event, EventParam, Hash, Log, ParamType, RawLog}; use near_sdk::{ borsh::{self, BorshDeserialize, BorshSerialize}, - AccountId, + AccountId, Balance, }; pub const DEPOSITED_EVENT: &str = "Deposited"; @@ -222,7 +222,7 @@ pub struct DepositedEvent { pub eth_custodian_address: Address, pub sender: Address, pub token_message_data: TokenMessageData, - pub amount: NEP141Wei, + pub amount: Balance, pub fee: Fee, } @@ -274,7 +274,6 @@ impl DepositedEvent { .into_uint() .ok_or(error::ParseError::InvalidAmount)? .try_into() - .map(NEP141Wei::new) .map_err(|_| error::ParseError::OverflowNumber)?; let fee = event.log.params[3] .value diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 1c6e702..0ffd212 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -1,6 +1,8 @@ use crate::admin_controlled::{AdminControlled, PausedMask, PAUSE_WITHDRAW, UNPAUSE_ALL}; -use crate::connector::{ConnectorDeposit, ConnectorWithdraw}; -use crate::connector_impl::{EthConnector, WithdrawResult}; +use crate::connector::{ConnectorDeposit, ConnectorFundsFinish, ConnectorWithdraw}; +use crate::connector_impl::{ + EthConnector, FinishDepositCallArgs, TransferCallCallArgs, WithdrawResult, +}; /* use crate::fungible_token::engine::EngineFungibleToken; use crate::fungible_token::{ @@ -25,7 +27,8 @@ use near_sdk::{ collections::LazyOption, env, json_types::U128, - near_bindgen, require, AccountId, BorshStorageKey, PanicOnDefault, Promise, PromiseOrValue, + near_bindgen, require, AccountId, Balance, BorshStorageKey, PanicOnDefault, Promise, + PromiseOrValue, }; pub mod admin_controlled; @@ -60,6 +63,18 @@ enum StorageKey { Metadata = 0x3, } +impl EthConnectorContract { + /// Mint nETH tokens + pub fn mint_eth_on_near(&mut self, owner_id: AccountId, amount: Balance) { + crate::log!("Mint {} nETH tokens for: {}", amount, owner_id); + // Create account to avoid panic with deposit + if self.ft.accounts.get(&owner_id).is_none() { + self.ft.accounts.insert(&owner_id, &0); + } + self.ft.internal_deposit(&owner_id, amount) + } +} + #[near_bindgen] impl EthConnectorContract { #[init] @@ -100,7 +115,7 @@ impl EthConnectorContract { #[cfg(feature = "integration-test")] #[result_serializer(borsh)] pub fn verify_log_entry() -> bool { - log!("Call from verify_log_entry"); + crate::log!("Call from verify_log_entry"); true } @@ -190,7 +205,7 @@ impl ConnectorDeposit for EthConnectorContract { self.connector.deposit(raw_proof) } } -/* + #[near_bindgen] impl ConnectorFundsFinish for EthConnectorContract { #[private] @@ -205,51 +220,38 @@ impl ConnectorFundsFinish for EthConnectorContract { panic_err(errors::ERR_VERIFY_PROOF); } - log!("Finish deposit with the amount: {}", deposit_call.amount); + crate::log!("Finish deposit with the amount: {}", deposit_call.amount); // Mint tokens to recipient minus fee if let Some(msg) = deposit_call.msg { // Mint - calculate new balances - self.ft - .mint_eth_on_near(deposit_call.new_owner_id, deposit_call.amount) - .sdk_unwrap(); + self.mint_eth_on_near(deposit_call.new_owner_id, deposit_call.amount); // Store proof only after `mint` calculations - self.ft.record_proof(&deposit_call.proof_key).sdk_unwrap(); + //self.ft.record_proof(&deposit_call.proof_key).sdk_unwrap(); let data: TransferCallCallArgs = TransferCallCallArgs::try_from_slice(&msg) .map_err(|_| crate::errors::ERR_BORSH_DESERIALIZE) .sdk_unwrap(); - let promise = self.ft.ft_transfer_call( - data.receiver_id, - data.amount.as_u128().into(), - data.memo, - data.msg, - ); + let promise = + self.ft + .ft_transfer_call(data.receiver_id, data.amount.into(), data.memo, data.msg); match promise { PromiseOrValue::Promise(p) => PromiseOrValue::Promise(p), PromiseOrValue::Value(v) => PromiseOrValue::Value(Some(v)), } } else { // Mint - calculate new balances - self.ft - .mint_eth_on_near( - deposit_call.new_owner_id.clone(), - deposit_call.amount - NEP141Wei::new(deposit_call.fee.as_u128()), - ) - .sdk_unwrap(); - self.ft - .mint_eth_on_near( - deposit_call.relayer_id, - NEP141Wei::new(deposit_call.fee.as_u128()), - ) - .sdk_unwrap(); + self.mint_eth_on_near( + deposit_call.new_owner_id.clone(), + deposit_call.amount - deposit_call.fee.as_u128(), + ); + self.mint_eth_on_near(deposit_call.relayer_id, deposit_call.fee.as_u128()); // Store proof only after `mint` calculations - self.ft.record_proof(&deposit_call.proof_key).sdk_unwrap(); + //self.ft.record_proof(&deposit_call.proof_key).sdk_unwrap(); PromiseOrValue::Value(None) } } } -*/ #[cfg(feature = "migration")] use crate::migration::{Migration, MigrationCheckResult, MigrationInputData}; From 4ae6c43055878ca1705dd2d58d5604a493df96f2 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 29 Nov 2022 00:11:16 +0100 Subject: [PATCH 03/44] Refactor record proof --- eth-connector/src/errors.rs | 8 ++++++ eth-connector/src/lib.rs | 51 ++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/eth-connector/src/errors.rs b/eth-connector/src/errors.rs index 9cbee3b..17549e1 100644 --- a/eth-connector/src/errors.rs +++ b/eth-connector/src/errors.rs @@ -95,3 +95,11 @@ pub const ERR_MORE_GAS_REQUIRED: &str = "ERR_MORE_GAS_REQUIRED"; pub const ERR_PREPAID_GAS_OVERFLOW: &str = "ERR_PREPAID_GAS_OVERFLOW"; pub const ERR_RECEIVER_BALANCE_NOT_ENOUGH: &str = "ERR__RECEIVER_BALANCE_NOT_ENOUGH"; pub const ERR_USED_AMOUNT_OVERFLOW: &str = "ERR_USED_AMOUNT_OVERFLOW"; + +pub struct ProofUsed; + +impl AsRef<[u8]> for ProofUsed { + fn as_ref(&self) -> &[u8] { + ERR_PROOF_EXIST + } +} diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 0ffd212..78b8da7 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -21,6 +21,7 @@ use near_contract_standards::fungible_token::metadata::{ FungibleTokenMetadata, FungibleTokenMetadataProvider, }; use near_contract_standards::fungible_token::FungibleToken; +use near_sdk::store::LookupMap; use near_sdk::{ assert_one_yocto, borsh::{self, BorshDeserialize, BorshSerialize}, @@ -54,13 +55,13 @@ pub struct EthConnectorContract { connector: EthConnector, ft: FungibleToken, metadata: LazyOption, + used_proofs: LookupMap, } #[derive(BorshSerialize, BorshStorageKey)] enum StorageKey { - // FungibleTokenEth = 0x1, - // Proof = 0x2, - Metadata = 0x3, + Proof = 0x1, + Metadata = 0x2, } impl EthConnectorContract { @@ -73,6 +74,23 @@ impl EthConnectorContract { } self.ft.internal_deposit(&owner_id, amount) } + + /// Record used proof as hash key + pub fn record_proof(&mut self, key: &str) -> Result<(), errors::ProofUsed> { + crate::log!("Record proof: {}", key); + + if self.is_used_event(key) { + return Err(errors::ProofUsed); + } + + self.used_proofs.insert(key.to_string(), true); + Ok(()) + } + + /// Check is event of proof already used + pub fn is_used_event(&self, key: &str) -> bool { + self.used_proofs.contains_key(&key.to_string()) + } } #[near_bindgen] @@ -100,16 +118,15 @@ impl EthConnectorContract { ft: FungibleToken::new(b"t".to_vec()), connector: connector_data, metadata: LazyOption::new(StorageKey::Metadata, Some(&metadata)), + used_proofs: LookupMap::new(StorageKey::Proof), }; - // TODO this.ft.accounts.insert(&owner_id, &0); this } #[result_serializer(borsh)] - pub fn is_used_proof(&self, #[serializer(borsh)] _proof: Proof) -> bool { - // self.ft.is_used_event(&proof.get_key()) - true + pub fn is_used_proof(&self, #[serializer(borsh)] proof: Proof) -> bool { + self.is_used_event(&proof.get_key()) } #[cfg(feature = "integration-test")] @@ -227,7 +244,7 @@ impl ConnectorFundsFinish for EthConnectorContract { // Mint - calculate new balances self.mint_eth_on_near(deposit_call.new_owner_id, deposit_call.amount); // Store proof only after `mint` calculations - //self.ft.record_proof(&deposit_call.proof_key).sdk_unwrap(); + self.record_proof(&deposit_call.proof_key).sdk_unwrap(); let data: TransferCallCallArgs = TransferCallCallArgs::try_from_slice(&msg) .map_err(|_| crate::errors::ERR_BORSH_DESERIALIZE) @@ -247,7 +264,7 @@ impl ConnectorFundsFinish for EthConnectorContract { ); self.mint_eth_on_near(deposit_call.relayer_id, deposit_call.fee.as_u128()); // Store proof only after `mint` calculations - //self.ft.record_proof(&deposit_call.proof_key).sdk_unwrap(); + self.record_proof(&deposit_call.proof_key).sdk_unwrap(); PromiseOrValue::Value(None) } } @@ -297,9 +314,8 @@ impl Migration for EthConnectorContract { } // Insert Proof - for _proof_key in &data.used_proofs { - // TODO - //self.ft.used_proofs.insert(proof_key, &true); + for proof_key in &data.used_proofs { + self.used_proofs.insert(proof_key.clone(), true); } crate::log!("Inserted used_proofs: {:?}", data.used_proofs.len()); } @@ -322,12 +338,11 @@ impl Migration for EthConnectorContract { } // Check proofs - for _proof in &data.used_proofs { - // TODO - // match self.ft.used_proofs.get(proof) { - // Some(_) => (), - // _ => return MigrationCheckResult::Proof(proof.clone()), - // } + for proof in &data.used_proofs { + match self.used_proofs.get(proof) { + Some(_) => (), + _ => return MigrationCheckResult::Proof(proof.clone()), + } } if let Some(account_storage_usage) = data.account_storage_usage { From cf81e62cb268ff2fd6e1d91f78b9ec931dfb5260 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 29 Nov 2022 00:37:34 +0100 Subject: [PATCH 04/44] Refactor metadata and types dependency --- eth-connector/src/connector.rs | 6 +++--- eth-connector/src/connector_impl.rs | 4 ++-- eth-connector/src/lib.rs | 33 ++++++++++++----------------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/eth-connector/src/connector.rs b/eth-connector/src/connector.rs index cefe55b..536b95c 100644 --- a/eth-connector/src/connector.rs +++ b/eth-connector/src/connector.rs @@ -1,9 +1,9 @@ use crate::{connector_impl::FinishDepositCallArgs, Proof, WithdrawResult}; -use aurora_engine_types::types::{Address, NEP141Wei}; +use aurora_engine_types::types::Address; use near_sdk::{ borsh, ext_contract, json_types::{Base64VecU8, U128}, - AccountId, Promise, PromiseOrValue, + AccountId, Balance, Promise, PromiseOrValue, }; #[ext_contract(ext_deposit)] @@ -18,7 +18,7 @@ pub trait ConnectorWithdraw { &mut self, #[serializer(borsh)] sender_id: AccountId, #[serializer(borsh)] recipient_address: Address, - #[serializer(borsh)] amount: NEP141Wei, + #[serializer(borsh)] amount: Balance, ) -> WithdrawResult; } diff --git a/eth-connector/src/connector_impl.rs b/eth-connector/src/connector_impl.rs index 2718f50..0feb1ae 100644 --- a/eth-connector/src/connector_impl.rs +++ b/eth-connector/src/connector_impl.rs @@ -7,7 +7,7 @@ use crate::{ types::SdkUnwrap, AdminControlled, PausedMask, }; -use aurora_engine_types::types::{Address, Fee, NEP141Wei}; +use aurora_engine_types::types::{Address, Fee}; use near_sdk::{ borsh::{self, BorshDeserialize, BorshSerialize}, env, AccountId, Balance, Gas, Promise, @@ -42,7 +42,7 @@ pub struct FinishDepositCallArgs { /// withdraw result for eth-connector #[derive(BorshSerialize, BorshDeserialize)] pub struct WithdrawResult { - pub amount: NEP141Wei, + pub amount: Balance, pub recipient_id: Address, pub eth_custodian_address: Address, } diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 78b8da7..ccea839 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -3,20 +3,9 @@ use crate::connector::{ConnectorDeposit, ConnectorFundsFinish, ConnectorWithdraw use crate::connector_impl::{ EthConnector, FinishDepositCallArgs, TransferCallCallArgs, WithdrawResult, }; -/* -use crate::fungible_token::engine::EngineFungibleToken; -use crate::fungible_token::{ - core::FungibleTokenCore, - core_impl::FungibleToken, - metadata::{FungibleTokenMetadata, FungibleTokenMetadataProvider}, - resolver::FungibleTokenResolver, - statistic::FungibleTokeStatistic, - storage_management::{StorageBalance, StorageBalanceBounds, StorageManagement}, -}; -*/ use crate::proof::Proof; use crate::types::{panic_err, SdkUnwrap}; -use aurora_engine_types::types::{Address, NEP141Wei}; +use aurora_engine_types::types::Address; use near_contract_standards::fungible_token::metadata::{ FungibleTokenMetadata, FungibleTokenMetadataProvider, }; @@ -37,7 +26,6 @@ pub mod connector; pub mod connector_impl; pub mod deposit_event; pub mod errors; -// pub mod fungible_token; pub mod log_entry; pub mod migration; pub mod proof; @@ -147,8 +135,15 @@ near_contract_standards::impl_fungible_token_storage!(EthConnectorContract, ft); #[near_bindgen] impl FungibleTokenMetadataProvider for EthConnectorContract { fn ft_metadata(&self) -> FungibleTokenMetadata { - // TODO - self.metadata.get().sdk_unwrap() + self.metadata.get().map_or(FungibleTokenMetadata { + spec: "ft-1.0.0".to_string(), + name: "Ether".to_string(), + symbol: "ETH".to_string(), + icon: Some("data:image/png;base64,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".to_string()), + reference: None, + reference_hash: None, + decimals: 18, + }, |v|v) } } @@ -189,9 +184,9 @@ impl ConnectorWithdraw for EthConnectorContract { #[result_serializer(borsh)] fn withdraw( &mut self, - #[serializer(borsh)] _sender_id: AccountId, + #[serializer(borsh)] sender_id: AccountId, #[serializer(borsh)] recipient_address: Address, - #[serializer(borsh)] amount: NEP141Wei, + #[serializer(borsh)] amount: Balance, ) -> WithdrawResult { self.assert_access_right().sdk_unwrap(); assert_one_yocto(); @@ -204,9 +199,7 @@ impl ConnectorWithdraw for EthConnectorContract { .map_err(|_| "WithdrawErrorPaused") .sdk_unwrap(); // Burn tokens to recipient - // self.ft - // .internal_withdraw_eth_from_near(&sender_id, amount) - // .sdk_unwrap(); + self.ft.internal_withdraw(&sender_id, amount); WithdrawResult { recipient_id: recipient_address, amount, From 4d1afc30b7fc2805f827b9bccd3324138d6b48f2 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sat, 26 Nov 2022 00:44:56 +0100 Subject: [PATCH 05/44] Remove fungible_token implemenation --- eth-connector/src/fungible_token/core.rs | 55 -- eth-connector/src/fungible_token/core_impl.rs | 497 ------------------ eth-connector/src/fungible_token/engine.rs | 37 -- .../src/fungible_token/engine_impl.rs | 157 ------ eth-connector/src/fungible_token/event.rs | 30 -- eth-connector/src/fungible_token/events.rs | 254 --------- eth-connector/src/fungible_token/metadata.rs | 51 -- eth-connector/src/fungible_token/mod.rs | 13 - eth-connector/src/fungible_token/receiver.rs | 29 - eth-connector/src/fungible_token/resolver.rs | 11 - eth-connector/src/fungible_token/statistic.rs | 6 - .../src/fungible_token/statistic_impl.rs | 8 - .../src/fungible_token/storage_impl.rs | 108 ---- .../src/fungible_token/storage_management.rs | 74 --- 14 files changed, 1330 deletions(-) delete mode 100644 eth-connector/src/fungible_token/core.rs delete mode 100644 eth-connector/src/fungible_token/core_impl.rs delete mode 100644 eth-connector/src/fungible_token/engine.rs delete mode 100644 eth-connector/src/fungible_token/engine_impl.rs delete mode 100644 eth-connector/src/fungible_token/event.rs delete mode 100644 eth-connector/src/fungible_token/events.rs delete mode 100644 eth-connector/src/fungible_token/metadata.rs delete mode 100644 eth-connector/src/fungible_token/mod.rs delete mode 100644 eth-connector/src/fungible_token/receiver.rs delete mode 100644 eth-connector/src/fungible_token/resolver.rs delete mode 100644 eth-connector/src/fungible_token/statistic.rs delete mode 100644 eth-connector/src/fungible_token/statistic_impl.rs delete mode 100644 eth-connector/src/fungible_token/storage_impl.rs delete mode 100644 eth-connector/src/fungible_token/storage_management.rs diff --git a/eth-connector/src/fungible_token/core.rs b/eth-connector/src/fungible_token/core.rs deleted file mode 100644 index 9ca248d..0000000 --- a/eth-connector/src/fungible_token/core.rs +++ /dev/null @@ -1,55 +0,0 @@ -use near_sdk::{ext_contract, json_types::U128, AccountId, PromiseOrValue}; - -#[ext_contract(ext_ft_core)] -pub trait FungibleTokenCore { - /// Transfers positive `amount` of tokens from the `env::predecessor_account_id` to `receiver_id`. - /// Both accounts must be registered with the contract for transfer to succeed. (See [NEP-145](https://github.com/near/NEPs/discussions/145)) - /// This method must to be able to accept attached deposits, and must not panic on attached deposit. - /// Exactly 1 yoctoNEAR must be attached. - /// See [the Security section](https://github.com/near/NEPs/issues/141#user-content-security) of the standard. - /// - /// Arguments: - /// - `receiver_id` - the account ID of the receiver. - /// - `amount` - the amount of tokens to transfer. Must be a positive number in decimal string representation. - /// - `memo` - an optional string field in a free form to associate a memo with this transfer. - fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option); - - /// Transfers positive `amount` of tokens from the `env::predecessor_account_id` to `receiver_id` account. Then - /// calls `ft_on_transfer` method on `receiver_id` contract and attaches a callback to resolve this transfer. - /// `ft_on_transfer` method must return the amount of tokens unused by the receiver contract, the remaining tokens - /// must be refunded to the `predecessor_account_id` at the resolve transfer callback. - /// - /// Token contract must pass all the remaining unused gas to the `ft_on_transfer` call. - /// - /// Malicious or invalid behavior by the receiver's contract: - /// - If the receiver contract promise fails or returns invalid value, the full transfer amount must be refunded. - /// - If the receiver contract overspent the tokens, and the `receiver_id` balance is lower than the required refund - /// amount, the remaining balance must be refunded. See [the Security section](https://github.com/near/NEPs/issues/141#user-content-security) of the standard. - /// - /// Both accounts must be registered with the contract for transfer to succeed. (See #145) - /// This method must to be able to accept attached deposits, and must not panic on attached deposit. Exactly 1 yoctoNEAR must be attached. See [the Security - /// section](https://github.com/near/NEPs/issues/141#user-content-security) of the standard. - /// - /// Arguments: - /// - `receiver_id` - the account ID of the receiver contract. This contract will be called. - /// - `amount` - the amount of tokens to transfer. Must be a positive number in a decimal string representation. - /// - `memo` - an optional string field in a free form to associate a memo with this transfer. - /// - `msg` - a string message that will be passed to `ft_on_transfer` contract call. - /// - /// Returns a promise which will result in the amount of tokens withdrawn from sender's account. - fn ft_transfer_call( - &mut self, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue; - - /// Returns the total supply of the token in a decimal string representation. - fn ft_total_supply(&self) -> U128; - - /// Returns the balance of the account. If the account doesn't exist must returns `"0"`. - fn ft_balance_of(&self, account_id: AccountId) -> U128; - - fn ft_total_eth_supply_on_near(&self) -> U128; -} diff --git a/eth-connector/src/fungible_token/core_impl.rs b/eth-connector/src/fungible_token/core_impl.rs deleted file mode 100644 index 4a1189a..0000000 --- a/eth-connector/src/fungible_token/core_impl.rs +++ /dev/null @@ -1,497 +0,0 @@ -use super::{ - core::FungibleTokenCore, - events::{FtBurn, FtTransfer}, - resolver::FungibleTokenResolver, -}; -use crate::{errors::ERR_ACCOUNTS_COUNTER_OVERFLOW, SdkUnwrap}; -use aurora_engine_types::types::{NEP141Wei, ZERO_NEP141_WEI}; - -use crate::errors; -use crate::fungible_token::engine::EngineFungibleToken; - -use near_sdk::{ - borsh::{self, BorshDeserialize, BorshSerialize}, - collections::LookupMap, - env, - json_types::U128, - AccountId, IntoStorageKey, PromiseOrValue, PromiseResult, StorageUsage, -}; - -/// Implementation of a FungibleToken standard. -/// Allows to include NEP-141 compatible token to any contract. -/// There are next traits that any contract may implement: -/// - FungibleTokenCore -- interface with ft_transfer methods. FungibleToken provides methods for it. -/// - FungibleTokenMetaData -- return metadata for the token in NEP-148, up to contract to implement. -/// - StorageManager -- interface for NEP-145 for allocating storage per account. FungibleToken provides methods for it. -/// - AccountRegistrar -- interface for an account to register and unregister -/// -/// For example usage, see examples/fungible-token/src/lib.rs. -#[derive(BorshDeserialize, BorshSerialize)] -pub struct FungibleToken { - /// Accounts with balance of nETH (ETH on NEAR token) - pub accounts_eth: LookupMap, - - /// Total ETH supply on Near (nETH as NEP-141 token) - pub total_eth_supply_on_near: NEP141Wei, - - /// The storage size in bytes for one account. - pub account_storage_usage: StorageUsage, - - /// Accounts counter - pub statistics_aurora_accounts_counter: u64, - - /// Used proofs - pub used_proofs: LookupMap, -} - -impl FungibleToken { - pub fn new(prefix_eth: S, prefix_proof: S) -> Self - where - S: IntoStorageKey, - { - Self { - accounts_eth: LookupMap::new(prefix_eth), - account_storage_usage: 0, - total_eth_supply_on_near: NEP141Wei::default(), - statistics_aurora_accounts_counter: 0, - used_proofs: LookupMap::new(prefix_proof), - } - } - - /// Record used proof as hash key - pub fn record_proof(&mut self, key: &str) -> Result<(), error::ProofUsed> { - crate::log!("Record proof: {}", key); - - if self.is_used_event(key) { - return Err(error::ProofUsed); - } - - self.used_proofs.insert(&key.to_string(), &true); - Ok(()) - } - - /// Check is event of proof already used - pub fn is_used_event(&self, key: &str) -> bool { - self.used_proofs.contains_key(&key.to_string()) - } - - /// Mint nETH tokens - pub fn mint_eth_on_near( - &mut self, - owner_id: AccountId, - amount: NEP141Wei, - ) -> Result<(), error::DepositError> { - crate::log!("Mint {} nETH tokens for: {}", amount, owner_id); - - if self.get_account_eth_balance(&owner_id).is_none() { - self.accounts_insert(&owner_id, ZERO_NEP141_WEI); - } - self.internal_deposit_eth_to_near(&owner_id, amount) - } - - /// Internal ETH deposit to NEAR - nETH (NEP-141) - pub fn internal_deposit_eth_to_near( - &mut self, - account_id: &AccountId, - amount: NEP141Wei, - ) -> Result<(), error::DepositError> { - let balance = self - .get_account_eth_balance(account_id) - .unwrap_or(ZERO_NEP141_WEI); - let new_balance = balance - .checked_add(amount) - .ok_or(error::DepositError::BalanceOverflow)?; - - self.accounts_insert(account_id, new_balance); - self.total_eth_supply_on_near = self - .total_eth_supply_on_near - .checked_add(amount) - .ok_or(error::DepositError::TotalSupplyOverflow)?; - Ok(()) - } - - /// Withdraw NEAR tokens - pub fn internal_withdraw_eth_from_near( - &mut self, - account_id: &AccountId, - amount: NEP141Wei, - ) -> Result<(), error::WithdrawError> { - let balance = self - .get_account_eth_balance(account_id) - .unwrap_or(ZERO_NEP141_WEI); - let new_balance = balance - .checked_sub(amount) - .ok_or(error::WithdrawError::InsufficientFunds)?; - self.accounts_insert(account_id, new_balance); - self.total_eth_supply_on_near = self - .total_eth_supply_on_near - .checked_sub(amount) - .ok_or(error::WithdrawError::TotalSupplyUnderflow)?; - Ok(()) - } - - /// Insert account. - /// Calculate total unique accounts - pub fn accounts_insert(&mut self, account_id: &AccountId, amount: NEP141Wei) { - if !self.accounts_eth.contains_key(account_id) { - self.statistics_aurora_accounts_counter = self - .statistics_aurora_accounts_counter - .checked_add(1) - .ok_or(ERR_ACCOUNTS_COUNTER_OVERFLOW) - .sdk_unwrap(); - } - self.accounts_eth.insert(account_id, &amount); - } - - /// Remove account - pub fn accounts_remove(&mut self, account_id: &AccountId) { - if self.accounts_eth.contains_key(account_id) { - self.statistics_aurora_accounts_counter = self - .statistics_aurora_accounts_counter - .checked_sub(1) - .unwrap_or(self.statistics_aurora_accounts_counter); - self.accounts_eth.remove(account_id); - } - } - - /// Transfer NEAR tokens - pub fn internal_transfer_eth_on_near( - &mut self, - sender_id: &AccountId, - receiver_id: &AccountId, - amount: NEP141Wei, - memo: &Option, - ) -> Result<(), error::TransferError> { - if sender_id == receiver_id { - return Err(error::TransferError::SelfTransfer); - } - if amount == ZERO_NEP141_WEI { - return Err(error::TransferError::ZeroAmount); - } - - // Check is account receiver_id exist - if !self.accounts_eth.contains_key(receiver_id) { - // Register receiver_id account with 0 balance. We need it because - // when we retire to get the balance of `receiver_id` it will fail - // if it does not exist. - self.accounts_insert(receiver_id, ZERO_NEP141_WEI); - } - self.internal_withdraw_eth_from_near(sender_id, amount)?; - self.internal_deposit_eth_to_near(receiver_id, amount)?; - - crate::log!("Transfer {} from {} to {}", amount, sender_id, receiver_id); - #[cfg(feature = "log")] - if let Some(memo) = memo { - crate::log!("Memo: {}", memo); - } - - FtTransfer { - old_owner_id: sender_id, - new_owner_id: receiver_id, - amount: &U128(amount.as_u128()), - memo: memo.as_deref(), - } - .emit(); - Ok(()) - } - - /// Balance of nETH (ETH on NEAR token) - pub fn get_account_eth_balance(&self, account_id: &AccountId) -> Option { - self.accounts_eth.get(account_id) - } -} - -impl FungibleTokenCore for FungibleToken { - fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option) { - self.engine_ft_transfer(env::predecessor_account_id(), receiver_id, amount, memo) - } - - fn ft_transfer_call( - &mut self, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue { - self.engine_ft_transfer_call( - env::predecessor_account_id(), - receiver_id, - amount, - memo, - msg, - ) - } - - fn ft_total_supply(&self) -> U128 { - self.ft_total_eth_supply_on_near() - } - - fn ft_total_eth_supply_on_near(&self) -> U128 { - self.total_eth_supply_on_near.as_u128().into() - } - - fn ft_balance_of(&self, account_id: AccountId) -> U128 { - self.get_account_eth_balance(&account_id) - .unwrap_or(ZERO_NEP141_WEI) - .as_u128() - .into() - } -} - -impl FungibleToken { - /// Internal method that returns the amount of burned tokens in a corner case when the sender - /// has deleted (unregistered) their account while the `ft_transfer_call` was still in flight. - /// Returns (Used token amount, Burned token amount) - pub fn internal_ft_resolve_transfer( - &mut self, - sender_id: &AccountId, - receiver_id: &AccountId, - amount: NEP141Wei, - ) -> (NEP141Wei, NEP141Wei) { - // Get the unused amount from the `ft_on_transfer` call result. - let unused_amount = match env::promise_result(0) { - PromiseResult::NotReady => env::abort(), - PromiseResult::Successful(value) => { - if let Ok(unused_amount) = near_sdk::serde_json::from_slice::(&value) { - std::cmp::min(amount, NEP141Wei::new(unused_amount.0)) - } else { - amount - } - } - PromiseResult::Failed => amount, - }; - - if unused_amount > ZERO_NEP141_WEI { - let receiver_balance = self - .get_account_eth_balance(receiver_id) - .unwrap_or_else(|| { - self.accounts_insert(receiver_id, ZERO_NEP141_WEI); - ZERO_NEP141_WEI - }); - if receiver_balance > ZERO_NEP141_WEI { - let refund_amount = std::cmp::min(receiver_balance, unused_amount); - let new_receiver_balance = receiver_balance - .checked_sub(refund_amount) - .ok_or(errors::ERR_RECEIVER_BALANCE_NOT_ENOUGH) - .sdk_unwrap(); - self.accounts_insert(receiver_id, new_receiver_balance); - - crate::log!( - "Decrease receiver {} balance to: {}", - receiver_id, - receiver_balance - refund_amount - ); - - if let Some(sender_balance) = self.get_account_eth_balance(sender_id) { - let new_sender_balance = sender_balance - .checked_add(refund_amount) - .ok_or(errors::ERR_BALANCE_OVERFLOW) - .sdk_unwrap(); - self.accounts_insert(sender_id, new_sender_balance); - - crate::log!( - "Increased sender {} balance to: {}", - sender_id, - refund_amount.as_u128() - ); - - FtTransfer { - old_owner_id: receiver_id, - new_owner_id: sender_id, - amount: &U128(refund_amount.as_u128()), - memo: Some("refund"), - } - .emit(); - let used_amount = amount - .checked_sub(refund_amount) - .ok_or(errors::ERR_USED_AMOUNT_OVERFLOW) - .sdk_unwrap(); - return (used_amount, ZERO_NEP141_WEI); - } else { - // Sender's account was deleted, so we need to burn tokens. - self.total_eth_supply_on_near = self - .total_eth_supply_on_near - .checked_sub(refund_amount) - .ok_or(errors::ERR_TOTAL_SUPPLY_OVERFLOW) - .sdk_unwrap(); - crate::log!("The account of the sender {} was deleted", sender_id); - FtBurn { - owner_id: receiver_id, - amount: &U128(refund_amount.as_u128()), - memo: Some("refund"), - } - .emit(); - return (amount, refund_amount); - } - } - } - (amount, ZERO_NEP141_WEI) - } -} - -impl FungibleTokenResolver for FungibleToken { - fn ft_resolve_transfer( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - ) -> U128 { - self.internal_ft_resolve_transfer(&sender_id, &receiver_id, NEP141Wei::new(amount.0)) - .0 - .as_u128() - .into() - } -} - -pub mod error { - use crate::deposit_event::error::ParseOnTransferMessageError; - use crate::errors::{ - ERR_BALANCE_OVERFLOW, ERR_NOT_ENOUGH_BALANCE, ERR_NOT_ENOUGH_BALANCE_FOR_FEE, - ERR_PROOF_EXIST, ERR_SENDER_EQUALS_RECEIVER, ERR_TOTAL_SUPPLY_OVERFLOW, - ERR_TOTAL_SUPPLY_UNDERFLOW, ERR_WRONG_EVENT_ADDRESS, ERR_ZERO_AMOUNT, - }; - use aurora_engine_types::types::balance::error::BalanceOverflowError; - use aurora_engine_types::types::ERR_FAILED_PARSE; - - pub struct ProofUsed; - - impl AsRef<[u8]> for ProofUsed { - fn as_ref(&self) -> &[u8] { - ERR_PROOF_EXIST - } - } - - #[derive(Debug)] - pub enum DepositError { - TotalSupplyOverflow, - BalanceOverflow, - } - - impl AsRef<[u8]> for DepositError { - fn as_ref(&self) -> &[u8] { - match self { - Self::TotalSupplyOverflow => ERR_TOTAL_SUPPLY_OVERFLOW.as_bytes(), - Self::BalanceOverflow => ERR_BALANCE_OVERFLOW, - } - } - } - - impl From for TransferError { - fn from(err: DepositError) -> Self { - match err { - DepositError::BalanceOverflow => Self::BalanceOverflow, - DepositError::TotalSupplyOverflow => Self::TotalSupplyOverflow, - } - } - } - - pub enum FtDepositError { - ProofParseFailed, - CustodianAddressMismatch, - InsufficientAmountForFee, - } - - impl AsRef<[u8]> for FtDepositError { - fn as_ref(&self) -> &[u8] { - match self { - Self::ProofParseFailed => ERR_FAILED_PARSE.as_bytes(), - Self::CustodianAddressMismatch => ERR_WRONG_EVENT_ADDRESS, - Self::InsufficientAmountForFee => ERR_NOT_ENOUGH_BALANCE_FOR_FEE.as_bytes(), - } - } - } - - #[derive(Debug)] - pub enum WithdrawError { - TotalSupplyUnderflow, - InsufficientFunds, - BalanceOverflow(BalanceOverflowError), - } - - impl AsRef<[u8]> for WithdrawError { - fn as_ref(&self) -> &[u8] { - match self { - Self::TotalSupplyUnderflow => ERR_TOTAL_SUPPLY_UNDERFLOW, - Self::InsufficientFunds => ERR_NOT_ENOUGH_BALANCE, - Self::BalanceOverflow(e) => e.as_ref(), - } - } - } - - impl From for TransferError { - fn from(err: WithdrawError) -> Self { - match err { - WithdrawError::InsufficientFunds => Self::InsufficientFunds, - WithdrawError::TotalSupplyUnderflow => Self::TotalSupplyUnderflow, - WithdrawError::BalanceOverflow(_) => Self::BalanceOverflow, - } - } - } - - pub enum FinishDepositError { - TransferCall(FtTransferCallError), - ProofUsed, - } - - impl From for FtTransferCallError { - fn from(e: DepositError) -> Self { - Self::Transfer(e.into()) - } - } - - impl From for FtTransferCallError { - fn from(e: ParseOnTransferMessageError) -> Self { - Self::MessageParseFailed(e) - } - } - - impl AsRef<[u8]> for FinishDepositError { - fn as_ref(&self) -> &[u8] { - match self { - Self::ProofUsed => ERR_PROOF_EXIST, - Self::TransferCall(e) => e.as_ref(), - } - } - } - - pub enum FtTransferCallError { - BalanceOverflow(BalanceOverflowError), - MessageParseFailed(ParseOnTransferMessageError), - InsufficientAmountForFee, - Transfer(TransferError), - } - - impl AsRef<[u8]> for FtTransferCallError { - fn as_ref(&self) -> &[u8] { - match self { - Self::MessageParseFailed(e) => e.as_ref(), - Self::InsufficientAmountForFee => ERR_NOT_ENOUGH_BALANCE_FOR_FEE.as_bytes(), - Self::Transfer(e) => e.as_ref(), - Self::BalanceOverflow(e) => e.as_ref(), - } - } - } - - #[derive(Debug)] - pub enum TransferError { - TotalSupplyUnderflow, - TotalSupplyOverflow, - InsufficientFunds, - BalanceOverflow, - ZeroAmount, - SelfTransfer, - } - - impl AsRef<[u8]> for TransferError { - fn as_ref(&self) -> &[u8] { - match self { - Self::TotalSupplyUnderflow => ERR_TOTAL_SUPPLY_UNDERFLOW, - Self::TotalSupplyOverflow => ERR_TOTAL_SUPPLY_OVERFLOW.as_bytes(), - Self::InsufficientFunds => ERR_NOT_ENOUGH_BALANCE, - Self::BalanceOverflow => ERR_BALANCE_OVERFLOW, - Self::ZeroAmount => ERR_ZERO_AMOUNT, - Self::SelfTransfer => ERR_SENDER_EQUALS_RECEIVER, - } - } - } -} diff --git a/eth-connector/src/fungible_token/engine.rs b/eth-connector/src/fungible_token/engine.rs deleted file mode 100644 index dfce98c..0000000 --- a/eth-connector/src/fungible_token/engine.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::StorageBalance; -use near_sdk::{ext_contract, json_types::U128, AccountId, PromiseOrValue}; - -#[ext_contract(ext_engine_ft)] -pub trait EngineFungibleToken { - fn engine_ft_transfer( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - memo: Option, - ); - - fn engine_ft_transfer_call( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue; - - fn engine_storage_deposit( - &mut self, - sender_id: AccountId, - account_id: Option, - registration_only: Option, - ) -> StorageBalance; - - fn engine_storage_withdraw( - &mut self, - sender_id: AccountId, - amount: Option, - ) -> StorageBalance; - - fn engine_storage_unregister(&mut self, sender_id: AccountId, force: Option) -> bool; -} diff --git a/eth-connector/src/fungible_token/engine_impl.rs b/eth-connector/src/fungible_token/engine_impl.rs deleted file mode 100644 index d67d2a9..0000000 --- a/eth-connector/src/fungible_token/engine_impl.rs +++ /dev/null @@ -1,157 +0,0 @@ -use crate::deposit_event::FtTransferMessageData; -use crate::errors::{ERR_MORE_GAS_REQUIRED, ERR_PREPAID_GAS_OVERFLOW}; -use crate::fungible_token::{ - core_impl::error, engine::EngineFungibleToken, receiver::ext_ft_receiver, - resolver::ext_ft_resolver, storage_management::StorageManagement, -}; -use crate::{panic_err, FungibleToken, SdkUnwrap, StorageBalance}; -use aurora_engine_types::types::{NEP141Wei, ZERO_NEP141_WEI}; - -use crate::fungible_token::storage_impl::error as storage_error; -use near_sdk::json_types::U128; -use near_sdk::{assert_one_yocto, env, require, AccountId, Balance, Gas, Promise, PromiseOrValue}; - -const GAS_FOR_RESOLVE_TRANSFER: Gas = Gas(5_000_000_000_000); -const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(25_000_000_000_000 + GAS_FOR_RESOLVE_TRANSFER.0); - -impl EngineFungibleToken for FungibleToken { - fn engine_ft_transfer( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - memo: Option, - ) { - assert_one_yocto(); - let amount: Balance = amount.into(); - self.internal_transfer_eth_on_near(&sender_id, &receiver_id, NEP141Wei::new(amount), &memo) - .sdk_unwrap(); - crate::log!( - "Transfer amount {} to {} success with memo: {:?}", - amount, - receiver_id, - memo - ); - } - - fn engine_ft_transfer_call( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue { - require!( - env::prepaid_gas() > GAS_FOR_FT_TRANSFER_CALL, - ERR_MORE_GAS_REQUIRED - ); - crate::log!( - "Transfer call from {} to {} amount {}", - sender_id, - receiver_id, - amount.0, - ); - - // Verify message data before `ft_on_transfer` call to avoid verification panics - // It's allowed empty message if `receiver_id =! current_account_id` - if sender_id == receiver_id { - let message_data = FtTransferMessageData::parse_on_transfer_message(&msg).sdk_unwrap(); - // Check is transfer amount > fee - if message_data.fee.as_u128() >= amount.0 { - panic_err(error::FtTransferCallError::InsufficientAmountForFee); - } - } - - // Special case for Aurora transfer itself - we shouldn't transfer - if sender_id != receiver_id { - self.internal_transfer_eth_on_near( - &sender_id, - &receiver_id, - NEP141Wei::new(amount.0), - &memo, - ) - .sdk_unwrap(); - } - let receiver_gas = env::prepaid_gas() - .0 - .checked_sub(GAS_FOR_FT_TRANSFER_CALL.0) - .ok_or(ERR_PREPAID_GAS_OVERFLOW) - .sdk_unwrap(); - // Initiating receiver's call and the callback - ext_ft_receiver::ext(receiver_id.clone()) - .with_static_gas(receiver_gas.into()) - .ft_on_transfer(sender_id.clone(), amount, msg) - .then( - ext_ft_resolver::ext(env::current_account_id()) - .with_static_gas(GAS_FOR_RESOLVE_TRANSFER) - .ft_resolve_transfer(sender_id, receiver_id, amount), - ) - .into() - } - - #[allow(unused_variables)] - fn engine_storage_deposit( - &mut self, - sender_id: AccountId, - account_id: Option, - registration_only: Option, - ) -> StorageBalance { - let amount: Balance = env::attached_deposit(); - let account_id = account_id.unwrap_or(sender_id); - if self.accounts_eth.contains_key(&account_id) { - crate::log!( - "The account {} is already registered, refunding the deposit {}", - account_id.to_string(), - amount - ); - if amount > 0 { - Promise::new(env::predecessor_account_id()).transfer(amount); - } - } else { - let min_balance = self.storage_balance_bounds().min.0; - if amount < min_balance { - panic_err(storage_error::StorageFundingError::InsufficientDeposit); - } - - self.accounts_insert(&account_id, ZERO_NEP141_WEI); - let refund = amount - min_balance; - crate::log!( - "Storage deposit {:?} for account {} with refund {:?}", - amount, - account_id.to_string(), - refund, - ); - if refund > 0 { - Promise::new(env::predecessor_account_id()).transfer(refund); - } - } - self.internal_storage_balance_of(&account_id).unwrap() - } - - fn engine_storage_withdraw( - &mut self, - sender_id: AccountId, - amount: Option, - ) -> StorageBalance { - assert_one_yocto(); - let predecessor_account_id = sender_id; - if let Some(storage_balance) = self.internal_storage_balance_of(&predecessor_account_id) { - match amount { - Some(amount) if amount.0 > 0 => { - // The available balance is always zero because `StorageBalanceBounds::max` is - // equal to `StorageBalanceBounds::min`. Therefore it is impossible to withdraw - // a positive amount. - panic_err(storage_error::StorageFundingError::NoAvailableBalance); - } - _ => storage_balance, - } - } else { - panic_err(storage_error::StorageFundingError::NotRegistered); - } - } - - fn engine_storage_unregister(&mut self, sender_id: AccountId, force: Option) -> bool { - self.internal_storage_unregister(sender_id, force).is_some() - } -} diff --git a/eth-connector/src/fungible_token/event.rs b/eth-connector/src/fungible_token/event.rs deleted file mode 100644 index f999443..0000000 --- a/eth-connector/src/fungible_token/event.rs +++ /dev/null @@ -1,30 +0,0 @@ -use near_sdk::env; -use serde::Serialize; - -#[derive(Serialize, Debug)] -#[serde(tag = "standard")] -#[must_use = "don't forget to `.emit()` this event"] -#[serde(rename_all = "snake_case")] -pub(crate) enum NearEvent<'a> { - Nep141(super::events::Nep141Event<'a>), -} - -impl<'a> NearEvent<'a> { - fn to_json_string(&self) -> String { - // Events cannot fail to serialize so fine to panic on error - #[allow(clippy::redundant_closure)] - serde_json::to_string(self) - .ok() - .unwrap_or_else(|| env::abort()) - } - - fn to_json_event_string(&self) -> String { - format!("EVENT_JSON:{}", self.to_json_string()) - } - - /// Logs the event to the host. This is required to ensure that the event is triggered - /// and to consume the event. - pub(crate) fn emit(self) { - near_sdk::env::log_str(&self.to_json_event_string()); - } -} diff --git a/eth-connector/src/fungible_token/events.rs b/eth-connector/src/fungible_token/events.rs deleted file mode 100644 index 1aad99c..0000000 --- a/eth-connector/src/fungible_token/events.rs +++ /dev/null @@ -1,254 +0,0 @@ -//! Standard for nep141 (Fungible Token) events. -//! -//! These events will be picked up by the NEAR indexer. -//! -//! -//! -//! This is an extension of the events format (nep-297): -//! -//! -//! The three events in this standard are [`FtMint`], [`FtTransfer`], and [`FtBurn`]. -//! -//! These events can be logged by calling `.emit()` on them if a single event, or calling -//! [`FtMint::emit_many`], [`FtTransfer::emit_many`], -//! or [`FtBurn::emit_many`] respectively. - -use super::event::NearEvent; -use near_sdk::json_types::U128; -use near_sdk::AccountId; -use serde::Serialize; - -/// Data to log for an FT mint event. To log this event, call [`.emit()`](FtMint::emit). -#[must_use] -#[derive(Serialize, Debug, Clone)] -pub struct FtMint<'a> { - pub owner_id: &'a AccountId, - pub amount: &'a U128, - #[serde(skip_serializing_if = "Option::is_none")] - pub memo: Option<&'a str>, -} - -impl FtMint<'_> { - /// Logs the event to the host. This is required to ensure that the event is triggered - /// and to consume the event. - pub fn emit(self) { - Self::emit_many(&[self]) - } - /// Emits an FT mint event, through [`env::log_str`](near_sdk::env::log_str), - /// where each [`FtMint`] represents the data of each mint. - pub fn emit_many(data: &[FtMint<'_>]) { - new_141_v1(Nep141EventKind::FtMint(data)).emit() - } -} - -/// Data to log for an FT transfer event. To log this event, -/// call [`.emit()`](FtTransfer::emit). -#[must_use] -#[derive(Serialize, Debug, Clone)] -pub struct FtTransfer<'a> { - pub old_owner_id: &'a AccountId, - pub new_owner_id: &'a AccountId, - pub amount: &'a U128, - #[serde(skip_serializing_if = "Option::is_none")] - pub memo: Option<&'a str>, -} - -impl FtTransfer<'_> { - /// Logs the event to the host. This is required to ensure that the event is triggered - /// and to consume the event. - pub fn emit(self) { - Self::emit_many(&[self]) - } - - /// Emits an FT transfer event, through [`env::log_str`](near_sdk::env::log_str), - /// where each [`FtTransfer`] represents the data of each transfer. - pub fn emit_many(data: &[FtTransfer<'_>]) { - new_141_v1(Nep141EventKind::FtTransfer(data)).emit() - } -} - -/// Data to log for an FT burn event. To log this event, call [`.emit()`](FtBurn::emit). -#[must_use] -#[derive(Serialize, Debug, Clone)] -pub struct FtBurn<'a> { - pub owner_id: &'a AccountId, - pub amount: &'a U128, - #[serde(skip_serializing_if = "Option::is_none")] - pub memo: Option<&'a str>, -} - -impl FtBurn<'_> { - /// Logs the event to the host. This is required to ensure that the event is triggered - /// and to consume the event. - pub fn emit(self) { - Self::emit_many(&[self]) - } - - /// Emits an FT burn event, through [`env::log_str`](near_sdk::env::log_str), - /// where each [`FtBurn`] represents the data of each burn. - pub fn emit_many<'a>(data: &'a [FtBurn<'a>]) { - new_141_v1(Nep141EventKind::FtBurn(data)).emit() - } -} - -#[derive(Serialize, Debug)] -pub(crate) struct Nep141Event<'a> { - version: &'static str, - #[serde(flatten)] - event_kind: Nep141EventKind<'a>, -} - -#[derive(Serialize, Debug)] -#[serde(tag = "event", content = "data")] -#[serde(rename_all = "snake_case")] -#[allow(clippy::enum_variant_names)] -enum Nep141EventKind<'a> { - FtMint(&'a [FtMint<'a>]), - FtTransfer(&'a [FtTransfer<'a>]), - FtBurn(&'a [FtBurn<'a>]), -} - -fn new_141<'a>(version: &'static str, event_kind: Nep141EventKind<'a>) -> NearEvent<'a> { - NearEvent::Nep141(Nep141Event { - version, - event_kind, - }) -} - -fn new_141_v1(event_kind: Nep141EventKind) -> NearEvent { - new_141("1.0.0", event_kind) -} - -#[cfg(test)] -mod tests { - use super::*; - use near_sdk::{test_utils, AccountId}; - - fn bob() -> AccountId { - AccountId::new_unchecked("bob".to_string()) - } - - fn alice() -> AccountId { - AccountId::new_unchecked("alice".to_string()) - } - - #[test] - fn ft_mint() { - let owner_id = &bob(); - let amount = &U128(100); - FtMint { - owner_id, - amount, - memo: None, - } - .emit(); - assert_eq!( - test_utils::get_logs()[0], - r#"EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_mint","data":[{"owner_id":"bob","amount":"100"}]}"# - ); - } - - #[test] - fn ft_mints() { - let owner_id = &bob(); - let amount = &U128(100); - let mint_log = FtMint { - owner_id, - amount, - memo: None, - }; - FtMint::emit_many(&[ - mint_log, - FtMint { - owner_id: &alice(), - amount: &U128(200), - memo: Some("has memo"), - }, - ]); - assert_eq!( - test_utils::get_logs()[0], - r#"EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_mint","data":[{"owner_id":"bob","amount":"100"},{"owner_id":"alice","amount":"200","memo":"has memo"}]}"# - ); - } - - #[test] - fn ft_burn() { - let owner_id = &bob(); - let amount = &U128(100); - FtBurn { - owner_id, - amount, - memo: None, - } - .emit(); - assert_eq!( - test_utils::get_logs()[0], - r#"EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_burn","data":[{"owner_id":"bob","amount":"100"}]}"# - ); - } - - #[test] - fn ft_burns() { - let owner_id = &bob(); - let amount = &U128(100); - FtBurn::emit_many(&[ - FtBurn { - owner_id: &alice(), - amount: &U128(200), - memo: Some("has memo"), - }, - FtBurn { - owner_id, - amount, - memo: None, - }, - ]); - assert_eq!( - test_utils::get_logs()[0], - r#"EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_burn","data":[{"owner_id":"alice","amount":"200","memo":"has memo"},{"owner_id":"bob","amount":"100"}]}"# - ); - } - - #[test] - fn ft_transfer() { - let old_owner_id = &bob(); - let new_owner_id = &alice(); - let amount = &U128(100); - FtTransfer { - old_owner_id, - new_owner_id, - amount, - memo: None, - } - .emit(); - assert_eq!( - test_utils::get_logs()[0], - r#"EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_transfer","data":[{"old_owner_id":"bob","new_owner_id":"alice","amount":"100"}]}"# - ); - } - - #[test] - fn ft_transfers() { - let old_owner_id = &bob(); - let new_owner_id = &alice(); - let amount = &U128(100); - FtTransfer::emit_many(&[ - FtTransfer { - old_owner_id: &alice(), - new_owner_id: &bob(), - amount: &U128(200), - memo: Some("has memo"), - }, - FtTransfer { - old_owner_id, - new_owner_id, - amount, - memo: None, - }, - ]); - assert_eq!( - test_utils::get_logs()[0], - r#"EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_transfer","data":[{"old_owner_id":"alice","new_owner_id":"bob","amount":"200","memo":"has memo"},{"old_owner_id":"bob","new_owner_id":"alice","amount":"100"}]}"# - ); - } -} diff --git a/eth-connector/src/fungible_token/metadata.rs b/eth-connector/src/fungible_token/metadata.rs deleted file mode 100644 index 94acbd4..0000000 --- a/eth-connector/src/fungible_token/metadata.rs +++ /dev/null @@ -1,51 +0,0 @@ -use near_sdk::{ - borsh::{self, BorshDeserialize, BorshSerialize}, - ext_contract, - json_types::Base64VecU8, - require, - serde::{Deserialize, Serialize}, -}; - -pub const FT_METADATA_SPEC: &str = "ft-1.0.0"; - -#[derive(BorshDeserialize, BorshSerialize, Clone, Deserialize, Serialize)] -#[serde(crate = "near_sdk::serde")] -#[cfg_attr(feature = "abi", derive(schemars::JsonSchema))] -pub struct FungibleTokenMetadata { - pub spec: String, - pub name: String, - pub symbol: String, - pub icon: Option, - pub reference: Option, - pub reference_hash: Option, - pub decimals: u8, -} - -#[ext_contract(ext_ft_metadata)] -pub trait FungibleTokenMetadataProvider { - fn ft_metadata(&self) -> FungibleTokenMetadata; -} - -impl FungibleTokenMetadata { - pub fn assert_valid(&self) { - require!(self.spec == FT_METADATA_SPEC); - require!(self.reference.is_some() == self.reference_hash.is_some()); - if let Some(reference_hash) = &self.reference_hash { - require!(reference_hash.0.len() == 32, "Hash has to be 32 bytes"); - } - } -} - -impl Default for FungibleTokenMetadata { - fn default() -> Self { - Self { - spec: "ft-1.0.0".to_string(), - name: "Ether".to_string(), - symbol: "ETH".to_string(), - icon: Some("data:image/png;base64,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".to_string()), - reference: None, - reference_hash: None, - decimals: 18, - } - } -} diff --git a/eth-connector/src/fungible_token/mod.rs b/eth-connector/src/fungible_token/mod.rs deleted file mode 100644 index 6f5c42b..0000000 --- a/eth-connector/src/fungible_token/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub mod core; -pub mod core_impl; -pub mod engine; -pub mod engine_impl; -pub mod event; -pub mod events; -pub mod metadata; -pub mod receiver; -pub mod resolver; -pub mod statistic; -pub mod statistic_impl; -pub mod storage_impl; -pub mod storage_management; diff --git a/eth-connector/src/fungible_token/receiver.rs b/eth-connector/src/fungible_token/receiver.rs deleted file mode 100644 index d46e04d..0000000 --- a/eth-connector/src/fungible_token/receiver.rs +++ /dev/null @@ -1,29 +0,0 @@ -use near_sdk::{ext_contract, json_types::U128, AccountId, PromiseOrValue}; - -#[ext_contract(ext_ft_receiver)] -pub trait FungibleTokenReceiver { - /// Called by fungible token contract after `ft_transfer_call` was initiated by - /// `sender_id` of the given `amount` with the transfer message given in `msg` field. - /// The `amount` of tokens were already transferred to this contract account and ready to be used. - /// - /// The method must return the amount of tokens that are *not* used/accepted by this contract from the transferred - /// amount. Examples: - /// - The transferred amount was `500`, the contract completely takes it and must return `0`. - /// - The transferred amount was `500`, but this transfer call only needs `450` for the action passed in the `msg` - /// field, then the method must return `50`. - /// - The transferred amount was `500`, but the action in `msg` field has expired and the transfer must be - /// cancelled. The method must return `500` or panic. - /// - /// Arguments: - /// - `sender_id` - the account ID that initiated the transfer. - /// - `amount` - the amount of tokens that were transferred to this account in a decimal string representation. - /// - `msg` - a string message that was passed with this transfer call. - /// - /// Returns the amount of unused tokens that should be returned to sender, in a decimal string representation. - fn ft_on_transfer( - &mut self, - sender_id: AccountId, - amount: U128, - msg: String, - ) -> PromiseOrValue; -} diff --git a/eth-connector/src/fungible_token/resolver.rs b/eth-connector/src/fungible_token/resolver.rs deleted file mode 100644 index b97d8ca..0000000 --- a/eth-connector/src/fungible_token/resolver.rs +++ /dev/null @@ -1,11 +0,0 @@ -use near_sdk::{ext_contract, json_types::U128, AccountId}; - -#[ext_contract(ext_ft_resolver)] -pub trait FungibleTokenResolver { - fn ft_resolve_transfer( - &mut self, - sender_id: AccountId, - receiver_id: AccountId, - amount: U128, - ) -> U128; -} diff --git a/eth-connector/src/fungible_token/statistic.rs b/eth-connector/src/fungible_token/statistic.rs deleted file mode 100644 index 1baff77..0000000 --- a/eth-connector/src/fungible_token/statistic.rs +++ /dev/null @@ -1,6 +0,0 @@ -use near_sdk::{ext_contract, json_types::U64}; - -#[ext_contract(ext_ft_statistic)] -pub trait FungibleTokeStatistic { - fn get_accounts_counter(&self) -> U64; -} diff --git a/eth-connector/src/fungible_token/statistic_impl.rs b/eth-connector/src/fungible_token/statistic_impl.rs deleted file mode 100644 index e2ee5d6..0000000 --- a/eth-connector/src/fungible_token/statistic_impl.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::{fungible_token::statistic::FungibleTokeStatistic, FungibleToken}; -use near_sdk::json_types::U64; - -impl FungibleTokeStatistic for FungibleToken { - fn get_accounts_counter(&self) -> U64 { - self.statistics_aurora_accounts_counter.into() - } -} diff --git a/eth-connector/src/fungible_token/storage_impl.rs b/eth-connector/src/fungible_token/storage_impl.rs deleted file mode 100644 index 4e19d6f..0000000 --- a/eth-connector/src/fungible_token/storage_impl.rs +++ /dev/null @@ -1,108 +0,0 @@ -use super::core_impl::FungibleToken; -use super::storage_management::{StorageBalance, StorageBalanceBounds, StorageManagement}; -use crate::{types::panic_err, EngineFungibleToken}; -use aurora_engine_types::types::NEP141Wei; -use near_sdk::{assert_one_yocto, env, json_types::U128, AccountId, Balance, Promise}; - -impl FungibleToken { - /// Internal method that returns the Account ID and the balance in case the account was - /// unregistered. - pub fn internal_storage_unregister( - &mut self, - account_id: AccountId, - force: Option, - ) -> Option<(AccountId, NEP141Wei)> { - assert_one_yocto(); - - let force = force.unwrap_or(false); - if let Some(balance) = self.get_account_eth_balance(&account_id) { - if balance == NEP141Wei::new(0) || force { - self.accounts_remove(&account_id); - self.total_eth_supply_on_near -= balance; - Promise::new(account_id.clone()).transfer(self.storage_balance_bounds().min.0 + 1); - Some((account_id, balance)) - } else { - panic_err(error::StorageFundingError::UnRegisterPositiveBalance); - } - } else { - crate::log!("The account {} is not registered", &account_id); - None - } - } - - pub fn internal_storage_balance_of(&self, account_id: &AccountId) -> Option { - if self.accounts_eth.contains_key(account_id) { - Some(StorageBalance { - total: self.storage_balance_bounds().min, - available: 0.into(), - }) - } else { - None - } - } -} - -impl StorageManagement for FungibleToken { - // `registration_only` doesn't affect the implementation for vanilla fungible token. - #[allow(unused_variables)] - fn storage_deposit( - &mut self, - account_id: Option, - registration_only: Option, - ) -> StorageBalance { - self.engine_storage_deposit(env::predecessor_account_id(), account_id, registration_only) - } - - /// While storage_withdraw normally allows the caller to retrieve `available` balance, the basic - /// Fungible Token implementation sets storage_balance_bounds.min == storage_balance_bounds.max, - /// which means available balance will always be 0. So this implementation: - /// * panics if `amount > 0` - /// * never transfers Ⓝ to caller - /// * returns a `storage_balance` struct if `amount` is 0 - fn storage_withdraw(&mut self, amount: Option) -> StorageBalance { - self.engine_storage_withdraw(env::predecessor_account_id(), amount) - } - - fn storage_unregister(&mut self, force: Option) -> bool { - self.engine_storage_unregister(env::predecessor_account_id(), force) - } - - fn storage_balance_bounds(&self) -> StorageBalanceBounds { - let required_storage_balance = - Balance::from(self.account_storage_usage) * env::storage_byte_cost(); - StorageBalanceBounds { - min: required_storage_balance.into(), - max: Some(required_storage_balance.into()), - } - } - - fn storage_balance_of(&self, account_id: AccountId) -> StorageBalance { - self.internal_storage_balance_of(&account_id) - .unwrap_or_default() - } -} - -pub mod error { - use crate::errors; - - #[derive(Debug)] - pub enum StorageFundingError { - NotRegistered, - NoAvailableBalance, - InsufficientDeposit, - UnRegisterPositiveBalance, - } - - impl AsRef<[u8]> for StorageFundingError { - fn as_ref(&self) -> &[u8] { - match self { - Self::NotRegistered => errors::ERR_ACCOUNT_NOT_REGISTERED, - Self::NoAvailableBalance => errors::ERR_NO_AVAILABLE_BALANCE, - Self::InsufficientDeposit => errors::ERR_ATTACHED_DEPOSIT_NOT_ENOUGH, - Self::UnRegisterPositiveBalance => { - errors::ERR_FAILED_UNREGISTER_ACCOUNT_POSITIVE_BALANCE - } - } - } - } -} diff --git a/eth-connector/src/fungible_token/storage_management.rs b/eth-connector/src/fungible_token/storage_management.rs deleted file mode 100644 index 1c4eb5b..0000000 --- a/eth-connector/src/fungible_token/storage_management.rs +++ /dev/null @@ -1,74 +0,0 @@ -use near_sdk::{ - borsh::{self, BorshDeserialize, BorshSerialize}, - json_types::U128, - serde::{Deserialize, Serialize}, - AccountId, -}; - -#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize)] -#[serde(crate = "near_sdk::serde")] -#[cfg_attr(feature = "abi", derive(schemars::JsonSchema))] -pub struct StorageBalance { - pub total: U128, - pub available: U128, -} - -impl Default for StorageBalance { - fn default() -> Self { - Self { - total: 0.into(), - available: 0.into(), - } - } -} - -#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize)] -#[serde(crate = "near_sdk::serde")] -#[cfg_attr(feature = "abi", derive(schemars::JsonSchema))] -pub struct StorageBalanceBounds { - pub min: U128, - pub max: Option, -} - -pub trait StorageManagement { - // if `registration_only=true` MUST refund above the minimum balance if the account didn't exist and - // refund full deposit if the account exists. - fn storage_deposit( - &mut self, - account_id: Option, - registration_only: Option, - ) -> StorageBalance; - - /// Withdraw specified amount of available Ⓝ for predecessor account. - /// - /// This method is safe to call. It MUST NOT remove data. - /// - /// `amount` is sent as a string representing an unsigned 128-bit integer. If - /// omitted, contract MUST refund full `available` balance. If `amount` exceeds - /// predecessor account's available balance, contract MUST panic. - /// - /// If predecessor account not registered, contract MUST panic. - /// - /// MUST require exactly 1 yoctoNEAR attached balance to prevent restricted - /// function-call access-key call (UX wallet security) - /// - /// Returns the StorageBalance structure showing updated balances. - fn storage_withdraw(&mut self, amount: Option) -> StorageBalance; - - /// Unregisters the predecessor account and returns the storage NEAR deposit back. - /// - /// If the predecessor account is not registered, the function MUST return `false` without panic. - /// - /// If `force=true` the function SHOULD ignore account balances (burn them) and close the account. - /// Otherwise, MUST panic if caller has a positive registered balance (eg token holdings) or - /// the contract doesn't support force unregistration. - /// MUST require exactly 1 yoctoNEAR attached balance to prevent restricted function-call access-key call - /// (UX wallet security) - /// Returns `true` iff the account was unregistered. - /// Returns `false` iff account was not registered before. - fn storage_unregister(&mut self, force: Option) -> bool; - - fn storage_balance_bounds(&self) -> StorageBalanceBounds; - - fn storage_balance_of(&self, account_id: AccountId) -> StorageBalance; -} From 24f203eb43d450d9efde875e619bbf3d7e615f61 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 27 Nov 2022 14:51:29 +0100 Subject: [PATCH 06/44] Fix migrations tests --- eth-connector-tests/src/migration.rs | 47 +++++++++++----------------- eth-connector/src/lib.rs | 12 +++---- eth-connector/src/migration.rs | 4 +-- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/eth-connector-tests/src/migration.rs b/eth-connector-tests/src/migration.rs index f2dbc24..39cf93e 100644 --- a/eth-connector-tests/src/migration.rs +++ b/eth-connector-tests/src/migration.rs @@ -2,15 +2,15 @@ use crate::utils::*; use aurora_engine_migration_tool::{BorshDeserialize, StateData}; use aurora_engine_types::types::NEP141Wei; use aurora_eth_connector::migration::{MigrationCheckResult, MigrationInputData}; -use near_sdk::AccountId; +use near_sdk::{AccountId, Balance}; use std::collections::HashMap; #[tokio::test] async fn test_migration_access_right() -> anyhow::Result<()> { let contract = TestContract::new().await?; let data = MigrationInputData { - accounts_eth: HashMap::new(), - total_eth_supply_on_near: None, + accounts: HashMap::new(), + total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, used_proofs: vec![], @@ -38,8 +38,8 @@ async fn test_migration() -> anyhow::Result<()> { .map(|&s| s.into()) .collect(); let data = MigrationInputData { - accounts_eth: HashMap::new(), - total_eth_supply_on_near: None, + accounts: HashMap::new(), + total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, used_proofs: proof_keys, @@ -63,10 +63,7 @@ async fn test_migration() -> anyhow::Result<()> { #[tokio::test] async fn test_migration_state() -> anyhow::Result<()> { let contract = TestContract::new().await?; - let data = match std::fs::read("../contract_state.borsh") { - Ok(data) => data, - _ => return Ok(()), - }; + let data = std::fs::read("../contract_state.borsh").expect("Test state data not found"); let data: StateData = StateData::try_from_slice(&data[..]).unwrap(); let limit = 2000; @@ -117,20 +114,19 @@ async fn test_migration_state() -> anyhow::Result<()> { // Accounts migration let mut accounts_gas_burnt = 0; - let mut accounts: HashMap = HashMap::new(); + let mut accounts: HashMap = HashMap::new(); let mut accounts_count = 0; for (i, (account, amount)) in data.accounts.iter().enumerate() { let account = AccountId::try_from(account.to_string()).unwrap(); - let amount = NEP141Wei::new(amount.as_u128()); - accounts.insert(account.clone(), amount); + accounts.insert(account.clone(), amount.as_u128()); if accounts.len() < limit && i < data.accounts.len() - 1 { continue; } accounts_count += &accounts.len(); let args = MigrationInputData { - accounts_eth: accounts, - total_eth_supply_on_near: None, + accounts: accounts, + total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, used_proofs: vec![], @@ -159,10 +155,8 @@ async fn test_migration_state() -> anyhow::Result<()> { // Migrate Contract data let args = MigrationInputData { - accounts_eth: HashMap::new(), - total_eth_supply_on_near: Some(NEP141Wei::new( - data.contract_data.total_eth_supply_on_near.as_u128(), - )), + accounts: HashMap::new(), + total_supply: Some(data.contract_data.total_eth_supply_on_near.as_u128()), account_storage_usage: Some(data.contract_data.account_storage_usage), statistics_aurora_accounts_counter: Some(data.accounts_counter), used_proofs: vec![], @@ -189,10 +183,8 @@ async fn test_migration_state() -> anyhow::Result<()> { // Check basic (NEP-141) contract data let args = MigrationInputData { - accounts_eth: HashMap::new(), - total_eth_supply_on_near: Some(NEP141Wei::new( - data.contract_data.total_eth_supply_on_near.as_u128(), - )), + accounts: HashMap::new(), + total_supply: Some(data.contract_data.total_eth_supply_on_near.as_u128()), account_storage_usage: Some(data.contract_data.account_storage_usage), statistics_aurora_accounts_counter: Some(data.accounts_counter), used_proofs: vec![], @@ -218,8 +210,8 @@ async fn test_migration_state() -> anyhow::Result<()> { }; proofs_count += proofs.len(); let args = MigrationInputData { - accounts_eth: HashMap::new(), - total_eth_supply_on_near: None, + accounts: HashMap::new(), + total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, used_proofs: proofs.to_vec(), @@ -247,15 +239,14 @@ async fn test_migration_state() -> anyhow::Result<()> { accounts_count = 0; for (i, (account, amount)) in data.accounts.iter().enumerate() { let account = AccountId::try_from(account.to_string()).unwrap(); - let amount = NEP141Wei::new(amount.as_u128()); - accounts.insert(account, amount); + accounts.insert(account, amount.as_u128()); if accounts.len() < limit && i < data.accounts.len() - 1 { continue; } accounts_count += accounts.len(); let args = MigrationInputData { - accounts_eth: accounts, - total_eth_supply_on_near: None, + accounts, + total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, used_proofs: vec![], diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index ccea839..4036fd0 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -273,13 +273,13 @@ impl Migration for EthConnectorContract { #[private] fn migrate(&mut self, #[serializer(borsh)] data: MigrationInputData) { // Insert account - for (account, amount) in &data.accounts_eth { + for (account, amount) in &data.accounts { self.ft.accounts.insert(account, amount); } - crate::log!("Inserted accounts_eth: {:?}", data.accounts_eth.len()); + crate::log!("Inserted accounts_eth: {:?}", data.accounts.len()); // Insert total_eth_supply_on_near - if let Some(total_eth_supply_on_near) = data.total_eth_supply_on_near { + if let Some(total_eth_supply_on_near) = data.total_supply { self.ft.total_supply = total_eth_supply_on_near; crate::log!( "Inserted total_eth_supply_on_near: {:?}", @@ -319,7 +319,7 @@ impl Migration for EthConnectorContract { #[serializer(borsh)] data: MigrationInputData, ) -> MigrationCheckResult { // Check accounts - for (account, amount) in &data.accounts_eth { + for (account, amount) in &data.accounts { match self.ft.accounts.get(account) { Some(ref value) => { if value != amount { @@ -343,8 +343,8 @@ impl Migration for EthConnectorContract { return MigrationCheckResult::StorageUsage(self.ft.account_storage_usage); } } - if let Some(total_eth_supply_on_near) = data.total_eth_supply_on_near { - if self.ft.total_supply != total_eth_supply_on_near { + if let Some(total_supply) = data.total_supply { + if self.ft.total_supply != total_supply { return MigrationCheckResult::TotalSupply(self.ft.total_supply); } } diff --git a/eth-connector/src/migration.rs b/eth-connector/src/migration.rs index f504662..0915d42 100644 --- a/eth-connector/src/migration.rs +++ b/eth-connector/src/migration.rs @@ -4,8 +4,8 @@ use std::collections::HashMap; #[derive(BorshDeserialize, BorshSerialize)] pub struct MigrationInputData { - pub accounts_eth: HashMap, - pub total_eth_supply_on_near: Option, + pub accounts: HashMap, + pub total_supply: Option, pub account_storage_usage: Option, pub statistics_aurora_accounts_counter: Option, pub used_proofs: Vec, From b0f5d5870b52ec22abaf26cb3d77464ee2924687 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 30 Nov 2022 00:54:20 +0100 Subject: [PATCH 07/44] Fix tests utils types --- Cargo.lock | 1 + eth-connector-tests/Cargo.toml | 1 + eth-connector-tests/src/connector.rs | 16 ++++++++-------- eth-connector-tests/src/migration.rs | 7 +++---- eth-connector-tests/src/utils.rs | 19 ++++++++++++++++--- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab3134f..4a512a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -219,6 +219,7 @@ dependencies = [ "byte-slice-cast", "ethabi", "hex 0.4.3", + "near-contract-standards", "near-primitives 0.5.0", "near-sdk", "near-units", diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index 285f675..572be0f 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -19,6 +19,7 @@ anyhow = "1.0" near-sdk = "4.0" near-primitives = "0.5" near-units = "0.2" +near-contract-standards = "4.1" tokio = { version = "1.14", features = ["full"] } workspaces = "0.6" byte-slice-cast = "1.2" diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 5bd2d97..370f9f5 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -6,11 +6,11 @@ use aurora_engine_types::{ use aurora_eth_connector::{ connector_impl::WithdrawResult, deposit_event::{DepositedEvent, TokenMessageData, DEPOSITED_EVENT}, - fungible_token::storage_management::StorageBalance, log_entry, proof::Proof, }; use byte_slice_cast::AsByteSlice; +use near_contract_standards::storage_management::StorageBalance; use near_sdk::serde_json::json; use near_sdk::{ json_types::{U128, U64}, @@ -108,7 +108,7 @@ async fn test_withdraw_eth_from_near() -> anyhow::Result<()> { let contract = TestContract::new().await?; contract.call_deposit_eth_to_near().await?; - let withdraw_amount = NEP141Wei::new(100); + let withdraw_amount = 100; let recipient_addr = validate_eth_address(RECIPIENT_ETH_ADDRESS); let receiver_id = AccountId::try_from(DEPOSITED_RECIPIENT.to_string()).unwrap(); let res = contract @@ -130,13 +130,13 @@ async fn test_withdraw_eth_from_near() -> anyhow::Result<()> { let balance = contract .get_eth_on_near_balance(contract.contract.id()) .await?; - assert_eq!(balance.0, DEPOSITED_FEE - withdraw_amount.as_u128()); + assert_eq!(balance.0, DEPOSITED_FEE - withdraw_amount); let balance = contract.get_eth_on_near_balance(&receiver_id).await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT - DEPOSITED_FEE as u128); + assert_eq!(balance.0, DEPOSITED_AMOUNT - DEPOSITED_FEE); let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT - withdraw_amount.as_u128()); + assert_eq!(balance.0, DEPOSITED_AMOUNT - withdraw_amount); Ok(()) } @@ -146,7 +146,7 @@ async fn test_withdraw_eth_from_near_user() -> anyhow::Result<()> { let contract = TestContract::new().await?; contract.call_deposit_eth_to_near().await?; - let withdraw_amount = NEP141Wei::new(100); + let withdraw_amount = 100; let recipient_addr = validate_eth_address(RECIPIENT_ETH_ADDRESS); let user_acc = contract.create_sub_account("eth_recipient").await?; @@ -183,11 +183,11 @@ async fn test_withdraw_eth_from_near_user() -> anyhow::Result<()> { ); assert_eq!( contract.get_eth_on_near_balance(user_acc.id()).await?.0, - DEPOSITED_AMOUNT - DEPOSITED_FEE - withdraw_amount.as_u128() + DEPOSITED_AMOUNT - DEPOSITED_FEE - withdraw_amount ); assert_eq!( contract.total_supply().await?.0, - DEPOSITED_AMOUNT - withdraw_amount.as_u128() + DEPOSITED_AMOUNT - withdraw_amount ); Ok(()) } diff --git a/eth-connector-tests/src/migration.rs b/eth-connector-tests/src/migration.rs index 39cf93e..016c789 100644 --- a/eth-connector-tests/src/migration.rs +++ b/eth-connector-tests/src/migration.rs @@ -1,6 +1,5 @@ use crate::utils::*; use aurora_engine_migration_tool::{BorshDeserialize, StateData}; -use aurora_engine_types::types::NEP141Wei; use aurora_eth_connector::migration::{MigrationCheckResult, MigrationInputData}; use near_sdk::{AccountId, Balance}; use std::collections::HashMap; @@ -81,8 +80,8 @@ async fn test_migration_state() -> anyhow::Result<()> { }; proofs_count += proofs.len(); let args = MigrationInputData { - accounts_eth: HashMap::new(), - total_eth_supply_on_near: None, + accounts: HashMap::new(), + total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, used_proofs: proofs.to_vec(), @@ -125,7 +124,7 @@ async fn test_migration_state() -> anyhow::Result<()> { accounts_count += &accounts.len(); let args = MigrationInputData { - accounts: accounts, + accounts, total_supply: None, account_storage_usage: None, statistics_aurora_accounts_counter: None, diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index a96ce1a..583f336 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -1,5 +1,6 @@ use aurora_engine_types::types::Address; -use aurora_eth_connector::{fungible_token::metadata::FungibleTokenMetadata, proof::Proof}; +use aurora_eth_connector::proof::Proof; +use near_contract_standards::fungible_token::metadata::FungibleTokenMetadata; use near_sdk::serde_json::json; use near_sdk::{json_types::U128, serde_json}; use workspaces::{result::ExecutionFinalResult, Account, AccountId, Contract}; @@ -28,7 +29,7 @@ impl TestContract { let prover_account: AccountId = contract.id().clone(); let eth_custodian_address = CUSTODIAN_ADDRESS; - let metadata = FungibleTokenMetadata::default(); + let metadata = Self::metadata_default(); let account_with_access_right: AccountId = AccountId::from_str(CONTRACT_ACC).unwrap(); // Init eth-connector let res = contract @@ -55,7 +56,7 @@ impl TestContract { let (contract, root_account) = Self::deploy_aurora_contract().await?; let prover_account: AccountId = contract.id().clone(); - let metadata = FungibleTokenMetadata::default(); + let metadata = Self::metadata_default(); let account_with_access_right: AccountId = AccountId::from_str(CONTRACT_ACC).unwrap(); // Init eth-connector let res = contract @@ -218,6 +219,18 @@ impl TestContract { .json::() .unwrap()) } + + fn metadata_default() -> FungibleTokenMetadata { + FungibleTokenMetadata { + symbol: String::default(), + name: String::default(), + spec: String::default(), + icon: None, + reference: None, + reference_hash: None, + decimals: 0, + } + } } pub fn print_logs(res: ExecutionFinalResult) { From 27af7eeddc11d42fe102063b0109c0d82ecfd241 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 30 Nov 2022 01:14:25 +0100 Subject: [PATCH 08/44] Fix tests - register_accounts --- Makefile.toml | 2 +- eth-connector-tests/src/connector.rs | 45 ++++++++++++---------------- eth-connector-tests/src/utils.rs | 27 +++++++++++++++-- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 00c8b68..dca812d 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -174,7 +174,7 @@ category = "Test" command = "${CARGO}" args = [ "test", - # "test_migration", + "test_access_rights", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 370f9f5..0848a88 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -379,7 +379,7 @@ async fn test_deposit_with_0x_prefix() -> anyhow::Result<()> { eth_custodian_address, sender: Address::zero(), token_message_data, - amount: NEP141Wei::new(deposit_amount), + amount: deposit_amount, fee, }; @@ -397,7 +397,7 @@ async fn test_deposit_with_0x_prefix() -> anyhow::Result<()> { ], data: ethabi::encode(&[ ethabi::Token::String(message), - ethabi::Token::Uint(U256::from(deposit_event.amount.as_u128())), + ethabi::Token::Uint(U256::from(deposit_event.amount)), ethabi::Token::Uint(U256::from(deposit_event.fee.as_u128())), ]), }; @@ -596,7 +596,7 @@ async fn test_admin_controlled_admin_can_perform_actions_when_paused() -> anyhow contract.call_deposit_eth_to_near().await?; let recipient_addr: Address = validate_eth_address(RECIPIENT_ETH_ADDRESS); - let withdraw_amount: NEP141Wei = NEP141Wei::new(100); + let withdraw_amount = 100; // 1st withdraw call when unpaused - should succeed let res = contract @@ -747,7 +747,7 @@ async fn test_withdraw_from_near_pausability() -> anyhow::Result<()> { assert!(res.is_success()); let recipient_addr: Address = validate_eth_address(RECIPIENT_ETH_ADDRESS); - let withdraw_amount: NEP141Wei = NEP141Wei::new(100); + let withdraw_amount = 100; // 1st withdraw - should succeed let res = user_acc .call(contract.contract.id(), "withdraw") @@ -1110,8 +1110,7 @@ async fn test_access_rights() -> anyhow::Result<()> { contract.call_deposit_eth_to_near().await?; let transfer_amount1: U128 = 50.into(); - let transfer_amount2: U128 = 3000.into(); - let receiver_id = AccountId::try_from("test.root".to_string()).unwrap(); + let receiver_id = contract.register_user("test.root").await?; let user_acc = contract.create_sub_account("eth_recipient").await?; let res = contract @@ -1137,9 +1136,11 @@ async fn test_access_rights() -> anyhow::Result<()> { ); assert_eq!(0, contract.get_eth_on_near_balance(&receiver_id).await?.0); + let withdraw_amount = 100; + let recipient_addr = validate_eth_address(RECIPIENT_ETH_ADDRESS); let res = user_acc - .call(contract.contract.id(), "ft_transfer") - .args_json((&receiver_id, transfer_amount2, "transfer memo")) + .call(contract.contract.id(), "withdraw") + .args_borsh((contract.contract.id(), recipient_addr, withdraw_amount)) .gas(DEFAULT_GAS) .deposit(ONE_YOCTO) .transact() @@ -1178,30 +1179,22 @@ async fn test_access_rights() -> anyhow::Result<()> { .json::()?; assert_eq!(&res, user_acc.id()); - let res = user_acc - .call(contract.contract.id(), "ft_transfer") - .args_json((&receiver_id, transfer_amount2, "transfer memo")) + let res = contract + .contract + .call("withdraw") + .args_borsh((contract.contract.id(), recipient_addr, withdraw_amount)) .gas(DEFAULT_GAS) .deposit(ONE_YOCTO) .transact() .await?; assert!(res.is_success()); - assert_eq!( - DEPOSITED_AMOUNT - DEPOSITED_FEE + transfer_amount1.0 - transfer_amount2.0, - contract.get_eth_on_near_balance(user_acc.id()).await?.0 - ); - assert_eq!( - DEPOSITED_FEE - transfer_amount1.0, - contract - .get_eth_on_near_balance(contract.contract.id()) - .await? - .0 - ); - assert_eq!( - transfer_amount2.0, - contract.get_eth_on_near_balance(&receiver_id).await?.0 - ); + let data: WithdrawResult = res.borsh()?; + let custodian_addr = validate_eth_address(CUSTODIAN_ADDRESS); + assert_eq!(data.recipient_id, recipient_addr); + assert_eq!(data.amount, withdraw_amount); + assert_eq!(data.eth_custodian_address, custodian_addr); + Ok(()) } diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 583f336..6ddd625 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -1,6 +1,6 @@ use aurora_engine_types::types::Address; use aurora_eth_connector::proof::Proof; -use near_contract_standards::fungible_token::metadata::FungibleTokenMetadata; +use near_contract_standards::fungible_token::metadata::{FungibleTokenMetadata, FT_METADATA_SPEC}; use near_sdk::serde_json::json; use near_sdk::{json_types::U128, serde_json}; use workspaces::{result::ExecutionFinalResult, Account, AccountId, Contract}; @@ -222,15 +222,38 @@ impl TestContract { fn metadata_default() -> FungibleTokenMetadata { FungibleTokenMetadata { + spec: FT_METADATA_SPEC.to_string(), symbol: String::default(), name: String::default(), - spec: String::default(), icon: None, reference: None, reference_hash: None, decimals: 0, } } + + pub async fn register_user(&self, user: &str) -> anyhow::Result { + use near_contract_standards::storage_management::StorageBalanceBounds; + + let bounds = self + .contract + .call("storage_balance_bounds") + .view() + .await? + .json::()?; + + let res = self + .contract + .call("storage_deposit") + .args_json(json!({ "account_id": &user })) + .gas(DEFAULT_GAS) + .deposit(bounds.min.into()) + .transact() + .await?; + assert!(res.is_success()); + + Ok(AccountId::try_from(user.to_string())?) + } } pub fn print_logs(res: ExecutionFinalResult) { From 99a18ad98dba3d96c6e37d2d020600c8a3df5add Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 3 Jun 2022 16:28:49 +0200 Subject: [PATCH 09/44] Fix totsl_supply tests --- Makefile.toml | 2 +- eth-connector-tests/src/connector.rs | 93 +++++----------------------- eth-connector-tests/src/utils.rs | 11 ---- eth-connector/src/lib.rs | 4 +- 4 files changed, 18 insertions(+), 92 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index dca812d..5720b67 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -174,7 +174,7 @@ category = "Test" command = "${CARGO}" args = [ "test", - "test_access_rights", + "test_deposit_pausability", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 0848a88..ba7302a 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -24,7 +24,7 @@ async fn test_ft_transfer() -> anyhow::Result<()> { contract.call_deposit_eth_to_near().await?; let transfer_amount = 70; - let receiver_id = AccountId::try_from(DEPOSITED_RECIPIENT.to_string()).unwrap(); + let receiver_id = contract.register_user(DEPOSITED_RECIPIENT).await?; let res = contract .contract .call("ft_transfer") @@ -47,10 +47,6 @@ async fn test_ft_transfer() -> anyhow::Result<()> { DEPOSITED_FEE - transfer_amount as u128 ); assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); - assert_eq!( - contract.total_eth_supply_on_near().await?.0, - DEPOSITED_AMOUNT - ); Ok(()) } @@ -96,10 +92,6 @@ async fn test_ft_transfer_user() -> anyhow::Result<()> { DEPOSITED_FEE + transfer_amount as u128 ); assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); - assert_eq!( - contract.total_eth_supply_on_near().await?.0, - DEPOSITED_AMOUNT - ); Ok(()) } @@ -210,12 +202,7 @@ async fn test_deposit_eth_to_near_balance_total_supply() -> anyhow::Result<()> { .await?; assert_eq!(balance.0, DEPOSITED_FEE); - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); Ok(()) } @@ -228,13 +215,7 @@ async fn test_deposit_eth_to_aurora_balance_total_supply() -> anyhow::Result<()> contract.call_is_used_proof(PROOF_DATA_ETH).await?, "Expected not to fail because the proof should have been already used", ); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_EVM_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_EVM_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_EVM_AMOUNT); Ok(()) } @@ -281,13 +262,7 @@ async fn test_ft_transfer_call_eth() -> anyhow::Result<()> { .get_eth_on_near_balance(contract.contract.id()) .await?; assert_eq!(balance.0, DEPOSITED_FEE); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); Ok(()) } @@ -349,13 +324,7 @@ async fn test_ft_transfer_call_without_message() -> anyhow::Result<()> { .get_eth_on_near_balance(contract.contract.id()) .await?; assert_eq!(balance.0, DEPOSITED_FEE); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); Ok(()) } @@ -505,13 +474,7 @@ async fn test_ft_transfer_call_without_relayer() -> anyhow::Result<()> { .get_eth_on_near_balance(contract.contract.id()) .await?; assert_eq!(balance.0, DEPOSITED_FEE); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); Ok(()) } @@ -550,13 +513,7 @@ async fn test_ft_transfer_call_fee_greater_than_amount() -> anyhow::Result<()> { .get_eth_on_near_balance(contract.contract.id()) .await?; assert_eq!(balance.0, DEPOSITED_FEE); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); Ok(()) } @@ -716,14 +673,12 @@ async fn test_deposit_pausability() -> anyhow::Result<()> { let res = contract .user_deposit_with_proof(&user_acc, &contract.get_proof(PROOF_DATA_ETH)) .await?; + println!("{:#?}", res); assert!(res.is_success()); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT + DEPOSITED_EVM_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT + DEPOSITED_EVM_AMOUNT); - + assert_eq!( + contract.total_supply().await?.0, + DEPOSITED_AMOUNT + DEPOSITED_EVM_AMOUNT + ); Ok(()) } @@ -866,13 +821,7 @@ async fn test_get_accounts_counter_and_transfer() -> anyhow::Result<()> { .get_eth_on_near_balance(contract.contract.id()) .await?; assert_eq!(balance.0, DEPOSITED_FEE - transfer_amount as u128); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, DEPOSITED_AMOUNT); - + assert_eq!(contract.total_supply().await?.0, DEPOSITED_AMOUNT); let res = contract .contract .call("get_accounts_counter") @@ -908,13 +857,7 @@ async fn test_deposit_to_near_with_zero_fee() -> anyhow::Result<()> { .get_eth_on_near_balance(contract.contract.id()) .await?; assert_eq!(balance.0, 0); - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, deposited_amount); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, deposited_amount); - + assert_eq!(contract.total_supply().await?.0, deposited_amount); Ok(()) } @@ -932,13 +875,7 @@ async fn test_deposit_to_aurora_with_zero_fee() -> anyhow::Result<()> { ); let deposited_amount = 2000; - - let balance = contract.total_supply().await?; - assert_eq!(balance.0, deposited_amount); - - let balance = contract.total_eth_supply_on_near().await?; - assert_eq!(balance.0, deposited_amount); - + assert_eq!(contract.total_supply().await?.0, deposited_amount); Ok(()) } diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 6ddd625..b53c8dc 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -173,17 +173,6 @@ impl TestContract { Ok(res) } - pub async fn total_eth_supply_on_near(&self) -> anyhow::Result { - let res = self - .contract - .call("ft_total_eth_supply_on_near") - .view() - .await? - .json::() - .unwrap(); - Ok(res) - } - pub async fn call_deposit_eth_to_aurora(&self) -> anyhow::Result<()> { let proof: Proof = serde_json::from_str(PROOF_DATA_ETH).unwrap(); let res = self.deposit_with_proof(&proof).await?; diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 4036fd0..3045fd6 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -7,7 +7,7 @@ use crate::proof::Proof; use crate::types::{panic_err, SdkUnwrap}; use aurora_engine_types::types::Address; use near_contract_standards::fungible_token::metadata::{ - FungibleTokenMetadata, FungibleTokenMetadataProvider, + FungibleTokenMetadata, FungibleTokenMetadataProvider, FT_METADATA_SPEC, }; use near_contract_standards::fungible_token::FungibleToken; use near_sdk::store::LookupMap; @@ -136,7 +136,7 @@ near_contract_standards::impl_fungible_token_storage!(EthConnectorContract, ft); impl FungibleTokenMetadataProvider for EthConnectorContract { fn ft_metadata(&self) -> FungibleTokenMetadata { self.metadata.get().map_or(FungibleTokenMetadata { - spec: "ft-1.0.0".to_string(), + spec: FT_METADATA_SPEC.to_string(), name: "Ether".to_string(), symbol: "ETH".to_string(), icon: Some("data:image/png;base64,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".to_string()), From 412baa6caefd0c825c1fa57f958dafdcce37b9d8 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sat, 4 Jun 2022 12:32:49 +0200 Subject: [PATCH 10/44] Removed ft-core macros --- eth-connector/src/lib.rs | 64 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 3045fd6..fed04b0 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -6,9 +6,11 @@ use crate::connector_impl::{ use crate::proof::Proof; use crate::types::{panic_err, SdkUnwrap}; use aurora_engine_types::types::Address; +use near_contract_standards::fungible_token::core::FungibleTokenCore; use near_contract_standards::fungible_token::metadata::{ FungibleTokenMetadata, FungibleTokenMetadataProvider, FT_METADATA_SPEC, }; +use near_contract_standards::fungible_token::resolver::FungibleTokenResolver; use near_contract_standards::fungible_token::FungibleToken; use near_sdk::store::LookupMap; use near_sdk::{ @@ -44,12 +46,14 @@ pub struct EthConnectorContract { ft: FungibleToken, metadata: LazyOption, used_proofs: LookupMap, + accounts_counter: u64, } #[derive(BorshSerialize, BorshStorageKey)] enum StorageKey { - Proof = 0x1, - Metadata = 0x2, + FungibleToken = 0x1, + Proof = 0x2, + Metadata = 0x3, } impl EthConnectorContract { @@ -79,6 +83,14 @@ impl EthConnectorContract { pub fn is_used_event(&self, key: &str) -> bool { self.used_proofs.contains_key(&key.to_string()) } + + // Register user and calculate counter + fn register_if_not_exists(&mut self, account: &AccountId) { + if !self.ft.accounts.contains_key(account) { + self.accounts_counter += 1; + self.ft.internal_register_account(account); + } + } } #[near_bindgen] @@ -103,12 +115,13 @@ impl EthConnectorContract { }; let owner_id = env::current_account_id(); let mut this = Self { - ft: FungibleToken::new(b"t".to_vec()), + ft: FungibleToken::new(StorageKey::FungibleToken), connector: connector_data, metadata: LazyOption::new(StorageKey::Metadata, Some(&metadata)), used_proofs: LookupMap::new(StorageKey::Proof), + accounts_counter: 0, }; - this.ft.accounts.insert(&owner_id, &0); + this.ft.internal_register_account(&owner_id); this } @@ -129,7 +142,48 @@ impl EthConnectorContract { } } -near_contract_standards::impl_fungible_token_core!(EthConnectorContract, ft); +#[near_bindgen] +impl FungibleTokenCore for EthConnectorContract { + #[payable] + fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option) { + self.register_if_not_exists(&receiver_id); + self.ft.ft_transfer(receiver_id, amount, memo) + } + + #[payable] + fn ft_transfer_call( + &mut self, + receiver_id: AccountId, + amount: U128, + memo: Option, + msg: String, + ) -> PromiseOrValue { + self.register_if_not_exists(&receiver_id); + self.ft.ft_transfer_call(receiver_id, amount, memo, msg) + } + + fn ft_total_supply(&self) -> U128 { + self.ft.ft_total_supply() + } + + fn ft_balance_of(&self, account_id: AccountId) -> U128 { + self.ft.ft_balance_of(account_id) + } +} + +#[near_bindgen] +impl FungibleTokenResolver for EthConnectorContract { + #[private] + fn ft_resolve_transfer( + &mut self, + sender_id: AccountId, + receiver_id: AccountId, + amount: U128, + ) -> U128 { + self.ft.ft_resolve_transfer(sender_id, receiver_id, amount) + } +} + near_contract_standards::impl_fungible_token_storage!(EthConnectorContract, ft); #[near_bindgen] From 6b07fcde8e7a3c1d010de8eebd4a4d5ba78849ef Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 5 Jun 2022 09:53:41 +0200 Subject: [PATCH 11/44] Added custom transfer call --- eth-connector/src/lib.rs | 52 +++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index fed04b0..2f0a518 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -10,7 +10,8 @@ use near_contract_standards::fungible_token::core::FungibleTokenCore; use near_contract_standards::fungible_token::metadata::{ FungibleTokenMetadata, FungibleTokenMetadataProvider, FT_METADATA_SPEC, }; -use near_contract_standards::fungible_token::resolver::FungibleTokenResolver; +use near_contract_standards::fungible_token::receiver::ext_ft_receiver; +use near_contract_standards::fungible_token::resolver::{ext_ft_resolver, FungibleTokenResolver}; use near_contract_standards::fungible_token::FungibleToken; use near_sdk::store::LookupMap; use near_sdk::{ @@ -58,7 +59,7 @@ enum StorageKey { impl EthConnectorContract { /// Mint nETH tokens - pub fn mint_eth_on_near(&mut self, owner_id: AccountId, amount: Balance) { + fn mint_eth_on_near(&mut self, owner_id: AccountId, amount: Balance) { crate::log!("Mint {} nETH tokens for: {}", amount, owner_id); // Create account to avoid panic with deposit if self.ft.accounts.get(&owner_id).is_none() { @@ -68,19 +69,17 @@ impl EthConnectorContract { } /// Record used proof as hash key - pub fn record_proof(&mut self, key: &str) -> Result<(), errors::ProofUsed> { + fn record_proof(&mut self, key: &str) -> Result<(), errors::ProofUsed> { crate::log!("Record proof: {}", key); - if self.is_used_event(key) { return Err(errors::ProofUsed); } - self.used_proofs.insert(key.to_string(), true); Ok(()) } /// Check is event of proof already used - pub fn is_used_event(&self, key: &str) -> bool { + fn is_used_event(&self, key: &str) -> bool { self.used_proofs.contains_key(&key.to_string()) } @@ -91,6 +90,38 @@ impl EthConnectorContract { self.ft.internal_register_account(account); } } + + fn finish_deposit_transfer_call( + &mut self, + receiver_id: AccountId, + amount: U128, + memo: Option, + msg: String, + ) -> PromiseOrValue { + use near_sdk::Gas; + const GAS_FOR_RESOLVE_TRANSFER: Gas = Gas(5_000_000_000_000); + const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(25_000_000_000_000 + GAS_FOR_RESOLVE_TRANSFER.0); + + let sender_id = env::predecessor_account_id(); + crate::log!("{:?} {:?}", &sender_id, &receiver_id); + let amount: Balance = amount.into(); + self.ft + .internal_transfer(&sender_id, &receiver_id, amount, memo); + let receiver_gas = env::prepaid_gas() + .0 + .checked_sub(GAS_FOR_FT_TRANSFER_CALL.0) + .unwrap_or_else(|| env::panic_str("Prepaid gas overflow")); + // Initiating receiver's call and the callback + ext_ft_receiver::ext(receiver_id.clone()) + .with_static_gas(receiver_gas.into()) + .ft_on_transfer(sender_id.clone(), amount.into(), msg) + .then( + ext_ft_resolver::ext(env::current_account_id()) + .with_static_gas(GAS_FOR_RESOLVE_TRANSFER) + .ft_resolve_transfer(sender_id, receiver_id, amount.into()), + ) + .into() + } } #[near_bindgen] @@ -296,9 +327,12 @@ impl ConnectorFundsFinish for EthConnectorContract { let data: TransferCallCallArgs = TransferCallCallArgs::try_from_slice(&msg) .map_err(|_| crate::errors::ERR_BORSH_DESERIALIZE) .sdk_unwrap(); - let promise = - self.ft - .ft_transfer_call(data.receiver_id, data.amount.into(), data.memo, data.msg); + let promise = self.finish_deposit_transfer_call( + data.receiver_id, + data.amount.into(), + data.memo, + data.msg, + ); match promise { PromiseOrValue::Promise(p) => PromiseOrValue::Promise(p), PromiseOrValue::Value(v) => PromiseOrValue::Value(Some(v)), From 08b6b7fc2966677650fea34a7e3a8060a7f34693 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 6 Jun 2022 03:01:21 +0200 Subject: [PATCH 12/44] Fix test_deposit_pausability --- eth-connector-tests/src/connector.rs | 1 - eth-connector/src/lib.rs | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index ba7302a..60f9ebd 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -673,7 +673,6 @@ async fn test_deposit_pausability() -> anyhow::Result<()> { let res = contract .user_deposit_with_proof(&user_acc, &contract.get_proof(PROOF_DATA_ETH)) .await?; - println!("{:#?}", res); assert!(res.is_success()); assert_eq!( contract.total_supply().await?.0, diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 2f0a518..81f0e1d 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -3,6 +3,7 @@ use crate::connector::{ConnectorDeposit, ConnectorFundsFinish, ConnectorWithdraw use crate::connector_impl::{ EthConnector, FinishDepositCallArgs, TransferCallCallArgs, WithdrawResult, }; +use crate::deposit_event::FtTransferMessageData; use crate::proof::Proof; use crate::types::{panic_err, SdkUnwrap}; use aurora_engine_types::types::Address; @@ -103,10 +104,28 @@ impl EthConnectorContract { const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(25_000_000_000_000 + GAS_FOR_RESOLVE_TRANSFER.0); let sender_id = env::predecessor_account_id(); - crate::log!("{:?} {:?}", &sender_id, &receiver_id); let amount: Balance = amount.into(); - self.ft - .internal_transfer(&sender_id, &receiver_id, amount, memo); + crate::log!( + "Transfer call from {} to {} amount {}", + sender_id, + receiver_id, + amount, + ); + + // Verify message data before `ft_on_transfer` call to avoid verification panics + // It's allowed empty message if `receiver_id =! current_account_id` + if sender_id == receiver_id { + let message_data = FtTransferMessageData::parse_on_transfer_message(&msg).sdk_unwrap(); + // Check is transfer amount > fee + if message_data.fee.as_u128() >= amount { + panic_err("insufficient balance"); + } + } + + if sender_id != receiver_id { + self.ft + .internal_transfer(&sender_id, &receiver_id, amount, memo); + } let receiver_gas = env::prepaid_gas() .0 .checked_sub(GAS_FOR_FT_TRANSFER_CALL.0) From 327d96ec9d71a8c7e27ee01a1470e6c9d1c23767 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 7 Jun 2022 15:28:19 +0200 Subject: [PATCH 13/44] Migration tests - increase gas cost --- Makefile.toml | 8 +++++++- eth-connector-tests/src/connector.rs | 4 ++-- eth-connector-tests/src/migration.rs | 11 +++++++---- eth-connector/src/lib.rs | 4 +++- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 5720b67..359bcff 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -174,7 +174,13 @@ category = "Test" command = "${CARGO}" args = [ "test", - "test_deposit_pausability", +# "test_ft_transfer_call_fee_greater_than_amount", +# "test_ft_transfer_max_value", +# "test_get_accounts_counter", +# "test_get_accounts_counter_and_transfer", +# "ctest_storage_deposit", +# "test_storage_withdraw", + "test_migration_state", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 60f9ebd..ca57459 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -247,14 +247,13 @@ async fn test_ft_transfer_call_eth() -> anyhow::Result<()> { let res = contract .contract .call("ft_transfer_call") - .args_json((contract.contract.id(), transfer_amount, memo, message)) + .args_json((&receiver_id, transfer_amount, memo, message)) .gas(DEFAULT_GAS) .deposit(ONE_YOCTO) .transact() .await?; assert!(res.is_success()); - let receiver_id = AccountId::try_from(DEPOSITED_RECIPIENT.to_string()).unwrap(); let balance = contract.get_eth_on_near_balance(&receiver_id).await?; assert_eq!(balance.0, DEPOSITED_AMOUNT - DEPOSITED_FEE); @@ -502,6 +501,7 @@ async fn test_ft_transfer_call_fee_greater_than_amount() -> anyhow::Result<()> { .deposit(ONE_YOCTO) .transact() .await?; + println!("{:?}", res); assert!(res.is_failure()); assert!(contract.check_error_message(res, "ERR_NOT_ENOUGH_BALANCE_FOR_FEE")); diff --git a/eth-connector-tests/src/migration.rs b/eth-connector-tests/src/migration.rs index 016c789..2bddd6b 100644 --- a/eth-connector-tests/src/migration.rs +++ b/eth-connector-tests/src/migration.rs @@ -65,7 +65,7 @@ async fn test_migration_state() -> anyhow::Result<()> { let data = std::fs::read("../contract_state.borsh").expect("Test state data not found"); let data: StateData = StateData::try_from_slice(&data[..]).unwrap(); - let limit = 2000; + let limit = 1000; let mut i = 0; let mut total_gas_burnt = 0; @@ -107,7 +107,8 @@ async fn test_migration_state() -> anyhow::Result<()> { } } assert_eq!(proofs_count, data.proofs.len()); - assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 5416.1); + // INCREASED! + //assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 5416.1); total_gas_burnt += proofs_gas_burnt; println!(); @@ -149,7 +150,8 @@ async fn test_migration_state() -> anyhow::Result<()> { accounts = HashMap::new(); } assert_eq!(data.accounts.len(), accounts_count); - assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1457.); + // INCREASED! + //assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1457.); total_gas_burnt += accounts_gas_burnt; // Migrate Contract data @@ -169,7 +171,8 @@ async fn test_migration_state() -> anyhow::Result<()> { .await?; assert!(res.is_success()); total_gas_burnt += res.total_gas_burnt; - assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 6878.6); + // INCREASED! + //assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 6878.6); println!( "Total Gas burnt: {:.1} TGas\n", diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 81f0e1d..f1cb011 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -122,6 +122,7 @@ impl EthConnectorContract { } } + // Special case for Aurora transfer itself - we shouldn't transfer if sender_id != receiver_id { self.ft .internal_transfer(&sender_id, &receiver_id, amount, memo); @@ -209,7 +210,8 @@ impl FungibleTokenCore for EthConnectorContract { msg: String, ) -> PromiseOrValue { self.register_if_not_exists(&receiver_id); - self.ft.ft_transfer_call(receiver_id, amount, memo, msg) + self.finish_deposit_transfer_call(receiver_id, amount, memo, msg) + //self.ft.ft_transfer_call(receiver_id, amount, memo, msg) } fn ft_total_supply(&self) -> U128 { From 92d7fdf59ca94804d893f4d00b41a171ac071205 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 1 Jun 2022 12:01:12 +0200 Subject: [PATCH 14/44] Refactored accounts counter --- eth-connector/src/connector.rs | 6 ++ eth-connector/src/lib.rs | 25 +++---- eth-connector/src/wei.rs | 129 --------------------------------- 3 files changed, 18 insertions(+), 142 deletions(-) delete mode 100644 eth-connector/src/wei.rs diff --git a/eth-connector/src/connector.rs b/eth-connector/src/connector.rs index 536b95c..418fc5e 100644 --- a/eth-connector/src/connector.rs +++ b/eth-connector/src/connector.rs @@ -1,5 +1,6 @@ use crate::{connector_impl::FinishDepositCallArgs, Proof, WithdrawResult}; use aurora_engine_types::types::Address; +use near_sdk::json_types::U64; use near_sdk::{ borsh, ext_contract, json_types::{Base64VecU8, U128}, @@ -38,3 +39,8 @@ pub trait ProofVerifier { #[result_serializer(borsh)] fn verify_log_entry(&self, #[serializer(borsh)] raw_proof: Base64VecU8) -> bool; } + +#[ext_contract(ext_ft_statistic)] +pub trait FungibleTokeStatistic { + fn get_accounts_counter(&self) -> U64; +} diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index f1cb011..ea33e9b 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -1,5 +1,7 @@ use crate::admin_controlled::{AdminControlled, PausedMask, PAUSE_WITHDRAW, UNPAUSE_ALL}; -use crate::connector::{ConnectorDeposit, ConnectorFundsFinish, ConnectorWithdraw}; +use crate::connector::{ + ConnectorDeposit, ConnectorFundsFinish, ConnectorWithdraw, FungibleTokeStatistic, +}; use crate::connector_impl::{ EthConnector, FinishDepositCallArgs, TransferCallCallArgs, WithdrawResult, }; @@ -14,6 +16,7 @@ use near_contract_standards::fungible_token::metadata::{ use near_contract_standards::fungible_token::receiver::ext_ft_receiver; use near_contract_standards::fungible_token::resolver::{ext_ft_resolver, FungibleTokenResolver}; use near_contract_standards::fungible_token::FungibleToken; +use near_sdk::json_types::U64; use near_sdk::store::LookupMap; use near_sdk::{ assert_one_yocto, @@ -34,7 +37,6 @@ pub mod log_entry; pub mod migration; pub mod proof; pub mod types; -pub mod wei; /// Eth-connector contract data. It's stored in the storage. /// Contains: @@ -253,14 +255,13 @@ impl FungibleTokenMetadataProvider for EthConnectorContract { } } -/* #[near_bindgen] impl FungibleTokeStatistic for EthConnectorContract { #[result_serializer(borsh)] fn get_accounts_counter(&self) -> U64 { - self.ft.get_accounts_counter() + self.accounts_counter.into() } -}*/ +} #[near_bindgen] impl AdminControlled for EthConnectorContract { @@ -457,14 +458,12 @@ impl Migration for EthConnectorContract { return MigrationCheckResult::TotalSupply(self.ft.total_supply); } } - // TODO - // if let Some(statistics_aurora_accounts_counter) = data.statistics_aurora_accounts_counter { - // if self.ft.statistics_aurora_accounts_counter != statistics_aurora_accounts_counter { - // return MigrationCheckResult::StatisticsCounter( - // self.ft.statistics_aurora_accounts_counter, - // ); - // } - // } + + if let Some(statistics_aurora_accounts_counter) = data.statistics_aurora_accounts_counter { + if self.accounts_counter != statistics_aurora_accounts_counter { + return MigrationCheckResult::StatisticsCounter(self.accounts_counter); + } + } MigrationCheckResult::Success } } diff --git a/eth-connector/src/wei.rs b/eth-connector/src/wei.rs deleted file mode 100644 index 8df47d8..0000000 --- a/eth-connector/src/wei.rs +++ /dev/null @@ -1,129 +0,0 @@ -use aurora_engine_types::types::balance::error::BalanceOverflowError; -use aurora_engine_types::types::{Fee, NEP141Wei}; -use aurora_engine_types::U256; -use byte_slice_cast::AsByteSlice; -use near_sdk::borsh::{maybestd::io, BorshDeserialize, BorshSerialize}; -use near_sdk::json_types::U128; -use std::io::Write; -use std::ops::{Add, Sub}; - -#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub struct Wei(U256); - -impl Wei { - const ETH_TO_WEI: U256 = U256([1_000_000_000_000_000_000, 0, 0, 0]); - - pub const fn zero() -> Self { - Self(U256([0, 0, 0, 0])) - } - - pub const fn new(amount: U256) -> Self { - Self(amount) - } - - // Purposely not implementing `From` because I want the call site to always - // say `Wei::`. If `From` is implemented then the caller might write - // `amount.into()` without thinking too hard about the units. Explicitly writing - // `Wei` reminds the developer to think about whether the amount they enter is really - // in units of `Wei` or not. - pub const fn new_u64(amount: u64) -> Self { - Self(U256([amount, 0, 0, 0])) - } - - pub fn from_eth(amount: U256) -> Option { - amount.checked_mul(Self::ETH_TO_WEI).map(Self) - } - - pub fn to_bytes(self) -> [u8; 32] { - u256_to_arr(&self.0) - } - - pub fn is_zero(&self) -> bool { - self.0.is_zero() - } - - pub fn raw(self) -> U256 { - self.0 - } - - pub fn checked_sub(self, rhs: Self) -> Option { - self.0.checked_sub(rhs.0).map(Self) - } - - pub fn checked_add(self, rhs: Self) -> Option { - self.0.checked_add(rhs.0).map(Self) - } - - /// Try convert U256 to u128 with checking overflow. - /// NOTICE: Error can contain only overflow - pub fn try_into_u128(self) -> Result { - self.0.try_into().map_err(|_| BalanceOverflowError) - } -} - -impl BorshSerialize for Wei { - fn serialize(&self, writer: &mut W) -> std::io::Result<()> { - writer.write_all(self.0.as_byte_slice()) - } -} - -impl BorshDeserialize for Wei { - fn deserialize(buf: &mut &[u8]) -> io::Result { - if buf.len() < 32 { - return Err(io::Error::new( - io::ErrorKind::Other, - "IncorrectLength".to_string(), - )); - } - let result = U256::from_little_endian(buf[..32].as_byte_slice()); - *buf = &buf[32..]; - Ok(Wei::new(result)) - } -} - -impl std::fmt::Display for Wei { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl Add for Wei { - type Output = Wei; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -impl Sub for Wei { - type Output = Wei; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -impl From for Wei { - fn from(value: NEP141Wei) -> Self { - Wei(U256::from(value.as_u128())) - } -} - -impl From for Wei { - fn from(value: U128) -> Self { - Wei(U256::from(value.0)) - } -} - -#[allow(dead_code)] -pub fn u256_to_arr(value: &U256) -> [u8; 32] { - let mut result = [0u8; 32]; - value.to_big_endian(&mut result); - result -} - -impl From for Wei { - fn from(value: Fee) -> Self { - Wei(U256::from(value.as_u128())) - } -} From fca64ed6e5131b7027debfbcfc78459f8b476973 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Thu, 9 Jun 2022 17:41:13 +0200 Subject: [PATCH 15/44] Fix account counter --- Makefile.toml | 5 +---- eth-connector-tests/src/connector.rs | 1 + eth-connector/src/lib.rs | 6 ++---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 359bcff..e0aec66 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -176,11 +176,8 @@ args = [ "test", # "test_ft_transfer_call_fee_greater_than_amount", # "test_ft_transfer_max_value", -# "test_get_accounts_counter", -# "test_get_accounts_counter_and_transfer", -# "ctest_storage_deposit", +# "test_storage_deposit", # "test_storage_withdraw", - "test_migration_state", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index ca57459..300a702 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -508,6 +508,7 @@ async fn test_ft_transfer_call_fee_greater_than_amount() -> anyhow::Result<()> { let receiver_id = AccountId::try_from(DEPOSITED_RECIPIENT.to_string()).unwrap(); let balance = contract.get_eth_on_near_balance(&receiver_id).await?; assert_eq!(balance.0, DEPOSITED_AMOUNT - DEPOSITED_FEE); + assert_eq!(balance.0, DEPOSITED_AMOUNT - DEPOSITED_FEE); let balance = contract .get_eth_on_near_balance(contract.contract.id()) diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index ea33e9b..294cd65 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -65,9 +65,7 @@ impl EthConnectorContract { fn mint_eth_on_near(&mut self, owner_id: AccountId, amount: Balance) { crate::log!("Mint {} nETH tokens for: {}", amount, owner_id); // Create account to avoid panic with deposit - if self.ft.accounts.get(&owner_id).is_none() { - self.ft.accounts.insert(&owner_id, &0); - } + self.register_if_not_exists(&owner_id); self.ft.internal_deposit(&owner_id, amount) } @@ -174,7 +172,7 @@ impl EthConnectorContract { used_proofs: LookupMap::new(StorageKey::Proof), accounts_counter: 0, }; - this.ft.internal_register_account(&owner_id); + this.register_if_not_exists(&owner_id); this } From c2c710a001c992e4b14c3e056928414049a7324d Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 10 Jun 2022 19:07:20 +0200 Subject: [PATCH 16/44] Fix test_storage_withdraw --- Makefile.toml | 2 +- eth-connector-tests/src/connector.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index e0aec66..f70c76a 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -177,7 +177,7 @@ args = [ # "test_ft_transfer_call_fee_greater_than_amount", # "test_ft_transfer_max_value", # "test_storage_deposit", -# "test_storage_withdraw", + "test_storage_withdraw", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 300a702..86a4c7e 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -1150,6 +1150,7 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(10) .transact() .await?; + println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); @@ -1165,6 +1166,7 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(10) .transact() .await?; + println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); @@ -1186,6 +1188,9 @@ async fn test_storage_withdraw() -> anyhow::Result<()> { .transact() .await?; assert!(res.is_failure()); - assert!(contract.check_error_message(res, "ERR_NO_AVAILABLE_BALANCE")); + assert!(contract.check_error_message( + res, + "The amount is greater than the available storage balance" + )); Ok(()) } From c13c9af27941cf1378b587a0fd3beea3b072e6b1 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 10 Jun 2022 17:32:23 +0200 Subject: [PATCH 17/44] Fix test_storage_withdraw --- Makefile.toml | 2 +- eth-connector-tests/src/connector.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index e0aec66..f70c76a 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -177,7 +177,7 @@ args = [ # "test_ft_transfer_call_fee_greater_than_amount", # "test_ft_transfer_max_value", # "test_storage_deposit", -# "test_storage_withdraw", + "test_storage_withdraw", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 300a702..86a4c7e 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -1150,6 +1150,7 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(10) .transact() .await?; + println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); @@ -1165,6 +1166,7 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(10) .transact() .await?; + println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); @@ -1186,6 +1188,9 @@ async fn test_storage_withdraw() -> anyhow::Result<()> { .transact() .await?; assert!(res.is_failure()); - assert!(contract.check_error_message(res, "ERR_NO_AVAILABLE_BALANCE")); + assert!(contract.check_error_message( + res, + "The amount is greater than the available storage balance" + )); Ok(()) } From f38d7ea43a28ec0b5d7231e5aac685c607d64155 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sat, 11 Jun 2022 07:36:12 +0200 Subject: [PATCH 18/44] Fix test_storage_deposit --- Makefile.toml | 3 +-- eth-connector-tests/src/connector.rs | 17 +++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index f70c76a..1899e18 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -176,8 +176,7 @@ args = [ "test", # "test_ft_transfer_call_fee_greater_than_amount", # "test_ft_transfer_max_value", -# "test_storage_deposit", - "test_storage_withdraw", + "test_storage_deposit", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 86a4c7e..1e03eb7 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -10,7 +10,7 @@ use aurora_eth_connector::{ proof::Proof, }; use byte_slice_cast::AsByteSlice; -use near_contract_standards::storage_management::StorageBalance; +use near_contract_standards::storage_management::{StorageBalance, StorageBalanceBounds}; use near_sdk::serde_json::json; use near_sdk::{ json_types::{U128, U64}, @@ -1140,6 +1140,13 @@ async fn test_storage_deposit() -> anyhow::Result<()> { let contract = TestContract::new().await?; let user_acc = contract.create_sub_account("eth_recipient").await?; + let bounds = contract + .contract + .call("storage_balance_bounds") + .view() + .await? + .json::()?; + let res = contract .contract .call("storage_deposit") @@ -1147,14 +1154,13 @@ async fn test_storage_deposit() -> anyhow::Result<()> { "account_id": &user_acc.id() })) .gas(DEFAULT_GAS) - .deposit(10) + .deposit(bounds.min.0) .transact() .await?; - println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); - assert_eq!(balance.total.0, 0); + assert!(balance.total.0 >= bounds.min.0); let res = contract .contract @@ -1166,11 +1172,10 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(10) .transact() .await?; - println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); - assert_eq!(balance.total.0, 0); + assert!(balance.total.0 >= bounds.min.0); Ok(()) } From 4e66f7606393d76a4d4b86d589d97adaadb91e41 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 12 Jun 2022 11:59:10 +0200 Subject: [PATCH 19/44] Fix test_ft_transfer_max_value --- eth-connector-tests/src/connector.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index 16318b0..dc98c7c 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -997,7 +997,10 @@ async fn test_ft_transfer_max_value() -> anyhow::Result<()> { .transact() .await?; assert!(res.is_failure()); - assert!(contract.check_error_message(res, "ERR_NOT_ENOUGH_BALANCE")); + assert!(contract.check_error_message( + res, + "Smart contract panicked: The account doesn't have enough balance" + )); Ok(()) } From 8898ca1e716047948e8db41d2c5857ed6e770a04 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 13 Jun 2022 20:01:16 +0200 Subject: [PATCH 20/44] Fix all tests --- Makefile.toml | 2 -- eth-connector-tests/src/connector.rs | 5 +---- eth-connector/src/lib.rs | 5 ++--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 6528e2b..7b874bf 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -174,8 +174,6 @@ category = "Test" command = "${CARGO}" args = [ "test", -# "test_ft_transfer_call_fee_greater_than_amount", - "test_ft_transfer_max_value", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/connector.rs b/eth-connector-tests/src/connector.rs index dc98c7c..5a364d9 100644 --- a/eth-connector-tests/src/connector.rs +++ b/eth-connector-tests/src/connector.rs @@ -501,9 +501,8 @@ async fn test_ft_transfer_call_fee_greater_than_amount() -> anyhow::Result<()> { .deposit(ONE_YOCTO) .transact() .await?; - println!("{:?}", res); assert!(res.is_failure()); - assert!(contract.check_error_message(res, "ERR_NOT_ENOUGH_BALANCE_FOR_FEE")); + assert!(contract.check_error_message(res, "insufficient balance for fee")); let receiver_id = AccountId::try_from(DEPOSITED_RECIPIENT.to_string()).unwrap(); let balance = contract.get_eth_on_near_balance(&receiver_id).await?; @@ -1160,7 +1159,6 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(bounds.min.0) .transact() .await?; - println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); @@ -1176,7 +1174,6 @@ async fn test_storage_deposit() -> anyhow::Result<()> { .deposit(10) .transact() .await?; - println!("{:#?}", res); assert!(res.is_success()); let balance = res.json::()?; assert_eq!(balance.available.0, 0); diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 294cd65..21f2940 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -118,7 +118,7 @@ impl EthConnectorContract { let message_data = FtTransferMessageData::parse_on_transfer_message(&msg).sdk_unwrap(); // Check is transfer amount > fee if message_data.fee.as_u128() >= amount { - panic_err("insufficient balance"); + panic_err("insufficient balance for fee"); } } @@ -406,8 +406,7 @@ impl Migration for EthConnectorContract { // Insert statistics_aurora_accounts_counter if let Some(statistics_aurora_accounts_counter) = data.statistics_aurora_accounts_counter { - // TODO: - //self.ft.statistics_aurora_accounts_counter = statistics_aurora_accounts_counter; + self.accounts_counter = statistics_aurora_accounts_counter; crate::log!( "Inserted statistics_aurora_accounts_counter: {:?}", statistics_aurora_accounts_counter From 11a161c80e2db892fffb98e433d4b26cf9593426 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Thu, 1 Dec 2022 17:12:31 +0100 Subject: [PATCH 21/44] Resolve ft_transfer_call --- eth-connector/src/lib.rs | 104 +++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 59 deletions(-) diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 21f2940..7a766a2 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -91,57 +91,6 @@ impl EthConnectorContract { self.ft.internal_register_account(account); } } - - fn finish_deposit_transfer_call( - &mut self, - receiver_id: AccountId, - amount: U128, - memo: Option, - msg: String, - ) -> PromiseOrValue { - use near_sdk::Gas; - const GAS_FOR_RESOLVE_TRANSFER: Gas = Gas(5_000_000_000_000); - const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(25_000_000_000_000 + GAS_FOR_RESOLVE_TRANSFER.0); - - let sender_id = env::predecessor_account_id(); - let amount: Balance = amount.into(); - crate::log!( - "Transfer call from {} to {} amount {}", - sender_id, - receiver_id, - amount, - ); - - // Verify message data before `ft_on_transfer` call to avoid verification panics - // It's allowed empty message if `receiver_id =! current_account_id` - if sender_id == receiver_id { - let message_data = FtTransferMessageData::parse_on_transfer_message(&msg).sdk_unwrap(); - // Check is transfer amount > fee - if message_data.fee.as_u128() >= amount { - panic_err("insufficient balance for fee"); - } - } - - // Special case for Aurora transfer itself - we shouldn't transfer - if sender_id != receiver_id { - self.ft - .internal_transfer(&sender_id, &receiver_id, amount, memo); - } - let receiver_gas = env::prepaid_gas() - .0 - .checked_sub(GAS_FOR_FT_TRANSFER_CALL.0) - .unwrap_or_else(|| env::panic_str("Prepaid gas overflow")); - // Initiating receiver's call and the callback - ext_ft_receiver::ext(receiver_id.clone()) - .with_static_gas(receiver_gas.into()) - .ft_on_transfer(sender_id.clone(), amount.into(), msg) - .then( - ext_ft_resolver::ext(env::current_account_id()) - .with_static_gas(GAS_FOR_RESOLVE_TRANSFER) - .ft_resolve_transfer(sender_id, receiver_id, amount.into()), - ) - .into() - } } #[near_bindgen] @@ -210,8 +159,49 @@ impl FungibleTokenCore for EthConnectorContract { msg: String, ) -> PromiseOrValue { self.register_if_not_exists(&receiver_id); - self.finish_deposit_transfer_call(receiver_id, amount, memo, msg) - //self.ft.ft_transfer_call(receiver_id, amount, memo, msg) + use near_sdk::Gas; + const GAS_FOR_RESOLVE_TRANSFER: Gas = Gas(5_000_000_000_000); + const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(25_000_000_000_000 + GAS_FOR_RESOLVE_TRANSFER.0); + + let sender_id = env::predecessor_account_id(); + let amount: Balance = amount.into(); + crate::log!( + "Transfer call from {} to {} amount {}", + sender_id, + receiver_id, + amount, + ); + + // Verify message data before `ft_on_transfer` call to avoid verification panics + // It's allowed empty message if `receiver_id =! current_account_id` + if sender_id == receiver_id { + let message_data = FtTransferMessageData::parse_on_transfer_message(&msg).sdk_unwrap(); + // Check is transfer amount > fee + if message_data.fee.as_u128() >= amount { + panic_err("insufficient balance for fee"); + } + } + + // Special case for Aurora transfer itself - we shouldn't transfer + if sender_id != receiver_id { + self.ft + .internal_transfer(&sender_id, &receiver_id, amount, memo); + } + + let receiver_gas = env::prepaid_gas() + .0 + .checked_sub(GAS_FOR_FT_TRANSFER_CALL.0) + .unwrap_or_else(|| env::panic_str("Prepaid gas overflow")); + // Initiating receiver's call and the callback + ext_ft_receiver::ext(receiver_id.clone()) + .with_static_gas(receiver_gas.into()) + .ft_on_transfer(sender_id.clone(), amount.into(), msg) + .then( + ext_ft_resolver::ext(env::current_account_id()) + .with_static_gas(GAS_FOR_RESOLVE_TRANSFER) + .ft_resolve_transfer(sender_id, receiver_id, amount.into()), + ) + .into() } fn ft_total_supply(&self) -> U128 { @@ -347,12 +337,8 @@ impl ConnectorFundsFinish for EthConnectorContract { let data: TransferCallCallArgs = TransferCallCallArgs::try_from_slice(&msg) .map_err(|_| crate::errors::ERR_BORSH_DESERIALIZE) .sdk_unwrap(); - let promise = self.finish_deposit_transfer_call( - data.receiver_id, - data.amount.into(), - data.memo, - data.msg, - ); + let promise = + self.ft_transfer_call(data.receiver_id, data.amount.into(), data.memo, data.msg); match promise { PromiseOrValue::Promise(p) => PromiseOrValue::Promise(p), PromiseOrValue::Value(v) => PromiseOrValue::Value(Some(v)), From 84854b8c06ec51e50cd8bde9cd23fbb623ca5786 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 6 Dec 2022 00:08:06 +0100 Subject: [PATCH 22/44] Added migtarion tests gas cost assertions --- eth-connector-tests/src/migration.rs | 3 ++ eth-connector/src/errors.rs | 73 ---------------------------- 2 files changed, 3 insertions(+), 73 deletions(-) diff --git a/eth-connector-tests/src/migration.rs b/eth-connector-tests/src/migration.rs index 2bddd6b..6f57fcb 100644 --- a/eth-connector-tests/src/migration.rs +++ b/eth-connector-tests/src/migration.rs @@ -109,6 +109,7 @@ async fn test_migration_state() -> anyhow::Result<()> { assert_eq!(proofs_count, data.proofs.len()); // INCREASED! //assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 5416.1); + assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 10325.0); total_gas_burnt += proofs_gas_burnt; println!(); @@ -152,6 +153,7 @@ async fn test_migration_state() -> anyhow::Result<()> { assert_eq!(data.accounts.len(), accounts_count); // INCREASED! //assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1457.); + assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1518.1); total_gas_burnt += accounts_gas_burnt; // Migrate Contract data @@ -173,6 +175,7 @@ async fn test_migration_state() -> anyhow::Result<()> { total_gas_burnt += res.total_gas_burnt; // INCREASED! //assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 6878.6); + assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 11849.); println!( "Total Gas burnt: {:.1} TGas\n", diff --git a/eth-connector/src/errors.rs b/eth-connector/src/errors.rs index 17549e1..f68514b 100644 --- a/eth-connector/src/errors.rs +++ b/eth-connector/src/errors.rs @@ -1,65 +1,9 @@ -pub const ERR_NOT_A_JSON_TYPE: &[u8; 19] = b"ERR_NOT_A_JSON_TYPE"; -pub const ERR_JSON_MISSING_VALUE: &[u8; 22] = b"ERR_JSON_MISSING_VALUE"; -pub const ERR_FAILED_PARSE_U8: &[u8; 19] = b"ERR_FAILED_PARSE_U8"; -pub const ERR_FAILED_PARSE_U64: &[u8; 20] = b"ERR_FAILED_PARSE_U64"; -pub const ERR_FAILED_PARSE_U128: &[u8; 21] = b"ERR_FAILED_PARSE_U128"; -pub const ERR_FAILED_PARSE_BOOL: &[u8; 21] = b"ERR_FAILED_PARSE_BOOL"; -pub const ERR_FAILED_PARSE_STRING: &[u8; 23] = b"ERR_FAILED_PARSE_STRING"; -pub const ERR_FAILED_PARSE_ARRAY: &[u8; 22] = b"ERR_FAILED_PARSE_ARRAY"; -pub const ERR_EXPECTED_STRING_GOT_NUMBER: &[u8; 30] = b"ERR_EXPECTED_STRING_GOT_NUMBER"; -pub const ERR_OUT_OF_RANGE_U8: &[u8; 19] = b"ERR_OUT_OF_RANGE_U8"; -pub const ERR_OUT_OF_RANGE_U128: &[u8; 21] = b"ERR_OUT_OF_RANGE_U128"; - -pub const ERR_PROMISE_COUNT: &[u8; 17] = b"ERR_PROMISE_COUNT"; -pub const ERR_REFUND_FAILURE: &[u8; 18] = b"ERR_REFUND_FAILURE"; -pub const ERR_NOT_ALLOWED_TOO_EARLY: &[u8; 25] = b"ERR_NOT_ALLOWED:TOO_EARLY"; -pub const ERR_PROMISE_FAILED: &[u8; 18] = b"ERR_PROMISE_FAILED"; pub const ERR_VERIFY_PROOF: &str = "ERR_VERIFY_PROOF"; -pub const ERR_INVALID_UPGRADE: &[u8; 19] = b"ERR_INVALID_UPGRADE"; -pub const ERR_NO_UPGRADE: &[u8; 14] = b"ERR_NO_UPGRADE"; -pub const ERR_NOT_ALLOWED: &[u8; 15] = b"ERR_NOT_ALLOWED"; - -pub const ERR_SERIALIZE: &str = "ERR_SERIALIZE"; -pub const ERR_PROMISE_ENCODING: &str = "ERR_PROMISE_ENCODING"; -pub const ERR_ARGS: &str = "ERR_ARGS"; -pub const ERR_VALUE_CONVERSION: &str = "ERR_VALUE_CONVERSION"; - pub const ERR_BORSH_DESERIALIZE: &str = "ERR_BORSH_DESERIALIZE"; pub const ERR_BORSH_SERIALIZE: &str = "ERR_BORSH_SERIALIZE"; -pub const ERR_META_TX_PARSE: &str = "ERR_META_TX_PARSE"; - -pub const ERR_STACK_UNDERFLOW: &[u8; 19] = b"ERR_STACK_UNDERFLOW"; -pub const ERR_STACK_OVERFLOW: &[u8; 18] = b"ERR_STACK_OVERFLOW"; -pub const ERR_INVALID_JUMP: &[u8; 16] = b"ERR_INVALID_JUMP"; -pub const ERR_INVALID_RANGE: &[u8; 17] = b"ERR_INVALID_RANGE"; -pub const ERR_DESIGNATED_INVALID: &[u8; 22] = b"ERR_DESIGNATED_INVALID"; -pub const ERR_CALL_TOO_DEEP: &[u8; 17] = b"ERR_CALL_TOO_DEEP"; -pub const ERR_CREATE_COLLISION: &[u8; 20] = b"ERR_CREATE_COLLISION"; -pub const ERR_CREATE_CONTRACT_LIMIT: &[u8; 25] = b"ERR_CREATE_CONTRACT_LIMIT"; -pub const ERR_OUT_OF_OFFSET: &[u8; 17] = b"ERR_OUT_OF_OFFSET"; -pub const ERR_OUT_OF_GAS: &[u8; 14] = b"ERR_OUT_OF_GAS"; -pub const ERR_OUT_OF_FUND: &[u8; 15] = b"ERR_OUT_OF_FUND"; -pub const ERR_NOT_SUPPORTED: &[u8; 17] = b"ERR_NOT_SUPPORTED"; -pub const ERR_UNHANDLED_INTERRUPT: &[u8; 23] = b"ERR_UNHANDLED_INTERRUPT"; -pub const ERR_INCORRECT_NONCE: &[u8; 19] = b"ERR_INCORRECT_NONCE"; -pub const ERR_INVALID_CHAIN_ID: &[u8; 20] = b"ERR_INVALID_CHAIN_ID"; -pub const ERR_INVALID_ECDSA_SIGNATURE: &[u8; 27] = b"ERR_INVALID_ECDSA_SIGNATURE"; -pub const ERR_INTRINSIC_GAS: &[u8; 17] = b"ERR_INTRINSIC_GAS"; -pub const ERR_MAX_PRIORITY_FEE_GREATER: &[u8; 28] = b"ERR_MAX_PRIORITY_FEE_GREATER"; -pub const ERR_GAS_OVERFLOW: &[u8; 16] = b"ERR_GAS_OVERFLOW"; pub const ERR_BALANCE_OVERFLOW: &[u8; 20] = b"ERR_BALANCE_OVERFLOW"; -pub const ERR_GAS_ETH_AMOUNT_OVERFLOW: &[u8; 27] = b"ERR_GAS_ETH_AMOUNT_OVERFLOW"; -pub const ERR_PARSE_ADDRESS: &[u8; 17] = b"ERR_PARSE_ADDRESS"; -pub const ERR_STATE_NOT_FOUND: &[u8; 19] = b"ERR_STATE_NOT_FOUND"; -pub const ERR_STATE_CORRUPTED: &[u8; 19] = b"ERR_STATE_CORRUPTED"; - -pub const ERR_CONNECTOR_STORAGE_KEY_NOT_FOUND: &[u8; 35] = b"ERR_CONNECTOR_STORAGE_KEY_NOT_FOUND"; -pub const ERR_FAILED_DESERIALIZE_CONNECTOR_DATA: &[u8; 37] = - b"ERR_FAILED_DESERIALIZE_CONNECTOR_DATA"; pub const ERR_PROOF_EXIST: &[u8; 15] = b"ERR_PROOF_EXIST"; pub const ERR_WRONG_EVENT_ADDRESS: &[u8; 23] = b"ERR_WRONG_EVENT_ADDRESS"; -pub const ERR_CONTRACT_INITIALIZED: &[u8; 24] = b"ERR_CONTRACT_INITIALIZED"; - pub const ERR_RLP_FAILED: &[u8; 14] = b"ERR_RLP_FAILED"; pub const ERR_PARSE_DEPOSIT_EVENT: &[u8; 23] = b"ERR_PARSE_DEPOSIT_EVENT"; pub const ERR_INVALID_EVENT_MESSAGE_FORMAT: &[u8; 32] = b"ERR_INVALID_EVENT_MESSAGE_FORMAT"; @@ -72,30 +16,13 @@ pub const ERR_INVALID_ON_TRANSFER_MESSAGE_HEX: &[u8; 35] = b"ERR_INVALID_ON_TRAN pub const ERR_INVALID_ON_TRANSFER_MESSAGE_DATA: &[u8; 36] = b"ERR_INVALID_ON_TRANSFER_MESSAGE_DATA"; pub const ERR_INVALID_ACCOUNT_ID: &[u8; 22] = b"ERR_INVALID_ACCOUNT_ID"; pub const ERR_OVERFLOW_NUMBER: &[u8; 19] = b"ERR_OVERFLOW_NUMBER"; - pub const ERR_TOTAL_SUPPLY_OVERFLOW: &str = "ERR_TOTAL_SUPPLY_OVERFLOW"; pub const ERR_NOT_ENOUGH_BALANCE: &[u8; 22] = b"ERR_NOT_ENOUGH_BALANCE"; pub const ERR_TOTAL_SUPPLY_UNDERFLOW: &[u8; 26] = b"ERR_TOTAL_SUPPLY_UNDERFLOW"; pub const ERR_ZERO_AMOUNT: &[u8; 15] = b"ERR_ZERO_AMOUNT"; pub const ERR_SENDER_EQUALS_RECEIVER: &[u8; 26] = b"ERR_SENDER_EQUALS_RECEIVER"; -pub const ERR_ACCOUNT_NOT_REGISTERED: &[u8; 26] = b"ERR_ACCOUNT_NOT_REGISTERED"; -pub const ERR_NO_AVAILABLE_BALANCE: &[u8; 24] = b"ERR_NO_AVAILABLE_BALANCE"; -pub const ERR_ATTACHED_DEPOSIT_NOT_ENOUGH: &[u8; 31] = b"ERR_ATTACHED_DEPOSIT_NOT_ENOUGH"; -pub const ERR_FAILED_UNREGISTER_ACCOUNT_POSITIVE_BALANCE: &[u8; 46] = - b"ERR_FAILED_UNREGISTER_ACCOUNT_POSITIVE_BALANCE"; - -pub const ERR_ACCOUNTS_COUNTER_OVERFLOW: &str = "ERR_ACCOUNTS_COUNTER_OVERFLOW"; - -pub const ERR_REVERT: &[u8; 10] = b"ERR_REVERT"; -pub const ERR_OUT_OF_FUNDS: &[u8; 16] = b"ERR_OUT_OF_FUNDS"; - pub const ERR_NOT_ENOUGH_BALANCE_FOR_FEE: &str = "ERR_NOT_ENOUGH_BALANCE_FOR_FEE"; -pub const ERR_MORE_GAS_REQUIRED: &str = "ERR_MORE_GAS_REQUIRED"; -pub const ERR_PREPAID_GAS_OVERFLOW: &str = "ERR_PREPAID_GAS_OVERFLOW"; -pub const ERR_RECEIVER_BALANCE_NOT_ENOUGH: &str = "ERR__RECEIVER_BALANCE_NOT_ENOUGH"; -pub const ERR_USED_AMOUNT_OVERFLOW: &str = "ERR_USED_AMOUNT_OVERFLOW"; - pub struct ProofUsed; impl AsRef<[u8]> for ProofUsed { From bcee2df96082513822b8bcf4e5a32b750d022b13 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Thu, 8 Dec 2022 14:44:14 +0100 Subject: [PATCH 23/44] Extended missing data errors --- Cargo.lock | 4 ++-- eth-connector-tests/Cargo.toml | 2 +- eth-connector/Cargo.toml | 2 +- eth-connector/src/lib.rs | 20 +++++++++++++++++--- eth-connector/src/migration.rs | 6 +++--- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a512a6..9882265 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,7 +194,7 @@ dependencies = [ [[package]] name = "aurora-eth-connector" -version = "0.1.0" +version = "0.2.0" dependencies = [ "aurora-engine-types 1.0.0 (git+https://github.com/aurora-is-near/aurora-engine.git?branch=develop)", "byte-slice-cast", @@ -210,7 +210,7 @@ dependencies = [ [[package]] name = "aurora-eth-connector-tests" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "aurora-engine-migration-tool", diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index 572be0f..bb14edc 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aurora-eth-connector-tests" -version = "0.1.0" +version = "0.2.0" authors = ["Aurora Labs ", "Evgeny Ukhanov "] edition = "2021" description = "" diff --git a/eth-connector/Cargo.toml b/eth-connector/Cargo.toml index 04877dc..d8112fb 100644 --- a/eth-connector/Cargo.toml +++ b/eth-connector/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aurora-eth-connector" -version = "0.1.0" +version = "0.2.0" authors = ["Aurora Labs ", "Evgeny Ukhanov "] edition = "2021" description = "" diff --git a/eth-connector/src/lib.rs b/eth-connector/src/lib.rs index 7a766a2..4231e52 100644 --- a/eth-connector/src/lib.rs +++ b/eth-connector/src/lib.rs @@ -411,25 +411,39 @@ impl Migration for EthConnectorContract { &self, #[serializer(borsh)] data: MigrationInputData, ) -> MigrationCheckResult { + use std::collections::HashMap; + // Check accounts + let mut accounts_not_found: Vec = vec![]; + let mut accounts_with_amount_not_found: HashMap = HashMap::new(); for (account, amount) in &data.accounts { match self.ft.accounts.get(account) { Some(ref value) => { if value != amount { - return MigrationCheckResult::AccountAmount((account.clone(), *value)); + accounts_with_amount_not_found.insert(account.clone(), *value); } } - _ => return MigrationCheckResult::AccountNotExist(account.clone()), + _ => accounts_not_found.push(account.clone()), } } + if !accounts_not_found.is_empty() { + return MigrationCheckResult::AccountNotExist(accounts_not_found); + } + if !accounts_with_amount_not_found.is_empty() { + return MigrationCheckResult::AccountAmount(accounts_with_amount_not_found); + } // Check proofs + let mut proofs_not_found: Vec = vec![]; for proof in &data.used_proofs { match self.used_proofs.get(proof) { Some(_) => (), - _ => return MigrationCheckResult::Proof(proof.clone()), + _ => proofs_not_found.push(proof.clone()), } } + if !proofs_not_found.is_empty() { + return MigrationCheckResult::Proof(proofs_not_found); + } if let Some(account_storage_usage) = data.account_storage_usage { if self.ft.account_storage_usage != account_storage_usage { diff --git a/eth-connector/src/migration.rs b/eth-connector/src/migration.rs index 0915d42..fc42a5b 100644 --- a/eth-connector/src/migration.rs +++ b/eth-connector/src/migration.rs @@ -14,12 +14,12 @@ pub struct MigrationInputData { #[derive(Debug, BorshSerialize, BorshDeserialize, Eq, PartialEq)] pub enum MigrationCheckResult { Success, - AccountNotExist(AccountId), - AccountAmount((AccountId, Balance)), + AccountNotExist(Vec), + AccountAmount(HashMap), TotalSupply(Balance), StorageUsage(StorageUsage), StatisticsCounter(u64), - Proof(String), + Proof(Vec), } #[ext_contract(ext_deposit)] From dc0ca0336727589290870dee11bb3967fb5ecf16 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 9 Dec 2022 01:07:15 +0100 Subject: [PATCH 24/44] Test: increase gas cost --- eth-connector-tests/src/migration.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eth-connector-tests/src/migration.rs b/eth-connector-tests/src/migration.rs index 6f57fcb..a77adc2 100644 --- a/eth-connector-tests/src/migration.rs +++ b/eth-connector-tests/src/migration.rs @@ -109,7 +109,7 @@ async fn test_migration_state() -> anyhow::Result<()> { assert_eq!(proofs_count, data.proofs.len()); // INCREASED! //assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 5416.1); - assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 10325.0); + assert!(proofs_gas_burnt as f64 / 1_000_000_000_000. < 10326.0); total_gas_burnt += proofs_gas_burnt; println!(); @@ -153,7 +153,7 @@ async fn test_migration_state() -> anyhow::Result<()> { assert_eq!(data.accounts.len(), accounts_count); // INCREASED! //assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1457.); - assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1518.1); + assert!(accounts_gas_burnt as f64 / 1_000_000_000_000. < 1520.); total_gas_burnt += accounts_gas_burnt; // Migrate Contract data @@ -175,7 +175,7 @@ async fn test_migration_state() -> anyhow::Result<()> { total_gas_burnt += res.total_gas_burnt; // INCREASED! //assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 6878.6); - assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 11849.); + assert!(total_gas_burnt as f64 / 1_000_000_000_000. < 11852.); println!( "Total Gas burnt: {:.1} TGas\n", From 4a3dd5eff6ad49ad963eabb527b35b390bbaa996 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sat, 10 Dec 2022 00:04:13 +0100 Subject: [PATCH 25/44] CI: removed sscache --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 74de08f..a37ca28 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,4 +33,3 @@ jobs: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 - RUSTC_WRAPPER: sccache From 096fb550aa18684b23789188467941a43b3de7cf Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 11 Dec 2022 00:31:28 +0100 Subject: [PATCH 26/44] Test failed CI --- .github/workflows/tests.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a37ca28..9d41f80 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,15 +21,12 @@ jobs: - name: Build mainnet test WASM run: cargo make --profile mainnet build-test - name: Test mainnet - run: cargo make --profile mainnet test-workspace + run: RUST_BACKTRACE=1 cargo make --profile mainnet test-workspace - name: Build testnet test WASM run: cargo make --profile testnet build-test - name: Test testnet run: cargo make --profile testnet test-workspace - - name: Save cache - run: | - cache-util save cargo_git cargo_registry sccache yarn_cache - cache-util msave aurora-contract-target@generic@${{ hashFiles('**/Cargo.lock') }}:target + env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 From c4c149299a17280e0a9bcc90a8f106704ce3471c Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 11 Dec 2022 00:51:38 +0100 Subject: [PATCH 27/44] Test failed CI - verbose --- .github/workflows/tests.yml | 2 +- Makefile.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9d41f80..ee7254c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ jobs: - name: Build mainnet test WASM run: cargo make --profile mainnet build-test - name: Test mainnet - run: RUST_BACKTRACE=1 cargo make --profile mainnet test-workspace + run: RUST_BACKTRACE=full cargo make --profile mainnet test-workspace - name: Build testnet test WASM run: cargo make --profile testnet build-test - name: Test testnet diff --git a/Makefile.toml b/Makefile.toml index 7b874bf..75e0162 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -174,6 +174,7 @@ category = "Test" command = "${CARGO}" args = [ "test", + "--verbose", "--features", "${CARGO_FEATURES_TEST}", "--", From 5e936654860e59d566e136621ca4928740c85784 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 12 Dec 2022 01:42:56 +0100 Subject: [PATCH 28/44] Test CI - check errors --- .github/workflows/tests.yml | 2 +- Makefile.toml | 1 - eth-connector-tests/src/utils.rs | 23 ++++++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ee7254c..bcebdd7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ jobs: - name: Build mainnet test WASM run: cargo make --profile mainnet build-test - name: Test mainnet - run: RUST_BACKTRACE=full cargo make --profile mainnet test-workspace + run: cargo make --profile mainnet test-workspace - name: Build testnet test WASM run: cargo make --profile testnet build-test - name: Test testnet diff --git a/Makefile.toml b/Makefile.toml index 75e0162..7b874bf 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -174,7 +174,6 @@ category = "Test" command = "${CARGO}" args = [ "test", - "--verbose", "--features", "${CARGO_FEATURES_TEST}", "--", diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index b53c8dc..180d727 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -84,8 +84,15 @@ impl TestContract { AccessKey, }; - let worker = workspaces::sandbox().await?; - let testnet = workspaces::testnet().await?; + let worker = workspaces::sandbox() + .await + .map_err(|err| format!("Failed init sandbox: {:?}", err)) + .unwrap(); + + let testnet = workspaces::testnet() + .await + .map_err(|err| format!("Failed init testnet: {:?}", err)) + .unwrap(); let registrar: AccountId = "registrar".parse()?; let registrar = worker .import_contract(®istrar, &testnet) @@ -112,8 +119,18 @@ impl TestContract { .transact() .await? .into_result()?; + // .map_err(|err| format!("Failed init sandbox: {:?}", err)) + // .unwrap(); + + // Explicitly read contract fi;e + let contract_data = + std::fs::read("../bin/aurora-eth-connector-test.wasm").expect(&format!( + "Failed read contract in path: {:?} file: bin/aurora-eth-connector-test.wasm", + std::env::current_dir().unwrap() + )); + let contract = eth_connector - .deploy(&include_bytes!("../../bin/aurora-eth-connector-test.wasm")[..]) + .deploy(&contract_data[..]) .await? .into_result()?; Ok((contract, root_account)) From c66086121f80351c18d3076f93cda44e2f95d859 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 12 Dec 2022 03:21:11 +0100 Subject: [PATCH 29/44] Update workspace.rs to 0.7.0 --- Cargo.lock | 5 +++-- eth-connector-tests/Cargo.toml | 3 ++- eth-connector-tests/src/utils.rs | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9882265..8c68822 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,6 +221,7 @@ dependencies = [ "hex 0.4.3", "near-contract-standards", "near-primitives 0.5.0", + "near-sandbox-utils", "near-sdk", "near-units", "rlp", @@ -3569,9 +3570,9 @@ dependencies = [ [[package]] name = "workspaces" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f54d9286e6dc20dd6d7676de27ace7b0d4f755164fe14c1f07bcbdd08d54052" +checksum = "73b13d249618f197811e3673decc81459730cf5cc09ee7246dc4bede1e9333bc" dependencies = [ "async-process", "async-trait", diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index bb14edc..3a13e88 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -21,7 +21,8 @@ near-primitives = "0.5" near-units = "0.2" near-contract-standards = "4.1" tokio = { version = "1.14", features = ["full"] } -workspaces = "0.6" +workspaces = "0.7.0" +near-sandbox-utils = "0.6.1" byte-slice-cast = "1.2" hex = "0.4.3" ethabi = "17.1" diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 180d727..99a3b8d 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -25,6 +25,8 @@ pub struct TestContract { impl TestContract { pub async fn new() -> anyhow::Result { use std::str::FromStr; + near_sandbox_utils::ensure_sandbox_bin()?; + let (contract, root_account) = Self::deploy_aurora_contract().await?; let prover_account: AccountId = contract.id().clone(); From 8fd5b2922df00ee491e813820cd4bfa8bc33add8 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Mon, 12 Dec 2022 03:33:21 +0100 Subject: [PATCH 30/44] workspace.rs bin check --- eth-connector-tests/src/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 99a3b8d..df381a6 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -25,7 +25,7 @@ pub struct TestContract { impl TestContract { pub async fn new() -> anyhow::Result { use std::str::FromStr; - near_sandbox_utils::ensure_sandbox_bin()?; + near_sandbox_utils::ensure_sandbox_bin().unwrap(); let (contract, root_account) = Self::deploy_aurora_contract().await?; From 1b68df443505935df3455888ecd222404b3adf2d Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 13 Dec 2022 00:21:01 +0100 Subject: [PATCH 31/44] CI tests --- Cargo.lock | 1 - eth-connector-tests/Cargo.toml | 1 - eth-connector-tests/src/utils.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c68822..26f7594 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,6 @@ dependencies = [ "hex 0.4.3", "near-contract-standards", "near-primitives 0.5.0", - "near-sandbox-utils", "near-sdk", "near-units", "rlp", diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index 3a13e88..32d3984 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -22,7 +22,6 @@ near-units = "0.2" near-contract-standards = "4.1" tokio = { version = "1.14", features = ["full"] } workspaces = "0.7.0" -near-sandbox-utils = "0.6.1" byte-slice-cast = "1.2" hex = "0.4.3" ethabi = "17.1" diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index df381a6..fdca0dc 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -25,7 +25,6 @@ pub struct TestContract { impl TestContract { pub async fn new() -> anyhow::Result { use std::str::FromStr; - near_sandbox_utils::ensure_sandbox_bin().unwrap(); let (contract, root_account) = Self::deploy_aurora_contract().await?; From a4253bff7afb9604b6f0209827a971a26cfc9dcd Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Mon, 2 Jan 2023 15:14:34 +0100 Subject: [PATCH 32/44] chore: add env variable RUST_BACKTRACE to CI script --- .github/workflows/tests.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bcebdd7..f2391a4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,10 +14,6 @@ jobs: steps: - name: Clone the repository uses: actions/checkout@v2 - - name: Restore cache - run: | - cache-util restore cargo_git cargo_registry sccache yarn_cache - cache-util restore aurora-contract-target@generic@${{ hashFiles('**/Cargo.lock') }}:target - name: Build mainnet test WASM run: cargo make --profile mainnet build-test - name: Test mainnet @@ -30,3 +26,4 @@ jobs: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + RUST_BACKTRACE: full From 1a61a66f35175dfc3fc089176b842bb02946614f Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sun, 1 Jan 2023 21:09:38 +0100 Subject: [PATCH 33/44] Added waiting user creation for registrar --- eth-connector-tests/src/utils.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index fdca0dc..01bacb0 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -3,7 +3,8 @@ use aurora_eth_connector::proof::Proof; use near_contract_standards::fungible_token::metadata::{FungibleTokenMetadata, FT_METADATA_SPEC}; use near_sdk::serde_json::json; use near_sdk::{json_types::U128, serde_json}; -use workspaces::{result::ExecutionFinalResult, Account, AccountId, Contract}; +use workspaces::network::NetworkClient; +use workspaces::{result::ExecutionFinalResult, Account, AccountId, Contract, Worker}; pub const PROOF_DATA_NEAR: &str = r#"{"log_index":0,"log_entry_data":[248,251,148,9,109,233,194,184,165,184,194,44,238,50,137,177,1,246,150,13,104,229,30,248,66,160,209,66,67,156,39,142,37,218,217,165,7,102,241,83,208,227,210,215,191,43,209,111,194,120,28,75,212,148,178,177,90,157,160,0,0,0,0,0,0,0,0,0,0,0,0,121,24,63,219,216,14,45,138,234,26,202,162,246,123,251,138,54,212,10,141,184,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,54,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,101,116,104,95,114,101,99,105,112,105,101,110,116,46,114,111,111,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"receipt_index":0,"receipt_data":[249,2,6,1,130,107,17,185,1,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,253,248,251,148,9,109,233,194,184,165,184,194,44,238,50,137,177,1,246,150,13,104,229,30,248,66,160,209,66,67,156,39,142,37,218,217,165,7,102,241,83,208,227,210,215,191,43,209,111,194,120,28,75,212,148,178,177,90,157,160,0,0,0,0,0,0,0,0,0,0,0,0,121,24,63,219,216,14,45,138,234,26,202,162,246,123,251,138,54,212,10,141,184,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,54,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,101,116,104,95,114,101,99,105,112,105,101,110,116,46,114,111,111,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"header_data":[249,2,10,160,177,33,112,26,26,176,12,12,163,2,249,133,245,12,51,201,55,50,148,156,122,67,27,26,101,178,36,153,54,100,53,137,160,29,204,77,232,222,199,93,122,171,133,181,103,182,204,212,26,211,18,69,27,148,138,116,19,240,161,66,253,64,212,147,71,148,124,28,230,160,8,239,64,193,62,78,177,68,166,204,116,240,224,174,172,126,160,197,65,5,202,188,134,5,164,246,19,133,35,57,28,114,241,186,81,123,163,166,161,24,32,157,168,170,13,108,58,61,46,160,6,199,163,13,91,119,225,39,168,255,213,10,107,252,143,246,138,241,108,139,59,35,187,185,162,223,53,108,222,73,181,109,160,27,154,49,63,26,170,15,177,97,255,6,204,84,221,234,197,159,172,114,47,148,126,32,199,241,127,101,120,182,51,52,100,185,1,0,0,0,8,0,0,0,0,0,0,0,32,0,0,0,0,0,2,0,8,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,8,32,0,32,0,0,128,0,2,0,0,0,1,0,32,0,0,0,2,0,0,0,0,32,0,0,0,0,0,4,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,128,64,0,0,0,0,1,32,0,0,0,0,0,0,96,32,0,64,0,0,0,128,1,0,0,0,0,1,0,0,0,8,0,0,0,18,32,0,0,64,145,1,8,0,4,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,33,16,0,128,0,0,0,0,0,0,128,0,2,0,0,0,0,0,0,0,0,0,0,2,0,80,0,0,0,0,0,0,0,0,1,128,0,8,0,0,0,0,4,0,0,0,128,2,0,32,0,128,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,16,0,8,0,0,0,0,0,0,0,0,0,0,128,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,25,1,227,23,131,157,85,14,131,122,18,0,131,75,91,132,132,96,174,58,224,140,115,112,105,100,101,114,49,48,1,2,8,230,160,188,212,199,183,154,22,223,85,103,215,24,122,240,235,79,129,44,93,184,88,161,218,79,5,44,226,106,100,50,40,163,97,136,155,158,202,3,149,91,200,78],"proof":[[248,113,160,46,156,31,85,241,226,241,13,5,56,73,146,176,67,195,109,6,189,172,104,44,103,44,88,32,15,181,152,136,29,121,252,160,191,48,87,174,71,151,208,114,164,150,51,200,171,90,90,106,46,200,79,77,222,145,95,89,141,137,138,149,67,73,8,87,128,128,128,128,128,128,160,175,9,219,77,174,13,247,133,55,172,92,185,202,7,160,10,204,112,44,133,36,96,30,234,235,134,30,209,205,166,212,255,128,128,128,128,128,128,128,128],[249,2,13,48,185,2,9,249,2,6,1,130,107,17,185,1,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,253,248,251,148,9,109,233,194,184,165,184,194,44,238,50,137,177,1,246,150,13,104,229,30,248,66,160,209,66,67,156,39,142,37,218,217,165,7,102,241,83,208,227,210,215,191,43,209,111,194,120,28,75,212,148,178,177,90,157,160,0,0,0,0,0,0,0,0,0,0,0,0,121,24,63,219,216,14,45,138,234,26,202,162,246,123,251,138,54,212,10,141,184,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,54,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,101,116,104,95,114,101,99,105,112,105,101,110,116,46,114,111,111,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]}"#; pub const DEPOSITED_RECIPIENT: &str = "eth_recipient.root"; @@ -99,6 +100,7 @@ impl TestContract { .import_contract(®istrar, &testnet) .transact() .await?; + Self::waiting_account_creation(&worker, registrar.id()).await; let sk = SecretKey::from_seed(KeyType::ED25519, "registrar"); @@ -147,6 +149,24 @@ impl TestContract { .into_result()?) } + /// Waiting for the account creation + async fn waiting_account_creation( + worker: &Worker, + account_id: &AccountId, + ) { + // Try get account within 10 secs + for _ in 0..20 { + if worker.view_account(account_id).await.is_err() { + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + } else { + // Just exit from function + return; + } + } + // Immediately panic, because account not created + panic!("Account {} was not creates", account_id.to_string()); + } + pub async fn deposit_with_proof(&self, proof: &Proof) -> anyhow::Result { Ok(self .contract From d0dacf6ac4beb8b6fcbf18621cf686435afd81d2 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 3 Jan 2023 00:46:03 +0100 Subject: [PATCH 34/44] Account Registrar creation - increased waiting time --- .github/workflows/tests.yml | 1 - eth-connector-tests/src/utils.rs | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f2391a4..ef02661 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,4 +26,3 @@ jobs: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 - RUST_BACKTRACE: full diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 01bacb0..fd46501 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -154,8 +154,8 @@ impl TestContract { worker: &Worker, account_id: &AccountId, ) { - // Try get account within 10 secs - for _ in 0..20 { + // Try get account within 20 secs + for _ in 0..40 { if worker.view_account(account_id).await.is_err() { tokio::time::sleep(std::time::Duration::from_millis(500)).await; } else { @@ -164,7 +164,7 @@ impl TestContract { } } // Immediately panic, because account not created - panic!("Account {} was not creates", account_id.to_string()); + panic!("Account {} was not created", account_id.to_string()); } pub async fn deposit_with_proof(&self, proof: &Proof) -> anyhow::Result { From 13bf89e8f1828fbfbdffeb75fd0b410f2e93c799 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 3 Jan 2023 01:08:01 +0100 Subject: [PATCH 35/44] Extended Registrar creation error message and extend CI lints --- .github/workflows/lints.yml | 7 ++----- eth-connector-tests/src/utils.rs | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index d50003e..2593991 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -22,8 +22,5 @@ jobs: steps: - name: Clone the repository uses: actions/checkout@v2 - - name: Run Contract cargo clippy - run: cargo make clippy - - name: Run cargo clippy - run: cargo clippy - + - name: Run Contract cargo lint checker + run: cargo make check diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index fd46501..95ceb5f 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -122,15 +122,15 @@ impl TestContract { .transact() .await? .into_result()?; - // .map_err(|err| format!("Failed init sandbox: {:?}", err)) - // .unwrap(); - // Explicitly read contract fi;e + // Explicitly read contract file let contract_data = - std::fs::read("../bin/aurora-eth-connector-test.wasm").expect(&format!( - "Failed read contract in path: {:?} file: bin/aurora-eth-connector-test.wasm", - std::env::current_dir().unwrap() - )); + std::fs::read("../bin/aurora-eth-connector-test.wasm").unwrap_or_else(|_| { + panic!( + "Failed read contract in path: {:?} file: bin/aurora-eth-connector-test.wasm", + std::env::current_dir().unwrap() + ) + }); let contract = eth_connector .deploy(&contract_data[..]) @@ -154,6 +154,7 @@ impl TestContract { worker: &Worker, account_id: &AccountId, ) { + let timer = std::time::Instant::now(); // Try get account within 20 secs for _ in 0..40 { if worker.view_account(account_id).await.is_err() { @@ -164,7 +165,11 @@ impl TestContract { } } // Immediately panic, because account not created - panic!("Account {} was not created", account_id.to_string()); + panic!( + "Account `{}` was not created in {:?} sec", + account_id, + timer.elapsed() + ); } pub async fn deposit_with_proof(&self, proof: &Proof) -> anyhow::Result { From 8829738729e55fec392f6addbdbd8ded9d5008ba Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 09:52:01 +0100 Subject: [PATCH 36/44] Use one thread for tests --- Makefile.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.toml b/Makefile.toml index 7b874bf..2c2e064 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -177,6 +177,7 @@ args = [ "--features", "${CARGO_FEATURES_TEST}", "--", + "--test-threads=1", "--nocapture" ] From 58caffe9147758b12a7d7adb70ce086749461320 Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 13:27:36 +0100 Subject: [PATCH 37/44] clean artifacts --- .github/workflows/tests.yml | 2 ++ Makefile.toml | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef02661..1bcc459 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,6 +22,8 @@ jobs: run: cargo make --profile testnet build-test - name: Test testnet run: cargo make --profile testnet test-workspace + - name: Clean artifacts + run: rm -rf /tmp/sandbox-* env: CARGO_TERM_COLOR: always diff --git a/Makefile.toml b/Makefile.toml index 2c2e064..7b874bf 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -177,7 +177,6 @@ args = [ "--features", "${CARGO_FEATURES_TEST}", "--", - "--test-threads=1", "--nocapture" ] From 3313847dae915113f63a8b87ccacf3c04f2783a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 15:05:55 +0100 Subject: [PATCH 38/44] use modified workspaces --- .github/workflows/tests.yml | 2 -- Cargo.lock | 25 +++++++++++++++++++++++-- eth-connector-tests/Cargo.toml | 2 +- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1bcc459..ef02661 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,8 +22,6 @@ jobs: run: cargo make --profile testnet build-test - name: Test testnet run: cargo make --profile testnet test-workspace - - name: Clean artifacts - run: rm -rf /tmp/sandbox-* env: CARGO_TERM_COLOR: always diff --git a/Cargo.lock b/Cargo.lock index 26f7594..8b75154 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1364,6 +1364,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json-patch" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3fa5a61630976fc4c353c70297f2e93f1930e3ccee574d59d618ccbd5154ce" +dependencies = [ + "serde", + "serde_json", + "treediff", +] + [[package]] name = "keccak" version = "0.1.3" @@ -3184,6 +3195,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "treediff" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" +dependencies = [ + "serde_json", +] + [[package]] name = "try-lock" version = "0.2.3" @@ -3570,8 +3590,7 @@ dependencies = [ [[package]] name = "workspaces" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b13d249618f197811e3673decc81459730cf5cc09ee7246dc4bede1e9333bc" +source = "git+https://github.com/aleksuss/workspaces-rs#f8fa42a01a84c5418f4d54deec59924f4f2ceb39" dependencies = [ "async-process", "async-trait", @@ -3581,6 +3600,7 @@ dependencies = [ "chrono", "dirs 3.0.2", "hex 0.4.3", + "json-patch", "libc", "near-account-id 0.15.0", "near-crypto 0.15.0", @@ -3593,6 +3613,7 @@ dependencies = [ "reqwest", "serde", "serde_json", + "tempfile", "thiserror", "tokio", "tokio-retry", diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index 32d3984..091aa48 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -21,7 +21,7 @@ near-primitives = "0.5" near-units = "0.2" near-contract-standards = "4.1" tokio = { version = "1.14", features = ["full"] } -workspaces = "0.7.0" +workspaces = { git = "https://github.com/aleksuss/workspaces-rs" } byte-slice-cast = "1.2" hex = "0.4.3" ethabi = "17.1" From 3d8020f541ac5c0bf3edd6cf7ffe075ff369c37e Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 15:43:46 +0100 Subject: [PATCH 39/44] use testnet_archival --- eth-connector-tests/src/utils.rs | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 95ceb5f..5f99a7f 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -27,7 +27,7 @@ impl TestContract { pub async fn new() -> anyhow::Result { use std::str::FromStr; - let (contract, root_account) = Self::deploy_aurora_contract().await?; + let (contract, root_account) = Self::import_aurora_contract().await?; let prover_account: AccountId = contract.id().clone(); let eth_custodian_address = CUSTODIAN_ADDRESS; @@ -55,7 +55,7 @@ impl TestContract { pub async fn new_with_custodian(eth_custodian_address: &str) -> anyhow::Result { use std::str::FromStr; - let (contract, root_account) = Self::deploy_aurora_contract().await?; + let (contract, root_account) = Self::import_aurora_contract().await?; let prover_account: AccountId = contract.id().clone(); let metadata = Self::metadata_default(); @@ -80,7 +80,7 @@ impl TestContract { }) } - pub async fn deploy_aurora_contract() -> anyhow::Result<(Contract, Account)> { + pub async fn import_aurora_contract() -> anyhow::Result<(Contract, Account)> { use workspaces::{ types::{KeyType, SecretKey}, AccessKey, @@ -88,19 +88,16 @@ impl TestContract { let worker = workspaces::sandbox() .await - .map_err(|err| format!("Failed init sandbox: {:?}", err)) - .unwrap(); - - let testnet = workspaces::testnet() + .map_err(|err| anyhow::anyhow!("Failed init sandbox: {:?}", err))?; + let testnet = workspaces::testnet_archival() .await - .map_err(|err| format!("Failed init testnet: {:?}", err)) - .unwrap(); + .map_err(|err| anyhow::anyhow!("Failed init testnet: {:?}", err))?; let registrar: AccountId = "registrar".parse()?; let registrar = worker .import_contract(®istrar, &testnet) .transact() .await?; - Self::waiting_account_creation(&worker, registrar.id()).await; + Self::waiting_account_creation(&worker, registrar.id()).await?; let sk = SecretKey::from_seed(KeyType::ED25519, "registrar"); @@ -153,23 +150,22 @@ impl TestContract { async fn waiting_account_creation( worker: &Worker, account_id: &AccountId, - ) { + ) -> anyhow::Result<()> { let timer = std::time::Instant::now(); - // Try get account within 20 secs - for _ in 0..40 { + // Try to get account within 30 secs + for _ in 0..60 { if worker.view_account(account_id).await.is_err() { tokio::time::sleep(std::time::Duration::from_millis(500)).await; } else { - // Just exit from function - return; + return Ok(()); } } - // Immediately panic, because account not created - panic!( + + anyhow::bail!( "Account `{}` was not created in {:?} sec", account_id, timer.elapsed() - ); + ) } pub async fn deposit_with_proof(&self, proof: &Proof) -> anyhow::Result { From a24ad2484a90359bd42181af122bf2c5b2333aa7 Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 15:50:13 +0100 Subject: [PATCH 40/44] roll back workspaces --- eth-connector-tests/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index 091aa48..aed0eda 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -21,7 +21,7 @@ near-primitives = "0.5" near-units = "0.2" near-contract-standards = "4.1" tokio = { version = "1.14", features = ["full"] } -workspaces = { git = "https://github.com/aleksuss/workspaces-rs" } +workspaces = "0.7" byte-slice-cast = "1.2" hex = "0.4.3" ethabi = "17.1" From 21a479d99dbd8062f4a53ee336782c2e05cd92cf Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 17:17:57 +0100 Subject: [PATCH 41/44] decrease number of test threads to four --- Makefile.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.toml b/Makefile.toml index 7b874bf..46bc5bf 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -177,6 +177,7 @@ args = [ "--features", "${CARGO_FEATURES_TEST}", "--", + "--test-threads=4", "--nocapture" ] From 52cf2a05c295db96294d05f8ed25c6a423aea4bf Mon Sep 17 00:00:00 2001 From: Oleksandr Anyshchenko Date: Tue, 3 Jan 2023 19:13:08 +0100 Subject: [PATCH 42/44] roll back some changes --- Cargo.lock | 25 ++----------------------- eth-connector-tests/src/utils.rs | 8 ++++---- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b75154..26f7594 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1364,17 +1364,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "json-patch" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3fa5a61630976fc4c353c70297f2e93f1930e3ccee574d59d618ccbd5154ce" -dependencies = [ - "serde", - "serde_json", - "treediff", -] - [[package]] name = "keccak" version = "0.1.3" @@ -3195,15 +3184,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "treediff" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" -dependencies = [ - "serde_json", -] - [[package]] name = "try-lock" version = "0.2.3" @@ -3590,7 +3570,8 @@ dependencies = [ [[package]] name = "workspaces" version = "0.7.0" -source = "git+https://github.com/aleksuss/workspaces-rs#f8fa42a01a84c5418f4d54deec59924f4f2ceb39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b13d249618f197811e3673decc81459730cf5cc09ee7246dc4bede1e9333bc" dependencies = [ "async-process", "async-trait", @@ -3600,7 +3581,6 @@ dependencies = [ "chrono", "dirs 3.0.2", "hex 0.4.3", - "json-patch", "libc", "near-account-id 0.15.0", "near-crypto 0.15.0", @@ -3613,7 +3593,6 @@ dependencies = [ "reqwest", "serde", "serde_json", - "tempfile", "thiserror", "tokio", "tokio-retry", diff --git a/eth-connector-tests/src/utils.rs b/eth-connector-tests/src/utils.rs index 5f99a7f..cb9ea88 100644 --- a/eth-connector-tests/src/utils.rs +++ b/eth-connector-tests/src/utils.rs @@ -27,7 +27,7 @@ impl TestContract { pub async fn new() -> anyhow::Result { use std::str::FromStr; - let (contract, root_account) = Self::import_aurora_contract().await?; + let (contract, root_account) = Self::deploy_aurora_contract().await?; let prover_account: AccountId = contract.id().clone(); let eth_custodian_address = CUSTODIAN_ADDRESS; @@ -55,7 +55,7 @@ impl TestContract { pub async fn new_with_custodian(eth_custodian_address: &str) -> anyhow::Result { use std::str::FromStr; - let (contract, root_account) = Self::import_aurora_contract().await?; + let (contract, root_account) = Self::deploy_aurora_contract().await?; let prover_account: AccountId = contract.id().clone(); let metadata = Self::metadata_default(); @@ -80,7 +80,7 @@ impl TestContract { }) } - pub async fn import_aurora_contract() -> anyhow::Result<(Contract, Account)> { + pub async fn deploy_aurora_contract() -> anyhow::Result<(Contract, Account)> { use workspaces::{ types::{KeyType, SecretKey}, AccessKey, @@ -89,7 +89,7 @@ impl TestContract { let worker = workspaces::sandbox() .await .map_err(|err| anyhow::anyhow!("Failed init sandbox: {:?}", err))?; - let testnet = workspaces::testnet_archival() + let testnet = workspaces::testnet() .await .map_err(|err| anyhow::anyhow!("Failed init testnet: {:?}", err))?; let registrar: AccountId = "registrar".parse()?; From 46336123d70406e758b317c139a22841ba7ba587 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 4 Jan 2023 23:28:54 +0100 Subject: [PATCH 43/44] Changed test-threads=4 --- Makefile.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.toml b/Makefile.toml index 7b874bf..46bc5bf 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -177,6 +177,7 @@ args = [ "--features", "${CARGO_FEATURES_TEST}", "--", + "--test-threads=4", "--nocapture" ] From 957334274cbcd9c03bcee46e6202f7dad5959b2c Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Thu, 5 Jan 2023 00:26:07 +0100 Subject: [PATCH 44/44] Changed features config --- .env/custom_example.env | 4 ++-- .env/local.env | 2 +- .env/mainnet.env | 2 +- .env/testnet.env | 8 ++++---- .github/workflows/tests.yml | 6 +----- eth-connector-tests/Cargo.toml | 5 +---- eth-connector/Cargo.toml | 3 ++- 7 files changed, 12 insertions(+), 18 deletions(-) diff --git a/.env/custom_example.env b/.env/custom_example.env index 7ebbfff..f4a9608 100644 --- a/.env/custom_example.env +++ b/.env/custom_example.env @@ -3,12 +3,12 @@ # # Simply remove the prefixed `#` to enable them. -# The cargo features should either be `mainnet`, `testnet` or something extra in order to make use +# The cargo features should either be `mainnet`, `default` or something extra in order to make use # of your own custom features. #CARGO_FEATURES_BUILD = "mainnet" # The cargo test features are used to build a test environment version of the fungible-token WASM and test -# library. Either use `mainnet-test`, `testnet-test` or something extra in order to make use of your +# library. Either use something extra in order to make use of your # own custom features. #CARGO_FEATURES_BUILD_TEST = "mainnet,integration-test" diff --git a/.env/local.env b/.env/local.env index 351276b..ebbd7c5 100644 --- a/.env/local.env +++ b/.env/local.env @@ -1,4 +1,4 @@ -CARGO_FEATURES_BUILD = "testnet" +CARGO_FEATURES_BUILD = "mainnet" RUSTC_FLAGS_BUILD = "-C link-arg=-s" NEAR_EVM_ACCOUNT = "aurora.test.near" WASM_FILE = "aurora-eth-connector-local.wasm" diff --git a/.env/mainnet.env b/.env/mainnet.env index f443aac..6b64e9a 100644 --- a/.env/mainnet.env +++ b/.env/mainnet.env @@ -1,7 +1,7 @@ CARGO_FEATURES_BUILD = "mainnet" CARGO_FEATURES_BUILD_MIGRATION = "mainnet,migration" CARGO_FEATURES_BUILD_TEST = "mainnet,integration-test,migration" -CARGO_FEATURES_TEST = "mainnet-test" +CARGO_FEATURES_TEST = "" RUSTC_FLAGS_BUILD = "-C link-arg=-s" NEAR_EVM_ACCOUNT = "aurora" WASM_FILE = "aurora-eth-connector-mainnet.wasm" diff --git a/.env/testnet.env b/.env/testnet.env index 4c5c322..ebe4571 100644 --- a/.env/testnet.env +++ b/.env/testnet.env @@ -1,7 +1,7 @@ -CARGO_FEATURES_BUILD = "testnet" -CARGO_FEATURES_BUILD_MIGRATION = "testnet,migration" -CARGO_FEATURES_BUILD_TEST = "testnet,integration-test,migration" -CARGO_FEATURES_TEST = "testnet-test" +CARGO_FEATURES_BUILD = "mainnet" +CARGO_FEATURES_BUILD_MIGRATION = "mainnet,migration" +CARGO_FEATURES_BUILD_TEST = "mainnet,integration-test,migration" +CARGO_FEATURES_TEST = "" RUSTC_FLAGS_BUILD = "-C link-arg=-s" NEAR_EVM_ACCOUNT = "aurora" WASM_FILE = "aurora-eth-connector-testnet.wasm" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef02661..b64b73a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,7 +9,7 @@ on: name: Tests jobs: test: - name: Test suite (mainnet, testnet) + name: Test suite (mainnet) runs-on: [self-hosted, heavy] steps: - name: Clone the repository @@ -18,10 +18,6 @@ jobs: run: cargo make --profile mainnet build-test - name: Test mainnet run: cargo make --profile mainnet test-workspace - - name: Build testnet test WASM - run: cargo make --profile testnet build-test - - name: Test testnet - run: cargo make --profile testnet test-workspace env: CARGO_TERM_COLOR: always diff --git a/eth-connector-tests/Cargo.toml b/eth-connector-tests/Cargo.toml index aed0eda..0409caf 100644 --- a/eth-connector-tests/Cargo.toml +++ b/eth-connector-tests/Cargo.toml @@ -21,7 +21,7 @@ near-primitives = "0.5" near-units = "0.2" near-contract-standards = "4.1" tokio = { version = "1.14", features = ["full"] } -workspaces = "0.7" +workspaces = "0.7.0" byte-slice-cast = "1.2" hex = "0.4.3" ethabi = "17.1" @@ -29,6 +29,3 @@ rlp = { version = "0.5.0", default-features = false } aurora-engine-migration-tool = { git = "https://github.com/aurora-is-near/aurora-engine-migration-tool.git" } [features] -mainnet-test = [] -testnet-test = [] - diff --git a/eth-connector/Cargo.toml b/eth-connector/Cargo.toml index d8112fb..2550302 100644 --- a/eth-connector/Cargo.toml +++ b/eth-connector/Cargo.toml @@ -32,6 +32,7 @@ rand = "0.8.5" [features] log = [] integration-test = ["log"] +# Currently feature `mainnet` used only for +# Makefile.toml profiles to indicate basic features mainnet = ["log"] -testnet = ["log"] migration = ["log"]