From 91d786e6ebe8c91509c7675cf46ce71d1720ec2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Mon, 15 Jan 2024 21:50:49 +0200 Subject: [PATCH] chore: fix various small nits --- .github/workflows/test.yml | 9 - near-sdk/src/environment/env.rs | 4 +- near-sdk/src/environment/mock/external.rs | 216 ------------------ .../src/environment/mock/mocked_blockchain.rs | 11 +- near-sdk/src/environment/mock/mod.rs | 2 - near-sdk/src/environment/mock/receipt.rs | 76 +++++- near-sdk/src/promise.rs | 29 +-- near-sdk/src/store/unordered_set/mod.rs | 2 +- near-sdk/src/test_utils/mod.rs | 14 +- near-sdk/src/types/public_key.rs | 34 +++ 10 files changed, 129 insertions(+), 268 deletions(-) delete mode 100644 near-sdk/src/environment/mock/external.rs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d3bfc89cf..96063203c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,15 +23,6 @@ jobs: toolchain: ${{ matrix.toolchain }} default: true target: wasm32-unknown-unknown - - name: downgrade `anstyle`,`anstyle-parse`,`anstyle-query`,`clap`,`clap_lex`, `home` crates to support older Rust toolchain - if: matrix.toolchain == '1.72.1' - run: | - cargo update -p anstyle --precise 1.0.2 - cargo update -p anstyle-query --precise 1.0.0 - cargo update -p anstyle-parse --precise 0.2.1 - cargo update -p clap --precise 4.3.24 - cargo update -p clap_lex --precise 0.5.0 - cargo update -p home --precise 0.5.5 - uses: Swatinem/rust-cache@v1 - name: Test run: cargo test --all --features unstable,legacy diff --git a/near-sdk/src/environment/env.rs b/near-sdk/src/environment/env.rs index 6ccc56fc3..1e89fe9ad 100644 --- a/near-sdk/src/environment/env.rs +++ b/near-sdk/src/environment/env.rs @@ -79,9 +79,9 @@ pub(crate) unsafe fn read_register_fixed_64(register_id: u64) -> [u8; 64] { /// low-level blockchain interfacr that implements `BlockchainInterface` trait. In most cases you /// want to use `testing_env!` macro to set it. /// -/// ```ignore +/// ``` /// # let context = near_sdk::test_utils::VMContextBuilder::new().build(); -/// # let vm_config = near_sdk::VMConfig::test(); +/// # let vm_config = near_sdk::test_vm_config(); /// # let fees_config = near_sdk::RuntimeFeesConfig::test(); /// # let storage = Default::default(); /// # let validators = Default::default(); diff --git a/near-sdk/src/environment/mock/external.rs b/near-sdk/src/environment/mock/external.rs deleted file mode 100644 index 547d3f27a..000000000 --- a/near-sdk/src/environment/mock/external.rs +++ /dev/null @@ -1,216 +0,0 @@ -use near_gas::NearGas; -use near_primitives::types::TrieNodesCount; -use near_primitives_core::hash::{hash, CryptoHash}; -use near_primitives_core::types::{AccountId, Balance, Gas, GasWeight}; -use near_token::NearToken; -use near_vm_runner::logic::types::ReceiptIndex; -use near_vm_runner::logic::{External, StorageGetMode, ValuePtr}; -use std::collections::HashMap; - -use super::receipt::MockAction; - -type Result = ::core::result::Result; - -#[derive(Default, Clone)] -/// Emulates the trie and the mock handling code for the SDK. This is a modified version of -/// `MockedExternal` from `near_vm_logic`. -pub(crate) struct SdkExternal { - pub fake_trie: HashMap, Vec>, - pub validators: HashMap, - pub action_log: Vec, - data_count: u64, -} - -pub struct MockedValuePtr { - value: Vec, -} - -impl ValuePtr for MockedValuePtr { - fn len(&self) -> u32 { - self.value.len() as u32 - } - - fn deref(&self) -> Result> { - Ok(self.value.clone()) - } -} - -impl SdkExternal { - pub fn new() -> Self { - Self::default() - } -} - -impl External for SdkExternal { - fn storage_set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { - self.fake_trie.insert(key.to_vec(), value.to_vec()); - Ok(()) - } - - fn storage_get( - &self, - key: &[u8], - _storage_get_mode: StorageGetMode, - ) -> Result>> { - Ok(self - .fake_trie - .get(key) - .map(|value| Box::new(MockedValuePtr { value: value.clone() }) as Box<_>)) - } - - fn storage_remove(&mut self, key: &[u8]) -> Result<()> { - self.fake_trie.remove(key); - Ok(()) - } - - fn storage_remove_subtree(&mut self, prefix: &[u8]) -> Result<()> { - self.fake_trie.retain(|key, _| !key.starts_with(prefix)); - Ok(()) - } - - fn storage_has_key(&mut self, key: &[u8], _mode: StorageGetMode) -> Result { - Ok(self.fake_trie.contains_key(key)) - } - - fn generate_data_id(&mut self) -> CryptoHash { - // Generates some hash for the data ID to receive data. This hash should not be functionally - // used in any mocked contexts. - let data_id = hash(&self.data_count.to_le_bytes()); - self.data_count += 1; - data_id - } - - fn get_trie_nodes_count(&self) -> TrieNodesCount { - TrieNodesCount { db_reads: 0, mem_reads: 0 } - } - - fn validator_stake(&self, account_id: &AccountId) -> Result> { - Ok(self.validators.get(account_id).cloned()) - } - - fn validator_total_stake(&self) -> Result { - Ok(self.validators.values().sum()) - } - - fn create_receipt( - &mut self, - receipt_indices: Vec, - receiver_id: AccountId, - ) -> Result { - let index = self.action_log.len(); - self.action_log.push(MockAction::CreateReceipt { receipt_indices, receiver_id }); - Ok(index as u64) - } - - fn append_action_create_account(&mut self, receipt_index: ReceiptIndex) -> Result<()> { - self.action_log.push(MockAction::CreateAccount { receipt_index }); - Ok(()) - } - - fn append_action_deploy_contract( - &mut self, - receipt_index: ReceiptIndex, - code: Vec, - ) -> Result<()> { - self.action_log.push(MockAction::DeployContract { receipt_index, code }); - Ok(()) - } - - fn append_action_function_call_weight( - &mut self, - receipt_index: ReceiptIndex, - method_name: Vec, - args: Vec, - attached_deposit: Balance, - prepaid_gas: Gas, - gas_weight: GasWeight, - ) -> Result<()> { - self.action_log.push(MockAction::FunctionCallWeight { - receipt_index, - method_name, - args, - attached_deposit: NearToken::from_yoctonear(attached_deposit), - prepaid_gas: NearGas::from_gas(prepaid_gas), - gas_weight, - }); - Ok(()) - } - - fn append_action_transfer( - &mut self, - receipt_index: ReceiptIndex, - deposit: Balance, - ) -> Result<()> { - self.action_log.push(MockAction::Transfer { - receipt_index, - deposit: NearToken::from_yoctonear(deposit), - }); - Ok(()) - } - - fn append_action_stake( - &mut self, - receipt_index: ReceiptIndex, - stake: Balance, - public_key: near_crypto::PublicKey, - ) { - self.action_log.push(MockAction::Stake { - receipt_index, - stake: NearToken::from_yoctonear(stake), - public_key, - }); - } - - fn append_action_add_key_with_full_access( - &mut self, - receipt_index: ReceiptIndex, - public_key: near_crypto::PublicKey, - nonce: near_primitives_core::types::Nonce, - ) { - self.action_log.push(MockAction::AddKeyWithFullAccess { receipt_index, public_key, nonce }); - } - - fn append_action_add_key_with_function_call( - &mut self, - receipt_index: ReceiptIndex, - public_key: near_crypto::PublicKey, - nonce: near_primitives_core::types::Nonce, - allowance: Option, - receiver_id: AccountId, - method_names: Vec>, - ) -> Result<()> { - self.action_log.push(MockAction::AddKeyWithFunctionCall { - receipt_index, - public_key, - nonce, - allowance: allowance.map(NearToken::from_yoctonear), - receiver_id, - method_names, - }); - Ok(()) - } - - fn append_action_delete_key( - &mut self, - receipt_index: ReceiptIndex, - public_key: near_crypto::PublicKey, - ) { - self.action_log.push(MockAction::DeleteKey { receipt_index, public_key }); - } - - fn append_action_delete_account( - &mut self, - receipt_index: ReceiptIndex, - beneficiary_id: AccountId, - ) -> Result<()> { - self.action_log.push(MockAction::DeleteAccount { receipt_index, beneficiary_id }); - Ok(()) - } - - fn get_receipt_receiver(&self, receipt_index: ReceiptIndex) -> &AccountId { - match &self.action_log[receipt_index as usize] { - MockAction::CreateReceipt { receiver_id, .. } => receiver_id, - _ => panic!("not a valid receipt index!"), - } - } -} diff --git a/near-sdk/src/environment/mock/mocked_blockchain.rs b/near-sdk/src/environment/mock/mocked_blockchain.rs index 9d36752f1..9ede0f5b3 100644 --- a/near-sdk/src/environment/mock/mocked_blockchain.rs +++ b/near-sdk/src/environment/mock/mocked_blockchain.rs @@ -1,4 +1,4 @@ -use super::{Receipt, SdkExternal}; +use super::Receipt; use crate::mock::MockAction; // TODO replace with near_vm_logic::mocks::mock_memory::MockedMemory after updating version from 0.17 use crate::mock::mocked_memory::MockedMemory; @@ -7,6 +7,7 @@ use crate::types::{NearToken, PromiseResult}; use crate::VMContext; use near_parameters::{RuntimeConfigStore, RuntimeFeesConfig}; use near_primitives_core::version::PROTOCOL_VERSION; +use near_vm_runner::logic::mocks::mock_external::MockedExternal; use near_vm_runner::logic::types::{PromiseResult as VmPromiseResult, ReceiptIndex}; use near_vm_runner::logic::{External, MemoryLike, VMLogic}; use std::cell::RefCell; @@ -48,7 +49,7 @@ impl Default for MockedBlockchain { } struct LogicFixture { - ext: Box, + ext: Box, memory: Box, #[allow(clippy::box_collection)] promise_results: Box>, @@ -66,7 +67,7 @@ impl MockedBlockchain { validators: HashMap, memory_opt: Option>, ) -> Self { - let mut ext = Box::new(SdkExternal::new()); + let mut ext = Box::new(MockedExternal::new()); let context = sdk_context_to_vm_context(context); ext.fake_trie = storage; ext.validators = @@ -100,7 +101,8 @@ impl MockedBlockchain { /// Returns metadata about the receipts created pub fn created_receipts(&self) -> Vec { let action_log = &self.logic_fixture.ext.action_log; - println!("{:#?}", action_log); + let action_log: Vec = + action_log.clone().into_iter().map(>::from).collect(); let create_receipts: Vec<(usize, MockAction)> = action_log .clone() .into_iter() @@ -130,7 +132,6 @@ impl MockedBlockchain { Receipt { receiver_id, actions, receipt_indices } }) .collect(); - println!("{:#?}", result); result } diff --git a/near-sdk/src/environment/mock/mod.rs b/near-sdk/src/environment/mock/mod.rs index 0ad9dce76..b9cd6b2df 100644 --- a/near-sdk/src/environment/mock/mod.rs +++ b/near-sdk/src/environment/mock/mod.rs @@ -1,11 +1,9 @@ -mod external; mod mocked_blockchain; mod mocked_memory; mod receipt; pub use mocked_blockchain::test_vm_config; -pub(crate) use self::external::SdkExternal; pub use self::mocked_blockchain::MockedBlockchain; pub use self::receipt::{MockAction, Receipt}; use core::cell::RefCell; diff --git a/near-sdk/src/environment/mock/receipt.rs b/near-sdk/src/environment/mock/receipt.rs index f3851fdf4..a41cc2c5b 100644 --- a/near-sdk/src/environment/mock/receipt.rs +++ b/near-sdk/src/environment/mock/receipt.rs @@ -1,4 +1,5 @@ use near_primitives_core::types::GasWeight; +use near_vm_runner::logic::mocks::mock_external::MockAction as LogicMockAction; use near_vm_runner::logic::types::ReceiptIndex; use crate::{AccountId, Gas, NearToken}; @@ -60,7 +61,7 @@ pub enum MockAction { nonce: u64, allowance: Option, receiver_id: AccountId, - method_names: Vec>, + method_names: Vec, }, AddKeyWithFullAccess { receipt_index: ReceiptIndex, @@ -85,3 +86,76 @@ impl MockAction { } } } + +fn map_vec_str(vec_str: Vec>) -> Vec { + vec_str + .into_iter() + .map(|element| { + let string: String = String::from_utf8(element).unwrap(); + string + }) + .collect() +} + +impl From for MockAction { + fn from(value: LogicMockAction) -> Self { + match value { + LogicMockAction::CreateReceipt { receipt_indices, receiver_id } => { + Self::CreateReceipt { receipt_indices, receiver_id } + } + LogicMockAction::CreateAccount { receipt_index } => { + Self::CreateAccount { receipt_index } + } + LogicMockAction::DeployContract { receipt_index, code } => { + Self::DeployContract { receipt_index, code } + } + LogicMockAction::FunctionCallWeight { + receipt_index, + method_name, + args, + attached_deposit, + prepaid_gas, + gas_weight, + } => Self::FunctionCallWeight { + receipt_index, + method_name, + args, + attached_deposit: NearToken::from_yoctonear(attached_deposit), + prepaid_gas: Gas::from_gas(prepaid_gas), + gas_weight, + }, + LogicMockAction::Transfer { receipt_index, deposit } => { + MockAction::Transfer { receipt_index, deposit: NearToken::from_yoctonear(deposit) } + } + LogicMockAction::Stake { receipt_index, stake, public_key } => MockAction::Stake { + receipt_index, + stake: NearToken::from_yoctonear(stake), + public_key, + }, + LogicMockAction::DeleteAccount { receipt_index, beneficiary_id } => { + Self::DeleteAccount { receipt_index, beneficiary_id } + } + LogicMockAction::DeleteKey { receipt_index, public_key } => { + Self::DeleteKey { receipt_index, public_key } + } + LogicMockAction::AddKeyWithFunctionCall { + receipt_index, + public_key, + nonce, + allowance, + receiver_id, + method_names, + } => Self::AddKeyWithFunctionCall { + receipt_index, + public_key, + nonce, + allowance: allowance.map(NearToken::from_yoctonear), + receiver_id, + method_names: map_vec_str(method_names), + }, + LogicMockAction::AddKeyWithFullAccess { receipt_index, public_key, nonce } => { + Self::AddKeyWithFullAccess { receipt_index, public_key, nonce } + } + } + } +} diff --git a/near-sdk/src/promise.rs b/near-sdk/src/promise.rs index b7228100d..5b42571c4 100644 --- a/near-sdk/src/promise.rs +++ b/near-sdk/src/promise.rs @@ -636,20 +636,10 @@ mod tests { let first_receipt = receipts.into_iter().next().unwrap(); first_receipt.actions.into_iter() } - fn convert_key(public_key: &PublicKey) -> near_crypto::PublicKey { - // TODO: add Secp conversion - - let key_bytes = public_key.clone().into_bytes(); - let public_key = near_crypto::PublicKey::ED25519( - near_crypto::ED25519PublicKey::try_from(&key_bytes.as_slice()[1..]).unwrap(), - ); - public_key - } fn has_add_key_with_full_access(public_key: PublicKey, nonce: Option) -> bool { + let public_key = near_crypto::PublicKey::try_from(public_key.clone()).unwrap(); get_actions().any(|el| { - let public_key = convert_key(&public_key); - matches!( el, MockAction::AddKeyWithFullAccess { public_key: p, nonce: n, receipt_index: _, } @@ -659,16 +649,6 @@ mod tests { }) } - fn map_vec_str(vec_str: Vec>) -> Vec { - vec_str - .into_iter() - .map(|element| { - let string: String = String::from_utf8(element).unwrap(); - string - }) - .collect() - } - fn has_add_key_with_function_call( public_key: PublicKey, allowance: u128, @@ -676,9 +656,8 @@ mod tests { function_names: String, nonce: Option, ) -> bool { + let public_key = near_crypto::PublicKey::try_from(public_key.clone()).unwrap(); get_actions().any(|el| { - let public_key = convert_key(&public_key); - matches!( el, MockAction::AddKeyWithFunctionCall { @@ -692,7 +671,7 @@ mod tests { if p == public_key && a.unwrap() == NearToken::from_yoctonear(allowance) && r == receiver_id - && map_vec_str(method_names.clone()) == function_names.split(',').collect::>() + && method_names.clone() == function_names.split(',').collect::>() && (nonce.is_none() || Some(n) == nonce) ) }) @@ -855,8 +834,8 @@ mod tests { .add_full_access_key(public_key.clone()) .delete_key(public_key.clone()); } + let public_key = near_crypto::PublicKey::try_from(public_key.clone()).unwrap(); - let public_key = convert_key(&public_key); let has_action = get_actions().any(|el| { matches!( el, diff --git a/near-sdk/src/store/unordered_set/mod.rs b/near-sdk/src/store/unordered_set/mod.rs index b0114c3a7..d704557fe 100644 --- a/near-sdk/src/store/unordered_set/mod.rs +++ b/near-sdk/src/store/unordered_set/mod.rs @@ -44,7 +44,7 @@ use std::fmt; /// [`UnorderedSet`] also implements various binary operations, which allow /// for iterating various combinations of two sets. /// -/// ```ignore +/// ``` /// use near_sdk::store::UnorderedSet; /// use std::collections::HashSet; /// diff --git a/near-sdk/src/test_utils/mod.rs b/near-sdk/src/test_utils/mod.rs index 993a6d706..aae576724 100644 --- a/near-sdk/src/test_utils/mod.rs +++ b/near-sdk/src/test_utils/mod.rs @@ -15,7 +15,7 @@ pub use context::{accounts, testing_env_with_promise_results, VMContextBuilder}; /// [`MockedBlockchain`], in this order: /// - `context`: [`VMContext`] which contains some core information about /// the blockchain and message data which can be used from the smart contract. -/// - `config` (optional): [`VMConfig`] which contains some additional information +/// - `config` (optional): [`vm::Config`] which contains some additional information /// about the VM to configure parameters not directly related to the transaction being executed. /// - `fee_config`(optional): [`RuntimeFeesConfig`] which configures the /// fees for execution and storage of transactions. @@ -28,10 +28,10 @@ pub use context::{accounts, testing_env_with_promise_results, VMContextBuilder}; /// /// # Example use /// -/// ```ignore -/// use near_sdk::testing_env; +/// ``` +/// use near_sdk::{testing_env, test_vm_config}; /// use near_sdk::test_utils::{accounts, VMContextBuilder}; -/// use near_sdk::{VMConfig, RuntimeFeesConfig}; +/// use near_parameters::RuntimeFeesConfig; /// use std::collections::HashMap; /// /// # fn main() { @@ -44,7 +44,7 @@ pub use context::{accounts, testing_env_with_promise_results, VMContextBuilder}; /// // Or include arguments up to the five optional /// testing_env!( /// context, -/// VMConfig::test(), +/// test_vm_config(), /// RuntimeFeesConfig::test(), /// HashMap::default(), /// Vec::default(), @@ -54,8 +54,8 @@ pub use context::{accounts, testing_env_with_promise_results, VMContextBuilder}; /// /// [`MockedBlockchain`]: crate::mock::MockedBlockchain /// [`VMContext`]: crate::VMContext -/// [`VMConfig`]: crate::VMConfig -/// [`RuntimeFeesConfig`]: crate::RuntimeFeesConfig +/// [`vm::Config`]: near_parameters::vm::Config +/// [`RuntimeFeesConfig`]: near_parameters::RuntimeFeesConfig /// [`AccountId`]: crate::AccountId /// [`Balance`]: crate::Balance /// [`PromiseResult`]: crate::PromiseResult diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs index 3266fe667..366418e21 100644 --- a/near-sdk/src/types/public_key.rs +++ b/near-sdk/src/types/public_key.rs @@ -43,6 +43,40 @@ impl std::str::FromStr for CurveType { } } +#[cfg(all(not(target_arch = "wasm32"), feature = "unit-testing"))] +#[cfg(test)] +impl TryFrom for near_crypto::PublicKey { + type Error = ParsePublicKeyError; + + fn try_from(public_key: PublicKey) -> Result { + let curve_type = CurveType::from_u8(public_key.data[0])?; + let expected_len = curve_type.data_len(); + + let key_bytes = public_key.clone().into_bytes(); + if key_bytes.len() != expected_len + 1 { + return Err(ParsePublicKeyError { + kind: ParsePublicKeyErrorKind::InvalidLength(key_bytes.len()), + }); + } + + let data = &key_bytes.as_slice()[1..]; + match curve_type { + CurveType::ED25519 => { + let public_key = near_crypto::PublicKey::ED25519( + near_crypto::ED25519PublicKey::try_from(data).unwrap(), + ); + Ok(public_key) + } + CurveType::SECP256K1 => { + let public_key = near_crypto::PublicKey::SECP256K1( + near_crypto::Secp256K1PublicKey::try_from(data).unwrap(), + ); + Ok(public_key) + } + } + } +} + /// Public key in a binary format with base58 string serialization with human-readable curve. /// The key types currently supported are `secp256k1` and `ed25519`. ///