From 9c7236001c5191eafd44d6e6e870bcb1c84131a0 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 28 Jul 2021 13:10:00 +0300 Subject: [PATCH 01/12] Fix StorageBalance - to_json_bytes --- src/parameters.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parameters.rs b/src/parameters.rs index c2b62bfa2..8f6464e1d 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -222,7 +222,7 @@ pub struct StorageBalance { impl StorageBalance { pub fn to_json_bytes(&self) -> Vec { crate::prelude::format!( - "{{\"total\": \"{}\", \"available\": \"{}\",}}", + "{{\"total\": \"{}\", \"available\": \"{}\"}}", self.total.to_string(), self.available.to_string() ) From 245fb065bf7abba6ac1628ee2f16572a49779051 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 28 Jul 2021 15:01:29 +0300 Subject: [PATCH 02/12] Added ft_metadata --- src/connector.rs | 15 +++++++++++++++ src/fungible_token.rs | 11 +++++++++++ src/lib.rs | 5 +++++ src/parameters.rs | 2 ++ src/storage.rs | 1 + 5 files changed, 34 insertions(+) diff --git a/src/connector.rs b/src/connector.rs index bed566ebf..7f47b4dad 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -28,6 +28,7 @@ pub struct EthConnectorContract { contract: EthConnector, ft: FungibleToken, paused_mask: PausedMask, + metadata: FungibleTokenMetadata, } /// eth-connector specific data @@ -58,6 +59,7 @@ impl EthConnectorContract { contract: Self::get_contract_data(&EthConnectorStorageId::Contract), ft: Self::get_contract_data(&EthConnectorStorageId::FungibleToken), paused_mask: Self::get_contract_data(&EthConnectorStorageId::PausedMask), + metadata: Self::get_contract_data(&EthConnectorStorageId::FungibleTokenMetadata), } } @@ -82,6 +84,7 @@ impl EthConnectorContract { let contract_data = Self::set_contract_data(SetContractDataCallArgs { prover_account: args.prover_account, eth_custodian_address: args.eth_custodian_address, + metadata: args.metadata.clone(), }); let current_account_id = sdk::current_account_id(); @@ -90,6 +93,8 @@ impl EthConnectorContract { // Register FT account for current contract ft.internal_register_account(&owner_id); + let metadata = args.metadata; + let paused_mask = UNPAUSE_ALL; sdk::save_contract( &Self::get_contract_key(&EthConnectorStorageId::PausedMask), @@ -100,6 +105,7 @@ impl EthConnectorContract { contract: contract_data, ft, paused_mask, + metadata, } .save_ft_contract(); } @@ -583,6 +589,10 @@ impl EthConnectorContract { &Self::get_contract_key(&EthConnectorStorageId::FungibleToken), &self.ft, ); + sdk::save_contract( + &Self::get_contract_key(&EthConnectorStorageId::FungibleTokenMetadata), + &self.metadata, + ); } /// Generate key for used events from Prood @@ -616,6 +626,11 @@ impl EthConnectorContract { pub fn set_paused_flags(&mut self, args: PauseEthConnectorCallArgs) { self.set_paused(args.paused_mask); } + + /// Return metdata + pub fn get_metadata(&self) { + sdk::return_output(&self.metadata.try_to_vec().unwrap()[..]); + } } impl AdminControlled for EthConnectorContract { diff --git a/src/fungible_token.rs b/src/fungible_token.rs index 00ff7b5c0..fa6a8edec 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -27,6 +27,17 @@ pub struct FungibleToken { pub account_storage_usage: StorageUsage, } +#[derive(Default, BorshDeserialize, BorshSerialize, Clone)] +pub struct FungibleTokenMetadata { + pub spec: String, + pub name: String, + pub symbol: String, + pub icon: Option, + pub reference: Option, + pub reference_hash: Option<[u8; 32]>, + pub decimals: u8, +} + impl FungibleToken { pub fn new() -> Self { Self::default() diff --git a/src/lib.rs b/src/lib.rs index df76445ad..b1dce2bf6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -591,6 +591,11 @@ mod contract { ); } + #[no_mangle] + pub extern "C" fn get_metadata() { + EthConnectorContract::get_instance().get_metadata(); + } + #[cfg(feature = "integration-test")] #[no_mangle] pub extern "C" fn verify_log_entry() { diff --git a/src/parameters.rs b/src/parameters.rs index 8f6464e1d..c1ef5346c 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -1,5 +1,6 @@ use borsh::{BorshDeserialize, BorshSerialize}; +use crate::fungible_token::FungibleTokenMetadata; use crate::prelude::{String, Vec}; use crate::types::{AccountId, Balance, RawAddress, RawH256, RawU256}; use crate::{ @@ -272,6 +273,7 @@ pub struct FinishDepositEthCallArgs { pub struct InitCallArgs { pub prover_account: AccountId, pub eth_custodian_address: AccountId, + pub metadata: FungibleTokenMetadata, } /// Eth-connector Set contract data call args diff --git a/src/storage.rs b/src/storage.rs index 52af685e9..6d8132fbf 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -30,6 +30,7 @@ pub enum EthConnectorStorageId { UsedEvent = 0x2, PausedMask = 0x3, StatisticsAuroraAccountsCounter = 0x4, + FungibleTokenMetadata = 0x5, } /// We can't use const generic over Enum, but we can do it over integral type From cd70631ba5f8aa0482da6891d3ab42e3cffe19a9 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 28 Jul 2021 15:06:38 +0300 Subject: [PATCH 03/12] Fix ft_metadata related tests --- Makefile | 2 +- src/test_utils/mod.rs | 3 ++- src/tests/eth_connector.rs | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8e9b34172..9c212379a 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ testnet-release.wasm: target/wasm32-unknown-unknown/release/aurora_engine.wasm betanet-release.wasm: target/wasm32-unknown-unknown/release/aurora_engine.wasm cp $< $@ -target/wasm32-unknown-unknown/release/aurora_engine.wasm: Cargo.toml Cargo.lock $(shell find src -name "*.rs") etc/eth-contracts/res/EvmErc20.bin +target/wasm32-unknown-unknown/release/aurora_engine.wasm: Cargo.toml Cargo.lock $(shell find src -name "*.rs") RUSTFLAGS='-C link-arg=-s' $(CARGO) build --target wasm32-unknown-unknown --release --no-default-features --features=$(FEATURES) -Z avoid-dev-deps etc/eth-contracts/res/EvmErc20.bin: $(shell find etc/eth-contracts/contracts -name "*.sol") etc/eth-contracts/package.json diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs index 827d00ed3..3d4110b6d 100644 --- a/src/test_utils/mod.rs +++ b/src/test_utils/mod.rs @@ -12,7 +12,7 @@ use primitive_types::U256; use rlp::RlpStream; use secp256k1::{self, Message, PublicKey, SecretKey}; -use crate::fungible_token::FungibleToken; +use crate::fungible_token::{FungibleToken, FungibleTokenMetadata}; use crate::parameters::{InitCallArgs, NewCallArgs, SubmitResult}; use crate::prelude::Address; use crate::storage; @@ -368,6 +368,7 @@ pub(crate) fn deploy_evm() -> AuroraRunner { let args = InitCallArgs { prover_account: "prover.near".to_string(), eth_custodian_address: "d045f7e19B2488924B97F9c145b5E51D0D895A65".to_string(), + metadata: FungibleTokenMetadata::default(), }; let (_, maybe_error) = runner.call( "new_eth_connector", diff --git a/src/tests/eth_connector.rs b/src/tests/eth_connector.rs index 1f8994d60..2c65e70d5 100644 --- a/src/tests/eth_connector.rs +++ b/src/tests/eth_connector.rs @@ -2,6 +2,7 @@ use crate::admin_controlled::{PausedMask, ERR_PAUSED}; use crate::connector::{ ERR_NOT_ENOUGH_BALANCE_FOR_FEE, PAUSE_DEPOSIT, PAUSE_WITHDRAW, UNPAUSE_ALL, }; +use crate::fungible_token::FungibleTokenMetadata; use crate::parameters::{ InitCallArgs, NewCallArgs, RegisterRelayerCallArgs, WithdrawCallArgs, WithdrawResult, }; @@ -71,6 +72,7 @@ fn init_contract( &InitCallArgs { prover_account: PROVER_ACCOUNT.into(), eth_custodian_address: custodian_address.into(), + metadata: FungibleTokenMetadata::default(), } .try_to_vec() .unwrap(), From 48b4987dfb3d93256f827169eab34c13d5e64931 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 28 Jul 2021 15:13:31 +0300 Subject: [PATCH 04/12] Extend Makefile --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9c212379a..943c375f8 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ testnet-release.wasm: target/wasm32-unknown-unknown/release/aurora_engine.wasm betanet-release.wasm: target/wasm32-unknown-unknown/release/aurora_engine.wasm cp $< $@ -target/wasm32-unknown-unknown/release/aurora_engine.wasm: Cargo.toml Cargo.lock $(shell find src -name "*.rs") +target/wasm32-unknown-unknown/release/aurora_engine.wasm: Cargo.toml Cargo.lock $(shell find src -name "*.rs") etc/eth-contracts/res/EvmErc20.bin RUSTFLAGS='-C link-arg=-s' $(CARGO) build --target wasm32-unknown-unknown --release --no-default-features --features=$(FEATURES) -Z avoid-dev-deps etc/eth-contracts/res/EvmErc20.bin: $(shell find etc/eth-contracts/contracts -name "*.sol") etc/eth-contracts/package.json @@ -106,6 +106,11 @@ clean: @rm -Rf *.wasm cargo clean +test-pure: FEATURES=mainnet,integration-test,meta-call +test-pure: Cargo.toml Cargo.lock $(shell find src -name "*.rs") + RUSTFLAGS='-C link-arg=-s' $(CARGO) build --target wasm32-unknown-unknown --release --no-default-features --features=$(FEATURES) -Z avoid-dev-deps + $(CARGO) test --features mainnet-test + .PHONY: release mainnet testnet betanet compile-release test-build deploy check check-format check-clippy test test-sol format clean debug mainnet-debug testnet-debug betanet-debug compile-debug mainnet-test-build testnet-test-build betanet-test-build target/wasm32-unknown-unknown/release/aurora_engine.wasm target/wasm32-unknown-unknown/debug/aurora_engine.wasm .SECONDARY: From 9a56053919b5d7f49b1cb4bd4ad1569ebf4db7b7 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 28 Jul 2021 19:53:11 +0300 Subject: [PATCH 05/12] Fix ft_metadata & FTMetadata default & tests --- Makefile | 5 ----- src/fungible_token.rs | 2 +- src/lib.rs | 2 +- src/tests/eth_connector.rs | 14 ++++++++++++++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 943c375f8..8e9b34172 100644 --- a/Makefile +++ b/Makefile @@ -106,11 +106,6 @@ clean: @rm -Rf *.wasm cargo clean -test-pure: FEATURES=mainnet,integration-test,meta-call -test-pure: Cargo.toml Cargo.lock $(shell find src -name "*.rs") - RUSTFLAGS='-C link-arg=-s' $(CARGO) build --target wasm32-unknown-unknown --release --no-default-features --features=$(FEATURES) -Z avoid-dev-deps - $(CARGO) test --features mainnet-test - .PHONY: release mainnet testnet betanet compile-release test-build deploy check check-format check-clippy test test-sol format clean debug mainnet-debug testnet-debug betanet-debug compile-debug mainnet-test-build testnet-test-build betanet-test-build target/wasm32-unknown-unknown/release/aurora_engine.wasm target/wasm32-unknown-unknown/debug/aurora_engine.wasm .SECONDARY: diff --git a/src/fungible_token.rs b/src/fungible_token.rs index fa6a8edec..1e6a07c2b 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -27,7 +27,7 @@ pub struct FungibleToken { pub account_storage_usage: StorageUsage, } -#[derive(Default, BorshDeserialize, BorshSerialize, Clone)] +#[derive(BorshDeserialize, BorshSerialize, Clone)] pub struct FungibleTokenMetadata { pub spec: String, pub name: String, diff --git a/src/lib.rs b/src/lib.rs index b1dce2bf6..936d56f0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -592,7 +592,7 @@ mod contract { } #[no_mangle] - pub extern "C" fn get_metadata() { + pub extern "C" fn ft_metadata() { EthConnectorContract::get_instance().get_metadata(); } diff --git a/src/tests/eth_connector.rs b/src/tests/eth_connector.rs index 2c65e70d5..51b3f56db 100644 --- a/src/tests/eth_connector.rs +++ b/src/tests/eth_connector.rs @@ -28,6 +28,20 @@ const EVM_CUSTODIAN_ADDRESS: &'static str = "096DE9C2B8A5B8c22cEe3289B101f6960d6 const DEPOSITED_EVM_AMOUNT: u128 = 10200; const DEPOSITED_EVM_FEE: u128 = 200; +impl Default for FungibleTokenMetadata { + fn default() -> Self { + Self { + spec: "".to_string(), + name: "".to_string(), + symbol: "".to_string(), + icon: None, + reference: None, + reference_hash: None, + decimals: 0, + } + } +} + #[derive(BorshDeserialize, Debug)] pub struct IsUsedProofResult { pub is_used_proof: bool, From e18ab4818d8ff0f8998ae08a5aa99ee66195e708 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 28 Jul 2021 21:59:08 +0300 Subject: [PATCH 06/12] Added Metadata migration --- src/lib.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 936d56f0b..33067c193 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,7 +89,7 @@ mod contract { use crate::json::parse_json; use crate::prelude::{Address, ToString, TryInto, H160, H256, U256}; use crate::sdk; - use crate::storage::{bytes_to_key, KeyPrefix}; + use crate::storage::{bytes_to_key, EthConnectorStorageId, KeyPrefix}; use crate::types::{ near_account_to_evm_address, u256_to_arr, SdkExpect, SdkProcess, SdkUnwrap, ERR_FAILED_PARSE, @@ -180,8 +180,23 @@ mod contract { /// code. #[no_mangle] pub extern "C" fn state_migration() { - // This function is purposely left empty because we do not have any state migration - // to do. + // Only owner can call migration + sdk::assert_private_call(); + + let metadata_key = bytes_to_key( + KeyPrefix::EthConnector, + &[EthConnectorStorageId::FungibleTokenMetadata as u8], + ); + + //========================================================= + // Migrate Metadata + if !sdk::storage_has_key(&metadata_key[..]) { + use crate::fungible_token::FungibleTokenMetadata; + + let metadata = + FungibleTokenMetadata::try_from_slice(&sdk::read_input()).expect(ERR_FAILED_PARSE); + sdk::save_contract(&metadata_key, &metadata); + } } /// From 8ee99ba134612b25cfa7eb91fa803bb4daf8f257 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 4 Aug 2021 11:41:22 +0300 Subject: [PATCH 07/12] ft_metadata: return json --- src/connector.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/connector.rs b/src/connector.rs index 7f47b4dad..8f19036a9 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -629,7 +629,33 @@ impl EthConnectorContract { /// Return metdata pub fn get_metadata(&self) { - sdk::return_output(&self.metadata.try_to_vec().unwrap()[..]); + let icon = if let Some(ref icon) = self.metadata.icon { + format!(r#""{}""#, icon) + } else { + "null".to_string() + }; + let reference = if let Some(ref reference) = self.metadata.reference { + format!(r#""{}""#, reference) + } else { + "null".to_string() + }; + let reference_hash = if let Some(ref reference_hash) = self.metadata.reference_hash { + format!("{:?}", reference_hash) + } else { + "null".to_string() + }; + let json_data = format!( + r#"{{"spec": "{}", "name": "{}", "symbol": "{}", "icon": {}, "reference": {}, "reference_hash": {}, "decimals": {:?}}}"#, + self.metadata.spec, + self.metadata.name, + self.metadata.symbol, + icon, + reference, + reference_hash, + self.metadata.decimals, + ); + // Return JSON + sdk::return_output(&json_data.as_bytes()); } } From 95282b828785331dd5e2aa18e07ac3dc991bab29 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 4 Aug 2021 11:59:49 +0300 Subject: [PATCH 08/12] state migration metadata - changed to empty default values --- src/lib.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 33067c193..02a431613 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -193,8 +193,15 @@ mod contract { if !sdk::storage_has_key(&metadata_key[..]) { use crate::fungible_token::FungibleTokenMetadata; - let metadata = - FungibleTokenMetadata::try_from_slice(&sdk::read_input()).expect(ERR_FAILED_PARSE); + let metadata = FungibleTokenMetadata { + spec: "".to_string(), + symbol: "".to_string(), + name: "".to_string(), + icon: None, + reference: None, + reference_hash: None, + decimals: 18, + }; sdk::save_contract(&metadata_key, &metadata); } } From 8d2af2afe4f9c8f3bc771c9e85568c278e85e6c8 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 6 Aug 2021 19:26:30 +0300 Subject: [PATCH 09/12] change default metadata --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 02a431613..a9aa6feb1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -194,9 +194,9 @@ mod contract { use crate::fungible_token::FungibleTokenMetadata; let metadata = FungibleTokenMetadata { - spec: "".to_string(), - symbol: "".to_string(), - name: "".to_string(), + spec: "ft-1.0.0".to_string(), + symbol: "ETH".to_string(), + name: "Ether".to_string(), icon: None, reference: None, reference_hash: None, From b4d2bbbe0292b94ecc9aac93def94ca7f45f2c78 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 11 Aug 2021 11:48:45 +0300 Subject: [PATCH 10/12] Modified get_metadata as optional --- src/connector.rs | 67 +++++++++++++++++++++++++++++------------------- src/lib.rs | 27 ++----------------- 2 files changed, 43 insertions(+), 51 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 8f19036a9..56ebddd7d 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -28,7 +28,7 @@ pub struct EthConnectorContract { contract: EthConnector, ft: FungibleToken, paused_mask: PausedMask, - metadata: FungibleTokenMetadata, + metadata: Option, } /// eth-connector specific data @@ -59,7 +59,7 @@ impl EthConnectorContract { contract: Self::get_contract_data(&EthConnectorStorageId::Contract), ft: Self::get_contract_data(&EthConnectorStorageId::FungibleToken), paused_mask: Self::get_contract_data(&EthConnectorStorageId::PausedMask), - metadata: Self::get_contract_data(&EthConnectorStorageId::FungibleTokenMetadata), + metadata: Self::get_contract_metadata(), } } @@ -72,6 +72,14 @@ impl EthConnectorContract { T::try_from_slice(&data[..]).unwrap() } + fn get_contract_metadata() -> Option { + let data = sdk::read_storage(&Self::get_contract_key( + &EthConnectorStorageId::FungibleTokenMetadata, + )) + .expect("Failed read storage"); + FungibleTokenMetadata::try_from_slice(&data[..]).ok() + } + /// Init eth-connector contract specific data pub fn init_contract(args: InitCallArgs) { // Check is it already initialized @@ -93,7 +101,7 @@ impl EthConnectorContract { // Register FT account for current contract ft.internal_register_account(&owner_id); - let metadata = args.metadata; + let metadata = Some(args.metadata); let paused_mask = UNPAUSE_ALL; sdk::save_contract( @@ -629,31 +637,38 @@ impl EthConnectorContract { /// Return metdata pub fn get_metadata(&self) { - let icon = if let Some(ref icon) = self.metadata.icon { - format!(r#""{}""#, icon) - } else { - "null".to_string() - }; - let reference = if let Some(ref reference) = self.metadata.reference { - format!(r#""{}""#, reference) + let json_data = if let Some(ref metadata) = self.metadata { + let icon = if let Some(ref icon) = metadata.icon { + format!(r#""{}""#, icon) + } else { + "null".to_string() + }; + let reference = if let Some(ref reference) = metadata.reference { + format!(r#""{}""#, reference) + } else { + "null".to_string() + }; + let reference_hash = if let Some(ref reference_hash) = metadata.reference_hash { + format!("{:?}", reference_hash) + } else { + "null".to_string() + }; + format!( + r#"{{"spec": "{}", "name": "{}", "symbol": "{}", "icon": {}, "reference": {}, "reference_hash": {}, "decimals": {:?}}}"#, + metadata.spec, + metadata.name, + metadata.symbol, + icon, + reference, + reference_hash, + metadata.decimals, + ) } else { - "null".to_string() + format!( + r#"{{"spec": "{}", "name": "{}", "symbol": "{}", "icon": {}, "reference": {}, "reference_hash": {}, "decimals": {:?}}}"#, + "ft-1.0.0", "ETH", "Ether", "", "", "", 18, + ) }; - let reference_hash = if let Some(ref reference_hash) = self.metadata.reference_hash { - format!("{:?}", reference_hash) - } else { - "null".to_string() - }; - let json_data = format!( - r#"{{"spec": "{}", "name": "{}", "symbol": "{}", "icon": {}, "reference": {}, "reference_hash": {}, "decimals": {:?}}}"#, - self.metadata.spec, - self.metadata.name, - self.metadata.symbol, - icon, - reference, - reference_hash, - self.metadata.decimals, - ); // Return JSON sdk::return_output(&json_data.as_bytes()); } diff --git a/src/lib.rs b/src/lib.rs index a9aa6feb1..b4a426cfa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,7 +89,7 @@ mod contract { use crate::json::parse_json; use crate::prelude::{Address, ToString, TryInto, H160, H256, U256}; use crate::sdk; - use crate::storage::{bytes_to_key, EthConnectorStorageId, KeyPrefix}; + use crate::storage::{bytes_to_key, KeyPrefix}; use crate::types::{ near_account_to_evm_address, u256_to_arr, SdkExpect, SdkProcess, SdkUnwrap, ERR_FAILED_PARSE, @@ -180,30 +180,7 @@ mod contract { /// code. #[no_mangle] pub extern "C" fn state_migration() { - // Only owner can call migration - sdk::assert_private_call(); - - let metadata_key = bytes_to_key( - KeyPrefix::EthConnector, - &[EthConnectorStorageId::FungibleTokenMetadata as u8], - ); - - //========================================================= - // Migrate Metadata - if !sdk::storage_has_key(&metadata_key[..]) { - use crate::fungible_token::FungibleTokenMetadata; - - let metadata = FungibleTokenMetadata { - spec: "ft-1.0.0".to_string(), - symbol: "ETH".to_string(), - name: "Ether".to_string(), - icon: None, - reference: None, - reference_hash: None, - decimals: 18, - }; - sdk::save_contract(&metadata_key, &metadata); - } + // TODO: currently we don't have migrations } /// From ed63447233bd6c4e3786f40280ff72115a2febb2 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 11 Aug 2021 13:23:43 +0000 Subject: [PATCH 11/12] Do not include metadata as field in eth-connector struct; convert to JsonValue for serialization; include icon in default value; serialize reference_hash as base64; add sanity test --- Cargo.toml | 2 +- etc/state-migration-test/Cargo.lock | 7 ++++ src/connector.rs | 60 +++++------------------------ src/fungible_token.rs | 52 +++++++++++++++++++++++++ src/json.rs | 1 + src/lib.rs | 6 ++- src/tests/eth_connector.rs | 14 ------- src/tests/sanity.rs | 20 ++++++++++ 8 files changed, 95 insertions(+), 67 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 86cdca639..3dde7ba07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ lto = true opt-level = 3 [dependencies] +base64 = { version = "0.13.0", default-features = false, features = ["alloc"] } blake2 = { git = "https://github.com/near/near-blake2.git", version = "0.9.1", default-features = false } borsh = { version = "0.8.2", default-features = false } bn = { package = "aurora-bn", git = "https://github.com/aurora-is-near/aurora-bn.git", default-features = false } @@ -80,7 +81,6 @@ rand = "0.7.3" criterion = "0.3.4" git2 = "0.13" lazy-static-include = "3.1.1" -base64 = "0.13.0" [features] default = ["sha2", "std"] diff --git a/etc/state-migration-test/Cargo.lock b/etc/state-migration-test/Cargo.lock index afcdb50df..eaf655a5e 100644 --- a/etc/state-migration-test/Cargo.lock +++ b/etc/state-migration-test/Cargo.lock @@ -34,6 +34,7 @@ name = "aurora-engine" version = "1.5.0" dependencies = [ "aurora-bn", + "base64", "blake2", "borsh", "byte-slice-cast", @@ -67,6 +68,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "beef" version = "0.5.0" diff --git a/src/connector.rs b/src/connector.rs index a8e90dfdd..5e1c62e4a 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -28,7 +28,6 @@ pub struct EthConnectorContract { contract: EthConnector, ft: FungibleToken, paused_mask: PausedMask, - metadata: Option, } /// eth-connector specific data @@ -59,7 +58,6 @@ impl EthConnectorContract { contract: Self::get_contract_data(&EthConnectorStorageId::Contract), ft: Self::get_contract_data(&EthConnectorStorageId::FungibleToken), paused_mask: Self::get_contract_data(&EthConnectorStorageId::PausedMask), - metadata: Self::get_contract_metadata(), } } @@ -72,14 +70,6 @@ impl EthConnectorContract { T::try_from_slice(&data[..]).unwrap() } - fn get_contract_metadata() -> Option { - let data = sdk::read_storage(&Self::get_contract_key( - &EthConnectorStorageId::FungibleTokenMetadata, - )) - .expect("Failed read storage"); - FungibleTokenMetadata::try_from_slice(&data[..]).ok() - } - /// Init eth-connector contract specific data pub fn init_contract(args: InitCallArgs) { // Check is it already initialized @@ -101,7 +91,10 @@ impl EthConnectorContract { // Register FT account for current contract ft.internal_register_account(&owner_id); - let metadata = Some(args.metadata); + sdk::save_contract( + &Self::get_contract_key(&EthConnectorStorageId::FungibleTokenMetadata), + &args.metadata, + ); let paused_mask = UNPAUSE_ALL; sdk::save_contract( @@ -113,7 +106,6 @@ impl EthConnectorContract { contract: contract_data, ft, paused_mask, - metadata, } .save_ft_contract(); } @@ -597,10 +589,6 @@ impl EthConnectorContract { &Self::get_contract_key(&EthConnectorStorageId::FungibleToken), &self.ft, ); - sdk::save_contract( - &Self::get_contract_key(&EthConnectorStorageId::FungibleTokenMetadata), - &self.metadata, - ); } /// Generate key for used events from Prood @@ -636,41 +624,11 @@ impl EthConnectorContract { } /// Return metdata - pub fn get_metadata(&self) { - let json_data = if let Some(ref metadata) = self.metadata { - let icon = if let Some(ref icon) = metadata.icon { - format!(r#""{}""#, icon) - } else { - "null".to_string() - }; - let reference = if let Some(ref reference) = metadata.reference { - format!(r#""{}""#, reference) - } else { - "null".to_string() - }; - let reference_hash = if let Some(ref reference_hash) = metadata.reference_hash { - format!("{:?}", reference_hash) - } else { - "null".to_string() - }; - format!( - r#"{{"spec": "{}", "name": "{}", "symbol": "{}", "icon": {}, "reference": {}, "reference_hash": {}, "decimals": {:?}}}"#, - metadata.spec, - metadata.name, - metadata.symbol, - icon, - reference, - reference_hash, - metadata.decimals, - ) - } else { - format!( - r#"{{"spec": "{}", "name": "{}", "symbol": "{}", "icon": {}, "reference": {}, "reference_hash": {}, "decimals": {:?}}}"#, - "ft-1.0.0", "ETH", "Ether", "", "", "", 18, - ) - }; - // Return JSON - sdk::return_output(json_data.as_bytes()); + pub fn get_metadata() -> Option { + sdk::read_storage(&Self::get_contract_key( + &EthConnectorStorageId::FungibleTokenMetadata, + )) + .and_then(|data| FungibleTokenMetadata::try_from_slice(&data).ok()) } } diff --git a/src/fungible_token.rs b/src/fungible_token.rs index 1e6a07c2b..de57c10cb 100644 --- a/src/fungible_token.rs +++ b/src/fungible_token.rs @@ -1,5 +1,7 @@ +use crate::json::JsonValue; #[cfg(feature = "log")] use crate::prelude::format; +use crate::prelude::BTreeMap; use crate::types::*; use borsh::{BorshDeserialize, BorshSerialize}; use { @@ -38,6 +40,56 @@ pub struct FungibleTokenMetadata { pub decimals: u8, } +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, + } + } +} + +impl From for JsonValue { + fn from(metadata: FungibleTokenMetadata) -> Self { + let mut kvs = BTreeMap::new(); + kvs.insert("spec".to_string(), JsonValue::String(metadata.spec)); + kvs.insert("name".to_string(), JsonValue::String(metadata.name)); + kvs.insert("symbol".to_string(), JsonValue::String(metadata.symbol)); + kvs.insert( + "icon".to_string(), + metadata + .icon + .map(JsonValue::String) + .unwrap_or(JsonValue::Null), + ); + kvs.insert( + "reference".to_string(), + metadata + .reference + .map(JsonValue::String) + .unwrap_or(JsonValue::Null), + ); + kvs.insert( + "reference_hash".to_string(), + metadata + .reference_hash + .map(|hash| JsonValue::String(base64::encode(hash))) + .unwrap_or(JsonValue::Null), + ); + kvs.insert( + "decimals".to_string(), + JsonValue::U64(metadata.decimals as u64), + ); + + JsonValue::Object(kvs) + } +} + impl FungibleToken { pub fn new() -> Self { Self::default() diff --git a/src/json.rs b/src/json.rs index 39d68ce88..242699d73 100644 --- a/src/json.rs +++ b/src/json.rs @@ -5,6 +5,7 @@ use rjson::{Array, Null, Object, Value}; #[cfg(test)] use std::collections::BTreeMap; +#[derive(PartialEq)] pub enum JsonValue { Null, F64(f64), diff --git a/src/lib.rs b/src/lib.rs index ada90bd22..3650e1dc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,6 +78,7 @@ mod contract { use crate::connector::EthConnectorContract; use crate::engine::{Engine, EngineState, GasPaymentError}; + use crate::fungible_token::FungibleTokenMetadata; #[cfg(feature = "evm_bully")] use crate::parameters::{BeginBlockArgs, BeginChainArgs}; use crate::parameters::{ @@ -638,7 +639,10 @@ mod contract { #[no_mangle] pub extern "C" fn ft_metadata() { - EthConnectorContract::get_instance().get_metadata(); + let metadata: FungibleTokenMetadata = + EthConnectorContract::get_metadata().unwrap_or_default(); + let json_data = crate::json::JsonValue::from(metadata); + sdk::return_output(json_data.to_string().as_bytes()) } #[cfg(feature = "integration-test")] diff --git a/src/tests/eth_connector.rs b/src/tests/eth_connector.rs index 51b3f56db..2c65e70d5 100644 --- a/src/tests/eth_connector.rs +++ b/src/tests/eth_connector.rs @@ -28,20 +28,6 @@ const EVM_CUSTODIAN_ADDRESS: &'static str = "096DE9C2B8A5B8c22cEe3289B101f6960d6 const DEPOSITED_EVM_AMOUNT: u128 = 10200; const DEPOSITED_EVM_FEE: u128 = 200; -impl Default for FungibleTokenMetadata { - fn default() -> Self { - Self { - spec: "".to_string(), - name: "".to_string(), - symbol: "".to_string(), - icon: None, - reference: None, - reference_hash: None, - decimals: 0, - } - } -} - #[derive(BorshDeserialize, Debug)] pub struct IsUsedProofResult { pub is_used_proof: bool, diff --git a/src/tests/sanity.rs b/src/tests/sanity.rs index 2be54a850..4268d7393 100644 --- a/src/tests/sanity.rs +++ b/src/tests/sanity.rs @@ -1,3 +1,4 @@ +use crate::fungible_token::FungibleTokenMetadata; use crate::parameters::{SubmitResult, TransactionStatus}; use crate::prelude::{Address, U256}; use crate::test_utils; @@ -318,6 +319,25 @@ fn test_block_hash_contract() { test_utils::panic_on_fail(result.status); } +#[test] +fn test_ft_metadata() { + let mut runner = test_utils::deploy_evm(); + + let (maybe_outcome, maybe_error) = runner.call( + "ft_metadata", + runner.context.signer_account_id.clone(), + Vec::new(), + ); + assert!(maybe_error.is_none()); + let outcome = maybe_outcome.unwrap(); + let json_value = crate::json::parse_json(&outcome.return_data.as_value().unwrap()).unwrap(); + + assert_eq!( + json_value, + crate::json::JsonValue::from(FungibleTokenMetadata::default()) + ); +} + // Same as `test_eth_transfer_insufficient_balance` above, except runs through // `near-sdk-sim` instead of `near-vm-runner`. This is important because `near-sdk-sim` // has more production logic, in particular, state revert on contract panic. From 91b616945341f9497955e0539117f6047bd6acbb Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 11 Aug 2021 13:39:06 +0000 Subject: [PATCH 12/12] Remove unnecessary clone --- src/connector.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/connector.rs b/src/connector.rs index 5e1c62e4a..d8b7580cd 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -82,7 +82,7 @@ impl EthConnectorContract { let contract_data = Self::set_contract_data(SetContractDataCallArgs { prover_account: args.prover_account, eth_custodian_address: args.eth_custodian_address, - metadata: args.metadata.clone(), + metadata: args.metadata, }); let current_account_id = sdk::current_account_id(); @@ -91,11 +91,6 @@ impl EthConnectorContract { // Register FT account for current contract ft.internal_register_account(&owner_id); - sdk::save_contract( - &Self::get_contract_key(&EthConnectorStorageId::FungibleTokenMetadata), - &args.metadata, - ); - let paused_mask = UNPAUSE_ALL; sdk::save_contract( &Self::get_contract_key(&EthConnectorStorageId::PausedMask), @@ -124,6 +119,11 @@ impl EthConnectorContract { &contract_data, ); + sdk::save_contract( + &Self::get_contract_key(&EthConnectorStorageId::FungibleTokenMetadata), + &args.metadata, + ); + contract_data }