diff --git a/CHANGELOG.md b/CHANGELOG.md index 56e66ac4a83..3e4317a58bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,6 @@ * undo-block tool to reset the chain head from current head to its prev block. Use the tool by running: `./target/release/neard undo-block`. [#8681](https://github.com/near/nearcore/pull/8681) * Add prometheus metrics for expected number of blocks/chunks at the end of the epoch. [#8759](https://github.com/near/nearcore/pull/8759) * Node can sync State from S3. [#8789](https://github.com/near/nearcore/pull/8789) -* The contract runtime switched to using our fork of wasmer, with various improvements. [#8912](https://github.com/near/nearcore/pull/8912) * Node can sync State from local filesystem. [#8913](https://github.com/near/nearcore/pull/8913) * Add per shard granularity for chunks in validator info metric. [#8934](https://github.com/near/nearcore/pull/8934) @@ -67,14 +66,14 @@ to pay for the storage of their accounts. [Stabilization #8601](https://github.com/near/nearcore/pull/8601) ### Non-protocol Changes -* Config validation can be done by following command: - `./target/debug/neard --home {path_to_config_files} validate-config`. - This will show error if there are file issues or semantic issues in `config.json`, `genesis.json`, `records.json`, `node_key.json` and `validator_key.json`. +* Config validation can be done by following command: + `./target/debug/neard --home {path_to_config_files} validate-config`. + This will show error if there are file issues or semantic issues in `config.json`, `genesis.json`, `records.json`, `node_key.json` and `validator_key.json`. [#8485](https://github.com/near/nearcore/pull/8485) * Comments are allowed in configs. This includes `config.json`, `genesis.json`, `node_key.json` and `validator_key.json`. You can use `//`, `#` and `/*...*/` for comments. [#8423](https://github.com/near/nearcore/pull/8423) -* `/debug` page now has client_config linked. +* `/debug` page now has client_config linked. You can also check your client_config directly at /debug/client_config [#8400](https://github.com/near/nearcore/pull/8400) * Added cold store loop - a background thread that copies data from hot to cold storage and a new json rpc endpoing - split_storage_info - that diff --git a/chain/chain/src/flat_storage_creator.rs b/chain/chain/src/flat_storage_creator.rs index bcebc16464a..0af4a018bbd 100644 --- a/chain/chain/src/flat_storage_creator.rs +++ b/chain/chain/src/flat_storage_creator.rs @@ -14,16 +14,18 @@ use assert_matches::assert_matches; use crossbeam_channel::{unbounded, Receiver, Sender}; use near_chain_primitives::Error; use near_primitives::shard_layout::ShardUId; +use near_primitives::state::ValueRef; use near_primitives::state_part::PartId; use near_primitives::types::{AccountId, BlockHeight, StateRoot}; use near_store::flat::{ - store_helper, BlockInfo, FetchingStateStatus, FlatStateChanges, FlatStateValue, - FlatStorageCreationMetrics, FlatStorageCreationStatus, FlatStorageReadyStatus, - FlatStorageStatus, NUM_PARTS_IN_ONE_STEP, STATE_PART_MEMORY_LIMIT, + store_helper, BlockInfo, FetchingStateStatus, FlatStateChanges, FlatStorageCreationMetrics, + FlatStorageCreationStatus, FlatStorageReadyStatus, FlatStorageStatus, NUM_PARTS_IN_ONE_STEP, + STATE_PART_MEMORY_LIMIT, }; use near_store::Store; use near_store::{Trie, TrieDBStorage, TrieTraversalItem}; use std::collections::HashMap; +use std::rc::Rc; use std::sync::atomic::AtomicU64; use std::sync::Arc; use tracing::{debug, info}; @@ -89,7 +91,7 @@ impl FlatStorageShardCreator { result_sender: Sender, ) { let trie_storage = TrieDBStorage::new(store.clone(), shard_uid); - let trie = Trie::new(Box::new(trie_storage), state_root, None); + let trie = Trie::new(Rc::new(trie_storage), state_root, None); let path_begin = trie.find_state_part_boundary(part_id.idx, part_id.total).unwrap(); let path_end = trie.find_state_part_boundary(part_id.idx + 1, part_id.total).unwrap(); let hex_path_begin = Self::nibbles_to_hex(&path_begin); @@ -103,13 +105,9 @@ impl FlatStorageShardCreator { { if let Some(key) = key { let value = trie.storage.retrieve_raw_bytes(&hash).unwrap(); - store_helper::set_flat_state_value( - &mut store_update, - shard_uid, - key, - Some(FlatStateValue::value_ref(&value)), - ) - .expect("Failed to put value in FlatState"); + let value_ref = ValueRef::new(&value); + store_helper::set_ref(&mut store_update, shard_uid, key, Some(value_ref)) + .expect("Failed to put value in FlatState"); num_items += 1; } } @@ -186,7 +184,7 @@ impl FlatStorageShardCreator { let trie_storage = TrieDBStorage::new(store, shard_uid); let state_root = *chain_store.get_chunk_extra(&block_hash, &shard_uid)?.state_root(); - let trie = Trie::new(Box::new(trie_storage), state_root, None); + let trie = Trie::new(Rc::new(trie_storage), state_root, None); let root_node = trie.retrieve_root_node().unwrap(); let num_state_parts = root_node.memory_usage / STATE_PART_MEMORY_LIMIT.as_u64() + 1; diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 4f9addae925..d8c771987b1 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -210,8 +210,8 @@ impl VMLimitConfig { // NOTE: Stack height has to be 16K, otherwise Wasmer produces non-deterministic results. // For experimentation try `test_stack_overflow`. - max_stack_height: 256 * 1024, // 256kiB of stack. - contract_prepare_version: ContractPrepareVersion::V2, + max_stack_height: 16 * 1024, // 16Kib of stack. + contract_prepare_version: ContractPrepareVersion::V1, initial_memory_pages: 2u32.pow(10), // 64Mib of memory. max_memory_pages: 2u32.pow(11), // 128Mib of memory. diff --git a/core/primitives/res/runtime_configs/61.yaml b/core/primitives/res/runtime_configs/61.yaml index c2ab6ded651..6f2943e1ea3 100644 --- a/core/primitives/res/runtime_configs/61.yaml +++ b/core/primitives/res/runtime_configs/61.yaml @@ -1,6 +1,3 @@ -max_stack_height: { old: 16384, new: 262144 } -contract_prepare_version: { old: 1, new: 2 } - # Compute costs to allow for flat storage read-only MVP. # See https://github.com/near/nearcore/issues/8006 wasm_touching_trie_node: { old: 16_101_955_926, new: { gas: 16_101_955_926, compute: 110_000_000_000 } } diff --git a/core/primitives/res/runtime_configs/parameters.snap b/core/primitives/res/runtime_configs/parameters.snap index 097cc69b462..96c5ca440a6 100644 --- a/core/primitives/res/runtime_configs/parameters.snap +++ b/core/primitives/res/runtime_configs/parameters.snap @@ -138,8 +138,8 @@ wasm_alt_bn128_g1_sum_base 3_000_000_000 wasm_alt_bn128_g1_sum_element 5_000_000_000 max_gas_burnt 300_000_000_000_000 max_gas_burnt_view 300_000_000_000_000 -max_stack_height 262_144 -contract_prepare_version 2 +max_stack_height 16_384 +contract_prepare_version 1 initial_memory_pages 1_024 max_memory_pages 2_048 registers_memory_limit 1_073_741_824 diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap index 60a5bcddd39..ef2462605a3 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap @@ -174,8 +174,8 @@ expression: config_view "regular_op_cost": 822756, "limit_config": { "max_gas_burnt": 300000000000000, - "max_stack_height": 262144, - "contract_prepare_version": 2, + "max_stack_height": 16384, + "contract_prepare_version": 1, "initial_memory_pages": 1024, "max_memory_pages": 2048, "registers_memory_limit": 1073741824, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap index 60a5bcddd39..ef2462605a3 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap @@ -174,8 +174,8 @@ expression: config_view "regular_op_cost": 822756, "limit_config": { "max_gas_burnt": 300000000000000, - "max_stack_height": 262144, - "contract_prepare_version": 2, + "max_stack_height": 16384, + "contract_prepare_version": 1, "initial_memory_pages": 1024, "max_memory_pages": 2048, "registers_memory_limit": 1073741824, diff --git a/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap b/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap index 4b2bd548491..620a2104a8c 100644 --- a/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap +++ b/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap @@ -174,8 +174,8 @@ expression: "&view" "regular_op_cost": 3856371, "limit_config": { "max_gas_burnt": 200000000000000, - "max_stack_height": 262144, - "contract_prepare_version": 2, + "max_stack_height": 16384, + "contract_prepare_version": 1, "initial_memory_pages": 1024, "max_memory_pages": 2048, "registers_memory_limit": 1073741824, diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index d877af6c667..7cc9abcc59f 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -89,12 +89,6 @@ pub enum ProtocolFeature { /// Although wasmer2 is faster, we don't change fees with this protocol /// version -- we can safely do that in a separate step. Wasmer2, - /// This feature switch our WASM engine implementation from wasmer 2.* to - /// near-vm, bringing better performance and reliability. - /// - /// Although near-vm is faster, we don't change fees with this protocol - /// version -- we can safely do that in a separate step. - NearVm, SimpleNightshade, LowerDataReceiptAndEcrecoverBaseCost, /// Lowers the cost of wasm instruction due to switch to wasmer2. @@ -250,9 +244,7 @@ impl ProtocolFeature { ProtocolFeature::Ed25519Verify | ProtocolFeature::ZeroBalanceAccount | ProtocolFeature::DelegateAction => 59, - ProtocolFeature::ComputeCosts - | ProtocolFeature::NearVm - | ProtocolFeature::FlatStorageReads => 61, + ProtocolFeature::ComputeCosts | ProtocolFeature::FlatStorageReads => 61, // Nightly features #[cfg(feature = "protocol_feature_fix_staking_threshold")] diff --git a/core/store/src/flat/chunk_view.rs b/core/store/src/flat/chunk_view.rs index d1b523cffb0..4a92e6f190d 100644 --- a/core/store/src/flat/chunk_view.rs +++ b/core/store/src/flat/chunk_view.rs @@ -1,8 +1,9 @@ use near_primitives::hash::CryptoHash; +use near_primitives::state::ValueRef; use crate::Store; -use super::{FlatStateValue, FlatStorage}; +use super::FlatStorage; /// Struct for getting value references from the flat storage, corresponding /// to some block defined in `blocks_to_head`. @@ -38,7 +39,7 @@ impl FlatStorageChunkView { /// they are stored in `DBCol::State`. Also the separation is done so we /// could charge users for the value length before loading the value. // TODO (#7327): consider inlining small values, so we could use only one db access. - pub fn get_value(&self, key: &[u8]) -> Result, crate::StorageError> { - self.flat_storage.get_value(&self.block_hash, key) + pub fn get_ref(&self, key: &[u8]) -> Result, crate::StorageError> { + self.flat_storage.get_ref(&self.block_hash, key) } } diff --git a/core/store/src/flat/delta.rs b/core/store/src/flat/delta.rs index b2099446a01..fe8e03180af 100644 --- a/core/store/src/flat/delta.rs +++ b/core/store/src/flat/delta.rs @@ -7,8 +7,7 @@ use near_primitives::types::RawStateChangesWithTrieKey; use std::collections::HashMap; use std::sync::Arc; -use super::types::INLINE_DISK_VALUE_THRESHOLD; -use super::{store_helper, BlockInfo, FlatStateValue}; +use super::{store_helper, BlockInfo}; use crate::{CryptoHash, StoreUpdate}; #[derive(Debug)] @@ -35,14 +34,14 @@ impl KeyForFlatStateDelta { res } } -/// Delta of the state for some shard and block, stores mapping from keys to values -/// or None, if key was removed in this block. +/// Delta of the state for some shard and block, stores mapping from keys to value refs or None, if key was removed in +/// this block. #[derive(BorshSerialize, BorshDeserialize, Clone, Default, PartialEq, Eq)] -pub struct FlatStateChanges(pub(crate) HashMap, Option>); +pub struct FlatStateChanges(pub(crate) HashMap, Option>); impl From for FlatStateChanges where - T: IntoIterator, Option)>, + T: IntoIterator, Option)>, { fn from(iter: T) -> Self { Self(HashMap::from_iter(iter)) @@ -58,17 +57,13 @@ impl std::fmt::Debug for FlatStateChanges { } impl FlatStateChanges { - /// Returns `Some(Option)` from delta for the given key. If key is not present, returns None. - pub fn get(&self, key: &[u8]) -> Option> { + /// Returns `Some(Option)` from delta for the given key. If key is not present, returns None. + pub fn get(&self, key: &[u8]) -> Option> { self.0.get(key).cloned() } /// Inserts a key-value pair to delta. - pub fn insert( - &mut self, - key: Vec, - value: Option, - ) -> Option> { + pub fn insert(&mut self, key: Vec, value: Option) -> Option> { self.0.insert(key, value) } @@ -93,14 +88,12 @@ impl FlatStateChanges { .last() .expect("Committed entry should have at least one change") .data; - let flat_state_value = last_change.as_ref().map(|value| { - if value.len() <= INLINE_DISK_VALUE_THRESHOLD { - FlatStateValue::inlined(value) - } else { - FlatStateValue::value_ref(value) + match last_change { + Some(value) => { + delta.insert(key, Some(near_primitives::state::ValueRef::new(value))) } - }); - delta.insert(key, flat_state_value); + None => delta.insert(key, None), + }; } Self(delta) } @@ -108,8 +101,7 @@ impl FlatStateChanges { /// Applies delta to the flat state. pub fn apply_to_flat_state(self, store_update: &mut StoreUpdate, shard_uid: ShardUId) { for (key, value) in self.0.into_iter() { - store_helper::set_flat_state_value(store_update, shard_uid, key, value) - .expect("Borsh cannot fail"); + store_helper::set_ref(store_update, shard_uid, key, value).expect("Borsh cannot fail"); } } } @@ -125,13 +117,7 @@ pub struct CachedFlatStateDelta { impl From for CachedFlatStateChanges { fn from(delta: FlatStateChanges) -> Self { - Self( - delta - .0 - .into_iter() - .map(|(key, value)| (hash(&key), value.map(|v| v.to_value_ref()))) - .collect(), - ) + Self(delta.0.into_iter().map(|(key, value)| (hash(&key), value)).collect()) } } @@ -158,9 +144,8 @@ impl CachedFlatStateChanges { #[cfg(test)] mod tests { - use crate::flat::FlatStateValue; - use super::FlatStateChanges; + use near_primitives::state::ValueRef; use near_primitives::trie_key::TrieKey; use near_primitives::types::{RawStateChange, RawStateChangesWithTrieKey, StateChangeCause}; @@ -223,17 +208,17 @@ mod tests { let flat_state_changes = FlatStateChanges::from_state_changes(&state_changes); assert_eq!( flat_state_changes.get(&alice_trie_key.to_vec()), - Some(Some(FlatStateValue::inlined(&[3, 4]))) + Some(Some(ValueRef::new(&[3, 4]))) ); assert_eq!(flat_state_changes.get(&bob_trie_key.to_vec()), Some(None)); assert_eq!(flat_state_changes.get(&carol_trie_key.to_vec()), None); assert_eq!( flat_state_changes.get(&delayed_trie_key.to_vec()), - Some(Some(FlatStateValue::inlined(&[1]))) + Some(Some(ValueRef::new(&[1]))) ); assert_eq!( flat_state_changes.get(&delayed_receipt_trie_key.to_vec()), - Some(Some(FlatStateValue::inlined(&[2]))) + Some(Some(ValueRef::new(&[2]))) ); } @@ -242,23 +227,23 @@ mod tests { #[test] fn flat_state_changes_merge() { let mut changes = FlatStateChanges::from([ - (vec![1], Some(FlatStateValue::value_ref(&[4]))), - (vec![2], Some(FlatStateValue::value_ref(&[5]))), + (vec![1], Some(ValueRef::new(&[4]))), + (vec![2], Some(ValueRef::new(&[5]))), (vec![3], None), - (vec![4], Some(FlatStateValue::value_ref(&[6]))), + (vec![4], Some(ValueRef::new(&[6]))), ]); let changes_new = FlatStateChanges::from([ - (vec![2], Some(FlatStateValue::value_ref(&[7]))), - (vec![3], Some(FlatStateValue::value_ref(&[8]))), + (vec![2], Some(ValueRef::new(&[7]))), + (vec![3], Some(ValueRef::new(&[8]))), (vec![4], None), - (vec![5], Some(FlatStateValue::value_ref(&[9]))), + (vec![5], Some(ValueRef::new(&[9]))), ]); changes.merge(changes_new); - assert_eq!(changes.get(&[1]), Some(Some(FlatStateValue::value_ref(&[4])))); - assert_eq!(changes.get(&[2]), Some(Some(FlatStateValue::value_ref(&[7])))); - assert_eq!(changes.get(&[3]), Some(Some(FlatStateValue::value_ref(&[8])))); + assert_eq!(changes.get(&[1]), Some(Some(ValueRef::new(&[4])))); + assert_eq!(changes.get(&[2]), Some(Some(ValueRef::new(&[7])))); + assert_eq!(changes.get(&[3]), Some(Some(ValueRef::new(&[8])))); assert_eq!(changes.get(&[4]), Some(None)); - assert_eq!(changes.get(&[5]), Some(Some(FlatStateValue::value_ref(&[9])))); + assert_eq!(changes.get(&[5]), Some(Some(ValueRef::new(&[9])))); } } diff --git a/core/store/src/flat/mod.rs b/core/store/src/flat/mod.rs index 0eb0564c36d..328df2db5e4 100644 --- a/core/store/src/flat/mod.rs +++ b/core/store/src/flat/mod.rs @@ -39,7 +39,7 @@ pub use manager::FlatStorageManager; pub use metrics::FlatStorageCreationMetrics; pub use storage::FlatStorage; pub use types::{ - BlockInfo, FetchingStateStatus, FlatStateValue, FlatStorageCreationStatus, FlatStorageError, + BlockInfo, FetchingStateStatus, FlatStorageCreationStatus, FlatStorageError, FlatStorageReadyStatus, FlatStorageStatus, }; diff --git a/core/store/src/flat/storage.rs b/core/store/src/flat/storage.rs index 065821988d6..eb3d132a2a3 100644 --- a/core/store/src/flat/storage.rs +++ b/core/store/src/flat/storage.rs @@ -4,6 +4,7 @@ use std::sync::{Arc, RwLock}; use near_primitives::errors::StorageError; use near_primitives::hash::CryptoHash; use near_primitives::shard_layout::{ShardLayout, ShardUId}; +use near_primitives::state::ValueRef; use tracing::{debug, info, warn}; use crate::flat::delta::CachedFlatStateChanges; @@ -13,7 +14,7 @@ use crate::{Store, StoreUpdate}; use super::delta::{CachedFlatStateDelta, FlatStateDelta}; use super::metrics::FlatStorageMetrics; -use super::types::{FlatStateValue, FlatStorageError}; +use super::types::FlatStorageError; use super::{store_helper, BlockInfo}; /// FlatStorage stores information on which blocks flat storage current supports key lookups on. @@ -176,11 +177,11 @@ impl FlatStorage { guard.get_blocks_to_head(target_block_hash) } - pub fn get_value( + pub fn get_ref( &self, block_hash: &CryptoHash, key: &[u8], - ) -> Result, crate::StorageError> { + ) -> Result, crate::StorageError> { let guard = self.0.read().expect(super::POISONED_LOCK_ERR); let blocks_to_head = guard.get_blocks_to_head(block_hash).map_err(|e| StorageError::from(e))?; @@ -189,14 +190,14 @@ impl FlatStorage { let changes = guard.get_block_changes(block_hash)?; match changes.get(key) { Some(value_ref) => { - return Ok(value_ref.map(|value_ref| FlatStateValue::Ref(value_ref))); + return Ok(value_ref); } None => {} }; } - let value = store_helper::get_flat_state_value(&guard.store, guard.shard_uid, key)?; - Ok(value) + let value_ref = store_helper::get_ref(&guard.store, guard.shard_uid, key)?; + Ok(value_ref) } /// Update the head of the flat storage, including updating the flat state in memory and on disk @@ -330,12 +331,13 @@ mod tests { use crate::flat::delta::{FlatStateChanges, FlatStateDelta, FlatStateDeltaMetadata}; use crate::flat::manager::FlatStorageManager; use crate::flat::storage::FlatStorage; - use crate::flat::types::{BlockInfo, FlatStateValue, FlatStorageError}; + use crate::flat::types::{BlockInfo, FlatStorageError}; use crate::flat::{store_helper, FlatStorageReadyStatus, FlatStorageStatus}; use crate::test_utils::create_test_store; use crate::StorageError; use borsh::BorshSerialize; use near_primitives::hash::{hash, CryptoHash}; + use near_primitives::state::ValueRef; use near_primitives::types::BlockHeight; use assert_matches::assert_matches; @@ -549,19 +551,11 @@ mod tests { shard_uid, FlatStorageStatus::Ready(FlatStorageReadyStatus { flat_head: chain.get_block(0) }), ); - store_helper::set_flat_state_value( - &mut store_update, - shard_uid, - vec![1], - Some(FlatStateValue::value_ref(&[0])), - ) - .unwrap(); + store_helper::set_ref(&mut store_update, shard_uid, vec![1], Some(ValueRef::new(&[0]))) + .unwrap(); for i in 1..10 { let delta = FlatStateDelta { - changes: FlatStateChanges::from([( - vec![1], - Some(FlatStateValue::value_ref(&[i as u8])), - )]), + changes: FlatStateChanges::from([(vec![1], Some(ValueRef::new(&[i as u8])))]), metadata: FlatStateDeltaMetadata { block: chain.get_block(i) }, }; store_helper::set_delta(&mut store_update, shard_uid, &delta).unwrap(); @@ -580,10 +574,7 @@ mod tests { assert_eq!(blocks.len(), i as usize); let chunk_view = flat_storage_manager.chunk_view(shard_uid, Some(block_hash), false).unwrap(); - assert_eq!( - chunk_view.get_value(&[1]).unwrap(), - Some(FlatStateValue::value_ref(&[i as u8])) - ); + assert_eq!(chunk_view.get_ref(&[1]).unwrap(), Some(ValueRef::new(&[i as u8]))); } // 3. Create a new block that deletes &[1] and add a new value &[2] @@ -593,7 +584,7 @@ mod tests { .add_delta(FlatStateDelta { changes: FlatStateChanges::from([ (vec![1], None), - (vec![2], Some(FlatStateValue::value_ref(&[1]))), + (vec![2], Some(ValueRef::new(&[1]))), ]), metadata: FlatStateDeltaMetadata { block: chain.get_block_info(&hash) }, }) @@ -610,10 +601,10 @@ mod tests { let chunk_view1 = flat_storage_manager .chunk_view(shard_uid, Some(chain.get_block_hash(4)), false) .unwrap(); - assert_eq!(chunk_view0.get_value(&[1]).unwrap(), None); - assert_eq!(chunk_view0.get_value(&[2]).unwrap(), Some(FlatStateValue::value_ref(&[1]))); - assert_eq!(chunk_view1.get_value(&[1]).unwrap(), Some(FlatStateValue::value_ref(&[4]))); - assert_eq!(chunk_view1.get_value(&[2]).unwrap(), None); + assert_eq!(chunk_view0.get_ref(&[1]).unwrap(), None); + assert_eq!(chunk_view0.get_ref(&[2]).unwrap(), Some(ValueRef::new(&[1]))); + assert_eq!(chunk_view1.get_ref(&[1]).unwrap(), Some(ValueRef::new(&[4]))); + assert_eq!(chunk_view1.get_ref(&[2]).unwrap(), None); assert_matches!( store_helper::get_delta_changes(&store, shard_uid, chain.get_block_hash(5)).unwrap(), Some(_) @@ -627,15 +618,15 @@ mod tests { // and chunk_view1 returns an error. Also check that DBCol::FlatState is updated correctly flat_storage.update_flat_head(&chain.get_block_hash(5)).unwrap(); assert_eq!( - store_helper::get_flat_state_value(&store, shard_uid, &[1]).unwrap(), - Some(FlatStateValue::value_ref(&[5])) + store_helper::get_ref(&store, shard_uid, &[1]).unwrap(), + Some(ValueRef::new(&[5])) ); let blocks = flat_storage.get_blocks_to_head(&chain.get_block_hash(10)).unwrap(); assert_eq!(blocks.len(), 5); - assert_eq!(chunk_view0.get_value(&[1]).unwrap(), None); - assert_eq!(chunk_view0.get_value(&[2]).unwrap(), Some(FlatStateValue::value_ref(&[1]))); + assert_eq!(chunk_view0.get_ref(&[1]).unwrap(), None); + assert_eq!(chunk_view0.get_ref(&[2]).unwrap(), Some(ValueRef::new(&[1]))); assert_matches!( - chunk_view1.get_value(&[1]), + chunk_view1.get_ref(&[1]), Err(StorageError::FlatStorageBlockNotSupported(_)) ); assert_matches!( @@ -652,13 +643,13 @@ mod tests { flat_storage.update_flat_head(&chain.get_block_hash(10)).unwrap(); let blocks = flat_storage.get_blocks_to_head(&chain.get_block_hash(10)).unwrap(); assert_eq!(blocks.len(), 0); - assert_eq!(store_helper::get_flat_state_value(&store, shard_uid, &[1]).unwrap(), None); + assert_eq!(store_helper::get_ref(&store, shard_uid, &[1]).unwrap(), None); assert_eq!( - store_helper::get_flat_state_value(&store, shard_uid, &[2]).unwrap(), - Some(FlatStateValue::value_ref(&[1])) + store_helper::get_ref(&store, shard_uid, &[2]).unwrap(), + Some(ValueRef::new(&[1])) ); - assert_eq!(chunk_view0.get_value(&[1]).unwrap(), None); - assert_eq!(chunk_view0.get_value(&[2]).unwrap(), Some(FlatStateValue::value_ref(&[1]))); + assert_eq!(chunk_view0.get_ref(&[1]).unwrap(), None); + assert_eq!(chunk_view0.get_ref(&[2]).unwrap(), Some(ValueRef::new(&[1]))); assert_matches!( store_helper::get_delta_changes(&store, shard_uid, chain.get_block_hash(10)).unwrap(), None diff --git a/core/store/src/flat/store_helper.rs b/core/store/src/flat/store_helper.rs index bd61d894e4d..e78334dac0e 100644 --- a/core/store/src/flat/store_helper.rs +++ b/core/store/src/flat/store_helper.rs @@ -7,6 +7,7 @@ use crate::{Store, StoreUpdate}; use near_primitives::errors::StorageError; use near_primitives::hash::CryptoHash; use near_primitives::shard_layout::{ShardLayout, ShardUId}; +use near_primitives::state::ValueRef; use super::delta::{FlatStateDelta, FlatStateDeltaMetadata}; use super::types::{FlatStateValue, FlatStorageStatus}; @@ -107,25 +108,27 @@ fn decode_flat_state_db_key(key: &Box<[u8]>) -> Result<(ShardUId, Vec), Stor Ok((shard_uid, trie_key.to_vec())) } -pub(crate) fn get_flat_state_value( +pub(crate) fn get_ref( store: &Store, shard_uid: ShardUId, key: &[u8], -) -> Result, FlatStorageError> { +) -> Result, FlatStorageError> { let db_key = encode_flat_state_db_key(shard_uid, key); store .get_ser(FlatStateColumn::State.to_db_col(), &db_key) .map_err(|_| FlatStorageError::StorageInternalError) + .map(|maybe_value| maybe_value.map(|FlatStateValue::Ref(v)| v)) } // TODO(#8577): make pub(crate) once flat storage creator is moved inside `flat` module. -pub fn set_flat_state_value( +pub fn set_ref( store_update: &mut StoreUpdate, shard_uid: ShardUId, key: Vec, - value: Option, + value_ref: Option, ) -> Result<(), FlatStorageError> { let db_key = encode_flat_state_db_key(shard_uid, &key); + let value = value_ref.map(|v| FlatStateValue::Ref(v)); match value { Some(value) => store_update .set_ser(FlatStateColumn::State.to_db_col(), &db_key, &value) diff --git a/core/store/src/flat/types.rs b/core/store/src/flat/types.rs index ba6b2be1065..a6d9b738210 100644 --- a/core/store/src/flat/types.rs +++ b/core/store/src/flat/types.rs @@ -4,35 +4,10 @@ use near_primitives::hash::CryptoHash; use near_primitives::state::ValueRef; use near_primitives::types::BlockHeight; -/// Defines value size threshold for flat state inlining. -/// It means that values having size greater than the threshold will be stored -/// in FlatState as `FlatStateValue::Ref`, otherwise the whole value will be -/// stored as `FlatStateValue::Inlined`. -/// See the following comment for reasoning behind the threshold value: -/// https://github.com/near/nearcore/issues/8243#issuecomment-1523049994 -pub const INLINE_DISK_VALUE_THRESHOLD: usize = 4000; - #[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)] pub enum FlatStateValue { Ref(ValueRef), - Inlined(Vec), -} - -impl FlatStateValue { - pub fn value_ref(value: &[u8]) -> Self { - Self::Ref(ValueRef::new(value)) - } - - pub fn inlined(value: &[u8]) -> Self { - Self::Inlined(value.to_vec()) - } - - pub fn to_value_ref(&self) -> ValueRef { - match self { - Self::Ref(value_ref) => value_ref.clone(), - Self::Inlined(value) => ValueRef::new(value), - } - } + // TODO(8243): add variant here for the inlined value } #[derive(BorshSerialize, BorshDeserialize, Debug, Copy, Clone, PartialEq, Eq)] diff --git a/core/store/src/trie/mod.rs b/core/store/src/trie/mod.rs index 84463fb1ec6..891a6d7a882 100644 --- a/core/store/src/trie/mod.rs +++ b/core/store/src/trie/mod.rs @@ -23,6 +23,7 @@ pub use raw_node::{Children, RawTrieNode, RawTrieNodeWithSize}; use std::cell::RefCell; use std::collections::HashMap; use std::fmt::Write; +use std::rc::Rc; use std::str; mod config; @@ -312,7 +313,7 @@ impl std::fmt::Debug for TrieNode { } pub struct Trie { - pub storage: Box, + pub storage: Rc, root: StateRoot, pub flat_storage_chunk_view: Option, } @@ -412,7 +413,7 @@ impl Trie { pub const EMPTY_ROOT: StateRoot = StateRoot::new(); pub fn new( - storage: Box, + storage: Rc, root: StateRoot, flat_storage_chunk_view: Option, ) -> Self { @@ -420,14 +421,11 @@ impl Trie { } pub fn recording_reads(&self) -> Self { - let storage = - self.storage.as_caching_storage().expect("Storage should be TrieCachingStorage"); let storage = TrieRecordingStorage { - store: storage.store.clone(), - shard_uid: storage.shard_uid, + storage: Rc::clone(&self.storage), recorded: RefCell::new(Default::default()), }; - Trie { storage: Box::new(storage), root: self.root, flat_storage_chunk_view: None } + Trie { storage: Rc::new(storage), root: self.root, flat_storage_chunk_view: None } } pub fn recorded_storage(&self) -> Option { @@ -441,7 +439,7 @@ impl Trie { pub fn from_recorded_storage(partial_storage: PartialStorage, root: StateRoot) -> Self { let PartialState::Nodes(nodes) = partial_storage.nodes; let recorded_storage = nodes.into_iter().map(|value| (hash(&value), value)).collect(); - let storage = Box::new(TrieMemoryPartialStorage { + let storage = Rc::new(TrieMemoryPartialStorage { recorded_storage, visited_nodes: Default::default(), }); @@ -802,9 +800,7 @@ impl Trie { matches!(mode, KeyLookupMode::FlatStorage) && self.flat_storage_chunk_view.is_some(); if use_flat_storage { - let flat_state_value = - self.flat_storage_chunk_view.as_ref().unwrap().get_value(&key)?; - Ok(flat_state_value.map(|value| value.to_value_ref())) + self.flat_storage_chunk_view.as_ref().unwrap().get_ref(&key) } else { let key_nibbles = NibbleSlice::new(key); self.lookup(key_nibbles) diff --git a/core/store/src/trie/prefetching_trie_storage.rs b/core/store/src/trie/prefetching_trie_storage.rs index 47e16a6f685..f393e23b3ba 100644 --- a/core/store/src/trie/prefetching_trie_storage.rs +++ b/core/store/src/trie/prefetching_trie_storage.rs @@ -12,6 +12,7 @@ use near_primitives::shard_layout::ShardUId; use near_primitives::trie_key::TrieKey; use near_primitives::types::{AccountId, ShardId, StateRoot, TrieNodesCount}; use std::collections::HashMap; +use std::rc::Rc; use std::sync::Arc; use std::thread; @@ -473,7 +474,7 @@ impl PrefetchApi { // the clone only clones a few `Arc`s, so the performance // hit is small. let prefetcher_trie = - Trie::new(Box::new(prefetcher_storage.clone()), trie_root, None); + Trie::new(Rc::new(prefetcher_storage.clone()), trie_root, None); let storage_key = trie_key.to_vec(); metric_prefetch_sent.inc(); if let Ok(_maybe_value) = prefetcher_trie.get(&storage_key) { diff --git a/core/store/src/trie/shard_tries.rs b/core/store/src/trie/shard_tries.rs index 4b74a70d98d..e9f63a4965d 100644 --- a/core/store/src/trie/shard_tries.rs +++ b/core/store/src/trie/shard_tries.rs @@ -13,6 +13,7 @@ use near_primitives::trie_key::TrieKey; use near_primitives::types::{ NumShards, RawStateChange, RawStateChangesWithTrieKey, StateChangeCause, StateRoot, }; +use std::rc::Rc; use std::sync::{Arc, RwLock}; struct ShardTriesInner { @@ -138,7 +139,7 @@ impl ShardTries { .clone() }); - let storage = Box::new(TrieCachingStorage::new( + let storage = Rc::new(TrieCachingStorage::new( self.0.store.clone(), cache, shard_uid, diff --git a/core/store/src/trie/state_parts.rs b/core/store/src/trie/state_parts.rs index 25c0f5cd18c..41295a17b2a 100644 --- a/core/store/src/trie/state_parts.rs +++ b/core/store/src/trie/state_parts.rs @@ -25,7 +25,7 @@ use near_primitives::state_part::PartId; use near_primitives::types::StateRoot; use tracing::error; -use crate::flat::{FlatStateChanges, FlatStateValue}; +use crate::flat::FlatStateChanges; use crate::trie::iterator::TrieTraversalItem; use crate::trie::nibble_slice::NibbleSlice; use crate::trie::{ @@ -258,7 +258,7 @@ impl Trie { map.entry(hash).or_insert_with(|| (value.to_vec(), 0)).1 += 1; if let Some(trie_key) = key { let value_ref = ValueRef::new(&value); - flat_state_delta.insert(trie_key.clone(), Some(FlatStateValue::Ref(value_ref))); + flat_state_delta.insert(trie_key.clone(), Some(value_ref)); if is_contract_code_key(&trie_key) { contract_codes.push(ContractCode::new(value.to_vec(), None)); } diff --git a/core/store/src/trie/trie_storage.rs b/core/store/src/trie/trie_storage.rs index a9607f92d61..fdf1b3129b8 100644 --- a/core/store/src/trie/trie_storage.rs +++ b/core/store/src/trie/trie_storage.rs @@ -14,6 +14,7 @@ use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet, VecDeque}; use std::io::ErrorKind; +use std::rc::Rc; use std::sync::{Arc, Mutex}; pub(crate) struct BoundedQueue { @@ -314,8 +315,7 @@ pub trait TrieStorage { /// Used for obtaining state parts (and challenges in the future). /// TODO (#6316): implement proper nodes counting logic as in TrieCachingStorage pub struct TrieRecordingStorage { - pub(crate) store: Store, - pub(crate) shard_uid: ShardUId, + pub(crate) storage: Rc, pub(crate) recorded: RefCell>>, } @@ -324,18 +324,9 @@ impl TrieStorage for TrieRecordingStorage { if let Some(val) = self.recorded.borrow().get(hash).cloned() { return Ok(val); } - let key = TrieCachingStorage::get_key_from_shard_uid_and_hash(self.shard_uid, hash); - let val = self - .store - .get(DBCol::State, key.as_ref()) - .map_err(|_| StorageError::StorageInternalError)?; - if let Some(val) = val { - let val = Arc::from(val); - self.recorded.borrow_mut().insert(*hash, Arc::clone(&val)); - Ok(val) - } else { - Err(StorageError::StorageInconsistentState("Trie node missing".to_string())) - } + let val = self.storage.retrieve_raw_bytes(hash)?; + self.recorded.borrow_mut().insert(*hash, Arc::clone(&val)); + Ok(val) } fn as_recording_storage(&self) -> Option<&TrieRecordingStorage> { diff --git a/core/store/src/trie/trie_tests.rs b/core/store/src/trie/trie_tests.rs index c6fed186efa..6de9f87d49f 100644 --- a/core/store/src/trie/trie_tests.rs +++ b/core/store/src/trie/trie_tests.rs @@ -79,7 +79,7 @@ where for i in 0..(size + 1) { let storage = IncompletePartialStorage::new(storage.clone(), i); let new_trie = Trie { - storage: Box::new(storage), + storage: Rc::new(storage), root: *trie.get_root(), flat_storage_chunk_view: None, }; diff --git a/integration-tests/src/tests/client/features/wasmer2.rs b/integration-tests/src/tests/client/features/wasmer2.rs index 80b868f37a2..7359612f935 100644 --- a/integration-tests/src/tests/client/features/wasmer2.rs +++ b/integration-tests/src/tests/client/features/wasmer2.rs @@ -11,13 +11,12 @@ use nearcore::config::GenesisExt; // This test fails on aarch because wasmer0 and wasmer2 are not available. #[cfg_attr(all(target_arch = "aarch64", target_vendor = "apple"), ignore)] #[test] -fn test_near_vm_upgrade() { +fn test_wasmer2_upgrade() { let mut capture = near_o11y::testonly::TracingCapture::enable(); let old_protocol_version = - near_primitives::version::ProtocolFeature::NearVm.protocol_version() - 1; + near_primitives::version::ProtocolFeature::Wasmer2.protocol_version() - 1; let new_protocol_version = old_protocol_version + 1; - eprintln!("Testing protocol upgrade between {old_protocol_version} and {new_protocol_version}"); // Prepare TestEnv with a contract at the old protocol version. let mut env = { @@ -89,10 +88,6 @@ fn test_near_vm_upgrade() { capture.drain() }; - assert!(logs_at_old_version.iter().any(|l| l.contains(&"vm_kind=Wasmer2"))); - assert!( - logs_at_new_version.iter().any(|l| l.contains(&"vm_kind=NearVm")), - "Expected to find 'vm_kind=NearVm' in logs, occurences of vm_kind are {:?}", - logs_at_new_version.iter().filter(|l| l.contains("vm_kind")).collect::>(), - ); + assert!(logs_at_old_version.iter().any(|l| l.contains(&"vm_kind=Wasmer0"))); + assert!(logs_at_new_version.iter().any(|l| l.contains(&"vm_kind=Wasmer2"))); } diff --git a/integration-tests/src/tests/client/flat_storage.rs b/integration-tests/src/tests/client/flat_storage.rs index fd11332405e..401f4308ecf 100644 --- a/integration-tests/src/tests/client/flat_storage.rs +++ b/integration-tests/src/tests/client/flat_storage.rs @@ -333,8 +333,7 @@ fn test_flat_storage_creation_start_from_state_part() { }; let mut store_update = store.store_update(); for key in trie_keys[1].iter() { - store_helper::set_flat_state_value(&mut store_update, shard_uid, key.clone(), None) - .unwrap(); + store_helper::set_ref(&mut store_update, shard_uid, key.clone(), None).unwrap(); } store_helper::set_flat_storage_status( &mut store_update, @@ -369,7 +368,7 @@ fn test_flat_storage_creation_start_from_state_part() { let chunk_view = trie.flat_storage_chunk_view.unwrap(); for part_trie_keys in trie_keys.iter() { for trie_key in part_trie_keys.iter() { - assert_matches!(chunk_view.get_value(trie_key), Ok(Some(_))); + assert_matches!(chunk_view.get_ref(trie_key), Ok(Some(_))); } } } diff --git a/integration-tests/src/tests/client/process_blocks.rs b/integration-tests/src/tests/client/process_blocks.rs index 4611b92ac00..9f8c46e15eb 100644 --- a/integration-tests/src/tests/client/process_blocks.rs +++ b/integration-tests/src/tests/client/process_blocks.rs @@ -2872,11 +2872,11 @@ fn test_execution_metadata() { "cost": "CONTRACT_LOADING_BYTES", "gas_used": "18423750" }, - // We spend two wasm instructions (call & drop), plus 8 ops for initializing the stack. + // We spend two wasm instructions (call & drop). { "cost_category": "WASM_HOST_COST", "cost": "WASM_INSTRUCTION", - "gas_used": (config.wasm_config.regular_op_cost as u64 * 10).to_string() + "gas_used": (config.wasm_config.regular_op_cost as u64 * 2).to_string() } ]); let outcome = &execution_outcome.receipts_outcome[0].outcome; diff --git a/integration-tests/src/tests/client/sharding_upgrade.rs b/integration-tests/src/tests/client/sharding_upgrade.rs index 449fb0bc47b..f4b2d1e5748 100644 --- a/integration-tests/src/tests/client/sharding_upgrade.rs +++ b/integration-tests/src/tests/client/sharding_upgrade.rs @@ -30,7 +30,7 @@ use tracing::debug; use assert_matches::assert_matches; use near_chain::test_utils::wait_for_all_blocks_in_processing; -use rand::seq::SliceRandom; +use rand::seq::{IteratorRandom, SliceRandom}; use rand::{thread_rng, Rng}; use std::collections::{HashMap, HashSet}; use std::sync::Arc; @@ -613,12 +613,14 @@ fn setup_test_env_with_cross_contract_txs( let mut rng = thread_rng(); let genesis_hash = *test_env.env.clients[0].chain.genesis_block().hash(); - // use test0, test1 and two random accounts to deploy contracts because we want accounts on different shards + // Use test0, test1 and two random accounts to deploy contracts because we want accounts on + // different shards. + let indices = (4..test_env.initial_accounts.len()).choose_multiple(&mut rng, 2); let contract_accounts = vec![ test_env.initial_accounts[0].clone(), test_env.initial_accounts[1].clone(), - test_env.initial_accounts[rng.gen_range(0..test_env.initial_accounts.len())].clone(), - test_env.initial_accounts[rng.gen_range(0..test_env.initial_accounts.len())].clone(), + test_env.initial_accounts[indices[0]].clone(), + test_env.initial_accounts[indices[1]].clone(), ]; test_env.set_init_tx( contract_accounts diff --git a/integration-tests/src/tests/runtime/sanity_checks.rs b/integration-tests/src/tests/runtime/sanity_checks.rs index 71427d0b6fb..dc8e2f47e3c 100644 --- a/integration-tests/src/tests/runtime/sanity_checks.rs +++ b/integration-tests/src/tests/runtime/sanity_checks.rs @@ -232,19 +232,22 @@ fn test_sanity_used_gas() { .collect::>(); // Executing `used_gas` costs `base_cost`. When executing `used_gas` twice - // within a metered block, the returned values should differ by that amount - // plus 2 regular_op_cost, one for the local.set and one for the call. + // within a metered block, the returned values should differ by that amount. let base_cost = node.client.read().unwrap().runtime_config.wasm_config.ext_costs.gas_cost(ExtCosts::base); - let regular_op_cost = - u64::from(node.client.read().unwrap().runtime_config.wasm_config.regular_op_cost); - assert_eq!(used_gas[1] - used_gas[0], base_cost + 2 * regular_op_cost); - - // Similarly, we have 7 instructions between the two used_gas calls. - assert_eq!(used_gas[2] - used_gas[1], base_cost + 7 * regular_op_cost); - - // And still the same if there are br_if calls (6 regular ops, as block doesn’t count) - assert_eq!(used_gas[3] - used_gas[2], base_cost + 6 * regular_op_cost); + assert_eq!(used_gas[1] - used_gas[0], base_cost); + + // The fees for executing a metered block's WASM code should be paid before + // any of the call instructions within that block are executed. Hence, even + // after arithmetics, the next call of `used_gas` should still return a + // value that differs only by `base_cost`. + assert_eq!(used_gas[2] - used_gas[1], base_cost); + + // Entering a new metered block, all of its instructions are paid upfront. + // Therefore, the difference across blocks must be larger than `base_cost`, + // given that the block contains other instructions besides the call of + // `used_gas`. + assert!(used_gas[3] - used_gas[2] > base_cost); } /// Returns a contract which calls host function `used_gas` multiple times, both diff --git a/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile.snap b/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile.snap index 8cfca701ac1..c9f7315dd83 100644 --- a/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile.snap +++ b/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile.snap @@ -382,11 +382,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [ @@ -400,11 +395,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [ @@ -418,11 +408,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [], @@ -440,11 +425,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [], @@ -461,11 +441,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [ diff --git a/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nightly.snap b/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nightly.snap index 8cfca701ac1..c9f7315dd83 100644 --- a/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nightly.snap +++ b/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nightly.snap @@ -382,11 +382,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [ @@ -400,11 +395,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [ @@ -418,11 +408,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [], @@ -440,11 +425,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [], @@ -461,11 +441,6 @@ expression: receipts_gas_profile cost: "CONTRACT_LOADING_BYTES", gas_used: 0, }, - CostGasUsed { - cost_category: "WASM_HOST_COST", - cost: "WASM_INSTRUCTION", - gas_used: 0, - }, ], [], [ diff --git a/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nondeterministic.snap b/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nondeterministic.snap index ed45e974852..b9616f30a16 100644 --- a/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nondeterministic.snap +++ b/integration-tests/src/tests/runtime/snapshots/integration_tests__tests__runtime__sanity_checks__receipts_gas_profile_nondeterministic.snap @@ -17,7 +17,7 @@ expression: receipts_gas_profile CostGasUsed { cost_category: "WASM_HOST_COST", cost: "WASM_INSTRUCTION", - gas_used: 8227560, + gas_used: 1645512, }, ], [], diff --git a/pytest/requirements.txt b/pytest/requirements.txt index 770126b0aa4..c5b87763fa1 100644 --- a/pytest/requirements.txt +++ b/pytest/requirements.txt @@ -15,3 +15,4 @@ scipy semver toml tqdm +urllib3<2 diff --git a/pytest/tests/sanity/split_storage.py b/pytest/tests/sanity/split_storage.py index 4488312e542..2532d3e407f 100644 --- a/pytest/tests/sanity/split_storage.py +++ b/pytest/tests/sanity/split_storage.py @@ -172,9 +172,7 @@ def _migrate_to_split_storage(self, rpc, archival, archival_dir, self._configure_hot_storage(archival_dir, rpc_dst) - logger.info("") logger.info("Phase 4 - After migration.") - logger.info("") archival.kill(gentle=True) archival.start() @@ -449,6 +447,8 @@ def test_archival_node_sync(self): logger.info("") # Archival node should be able to sync to split storage without problems. wait_for_blocks(archival, target=n + epoch_length, timeout=120) + archival.kill() + split.kill() if __name__ == "__main__": diff --git a/runtime/near-test-contracts/src/lib.rs b/runtime/near-test-contracts/src/lib.rs index feaa43f5272..70a8275ca27 100644 --- a/runtime/near-test-contracts/src/lib.rs +++ b/runtime/near-test-contracts/src/lib.rs @@ -30,7 +30,7 @@ pub fn sized_contract(size: usize) -> Vec { let adjusted_size = size as i64 - (base_size as i64 - size as i64); let payload = "x".repeat(adjusted_size as usize); let code = format!( - r#"(module + r#"(module (memory 1) (func (export "main")) (data (i32.const 0) "{payload}") diff --git a/runtime/near-test-contracts/test-contract-rs/src/lib.rs b/runtime/near-test-contracts/test-contract-rs/src/lib.rs index b3a1fba14b1..2638be47657 100644 --- a/runtime/near-test-contracts/test-contract-rs/src/lib.rs +++ b/runtime/near-test-contracts/test-contract-rs/src/lib.rs @@ -578,7 +578,6 @@ pub unsafe fn recurse() { /// Rust compiler is getting smarter and starts to optimize my deep recursion. /// We're going to fight it with a more obscure implementations. #[no_mangle] -#[inline(never)] fn internal_recurse(n: u64) -> u64 { if n <= 1 { n diff --git a/runtime/near-vm-runner/src/tests/cache.rs b/runtime/near-vm-runner/src/tests/cache.rs index 8dac268c7e2..d69b12656c6 100644 --- a/runtime/near-vm-runner/src/tests/cache.rs +++ b/runtime/near-vm-runner/src/tests/cache.rs @@ -3,7 +3,6 @@ use super::{create_context, with_vm_variants, LATEST_PROTOCOL_VERSION}; use crate::internal::VMKind; -use crate::near_vm_runner::NearVM; use crate::runner::VMResult; use crate::wasmer2_runner::Wasmer2VM; use crate::{prepare, MockCompiledContractCache}; @@ -13,14 +12,14 @@ use near_primitives::hash::CryptoHash; use near_primitives::runtime::fees::RuntimeFeesConfig; use near_primitives::types::{CompiledContract, CompiledContractCache}; use near_stable_hasher::StableHasher; -use near_vm_compiler::{CpuFeature, Target}; -use near_vm_engine::Executable; use near_vm_errors::VMRunnerError; use near_vm_logic::mocks::mock_external::MockedExternal; use near_vm_logic::VMConfig; use std::hash::{Hash, Hasher}; use std::io; use std::sync::atomic::{AtomicBool, Ordering}; +use wasmer_compiler::{CpuFeature, Target}; +use wasmer_engine::Executable; #[test] fn test_caches_compilation_error() { @@ -106,7 +105,6 @@ fn make_cached_contract_call_vm( #[test] fn test_wasmer2_artifact_output_stability() { - use wasmer_engine::Executable; // If this test has failed, you want to adjust the necessary constants so that `cache::vm_hash` // changes (and only then the hashes here). // @@ -114,23 +112,23 @@ fn test_wasmer2_artifact_output_stability() { // fall through the cracks here, but hopefully it should catch most of the fish just fine. let seeds = [2, 3, 5, 7, 11, 13, 17]; let prepared_hashes = [ - 11313378614122864359, - 5865541421624917606, - 11731917380556063495, - 8000182875575317016, - 3130574445877428311, - 11574598916196339098, - 10719493536745069553, + 12248437801724644735, + 2647244875869025389, + 892153519407678490, + 8592050243596620350, + 2309330154575012917, + 9323529151210819831, + 11488755771702465226, ]; let mut got_prepared_hashes = Vec::with_capacity(seeds.len()); let compiled_hashes = [ - 16241863964906842660, - 9891733092817574479, - 10697830987582926315, - 8841851979868162585, - 10549554738494211661, - 11197084127324548219, - 6788687979647989853, + 3818562753706235018, + 11870140033216711259, + 5923781907461180018, + 13755860129954519309, + 4832119422677650601, + 14075229507958855911, + 8220837142162862198, ]; let mut got_compiled_hashes = Vec::with_capacity(seeds.len()); for seed in seeds { @@ -143,84 +141,11 @@ fn test_wasmer2_artifact_output_stability() { (&contract.code(), &prepared_code).hash(&mut hasher); got_prepared_hashes.push(hasher.finish()); - let mut features = wasmer_compiler::CpuFeature::set(); - features.insert(wasmer_compiler::CpuFeature::AVX); - let triple = "x86_64-unknown-linux-gnu".parse().unwrap(); - let target = wasmer_compiler::Target::new(triple, features); - let vm = Wasmer2VM::new_for_target(config, target); - let artifact = vm.compile_uncached(&contract).unwrap(); - let serialized = artifact.serialize().unwrap(); - let mut hasher = StableHasher::new(); - serialized.hash(&mut hasher); - let this_hash = hasher.finish(); - got_compiled_hashes.push(this_hash); - - std::fs::write(format!("/tmp/artifact{}", this_hash), serialized).unwrap(); - } - // These asserts have failed as a result of some change and the following text describes what - // the implications of the change. - // - // May need a protocol version change, and definitely wants a `WASMER2_CONFIG version update - // too, as below. Maybe something else too. - assert!( - got_prepared_hashes == prepared_hashes, - "contract preparation hashes have changed to {:#?}", - got_prepared_hashes - ); - // In this case you will need to adjust the WASMER2_CONFIG version so that the cached contracts - // are evicted from the contract cache. - assert!( - got_compiled_hashes == compiled_hashes, - "VM output hashes have changed to {:#?}", - got_compiled_hashes - ); - // Once it has been confirmed that these steps have been done, the expected hashes in this test - // can be adjusted. -} - -#[test] -fn test_near_vm_artifact_output_stability() { - // If this test has failed, you want to adjust the necessary constants so that `cache::vm_hash` - // changes (and only then the hashes here). - // - // Note that this test is a best-effort fish net. Some changes that should modify the hash will - // fall through the cracks here, but hopefully it should catch most of the fish just fine. - let seeds = [2, 3, 5, 7, 11, 13, 17]; - let prepared_hashes = [ - 15237011375120738807, - 3750594434467176559, - 2196541628148102482, - 1576495094908614397, - 6394387219699970793, - 18132026143745992229, - 4095228008100475322, - ]; - let mut got_prepared_hashes = Vec::with_capacity(seeds.len()); - let compiled_hashes = [ - 13406898264102036990, - 357008982248812492, - 10171838574337806556, - 8933666767302544249, - 9580084654030896497, - 6856335382562175488, - 17700820009951734912, - ]; - let mut got_compiled_hashes = Vec::with_capacity(seeds.len()); - for seed in seeds { - let contract = ContractCode::new(near_test_contracts::arbitrary_contract(seed), None); - - let config = VMConfig::test(); - let prepared_code = - prepare::prepare_contract(contract.code(), &config, VMKind::NearVm).unwrap(); - let mut hasher = StableHasher::new(); - (&contract.code(), &prepared_code).hash(&mut hasher); - got_prepared_hashes.push(hasher.finish()); - let mut features = CpuFeature::set(); features.insert(CpuFeature::AVX); let triple = "x86_64-unknown-linux-gnu".parse().unwrap(); let target = Target::new(triple, features); - let vm = NearVM::new_for_target(config, target); + let vm = Wasmer2VM::new_for_target(config, target); let artifact = vm.compile_uncached(&contract).unwrap(); let serialized = artifact.serialize().unwrap(); let mut hasher = StableHasher::new(); diff --git a/runtime/near-vm-runner/src/tests/compile_errors.rs b/runtime/near-vm-runner/src/tests/compile_errors.rs index 5ffc6d62766..d2fc217cf18 100644 --- a/runtime/near-vm-runner/src/tests/compile_errors.rs +++ b/runtime/near-vm-runner/src/tests/compile_errors.rs @@ -171,11 +171,11 @@ fn test_limit_contract_functions_number() { VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13048032213 used gas 13048032213 "#]], expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13054614261 used gas 13054614261 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13048032213 used gas 13048032213 "#]], #[cfg(feature = "protocol_feature_fix_contract_loading_cost")] expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13054614261 used gas 13054614261 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13048032213 used gas 13048032213 "#]], ]); @@ -258,7 +258,7 @@ fn test_limit_contract_functions_number() { } #[test] -fn test_limit_locals_bigfunc() { +fn test_limit_locals() { test_builder() .wasm( &near_test_contracts::LargeContract { @@ -293,10 +293,10 @@ fn test_limit_locals_bigfunc() { } .make(), ) - .opaque_error() // near-vm returns a proper stack overflow, others return memory access violation + .skip_wasmtime() .expect(expect![[r#" VMOutcome: balance 4 storage_usage 12 return data None burnt gas 43682463 used gas 43682463 - Err: ... + Err: WebAssembly trap: An `unreachable` opcode was executed. "#]]); } @@ -338,7 +338,7 @@ fn test_limit_locals_global() { .make(), ) .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13001413761 used gas 13001413761 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 139269213 used gas 139269213 "#]]); } @@ -361,7 +361,7 @@ pub fn test_stablized_host_function() { Err: ... "#]], expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 7149592671 used gas 7149592671 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 7143010623 used gas 7143010623 "#]], ]); } diff --git a/runtime/near-vm-runner/src/tests/fuzzers.rs b/runtime/near-vm-runner/src/tests/fuzzers.rs index 8afc5e3f87a..23198c3be06 100644 --- a/runtime/near-vm-runner/src/tests/fuzzers.rs +++ b/runtime/near-vm-runner/src/tests/fuzzers.rs @@ -170,21 +170,7 @@ fn wasmer2_and_wasmtime_agree() { let wasmer2 = run_fuzz(&code, VMKind::Wasmer2).expect("fatal failure"); let wasmtime = run_fuzz(&code, VMKind::Wasmtime).expect("fatal failure"); assert_eq!(wasmer2, wasmtime); - }); -} - -#[test] -fn near_vm_and_wasmtime_agree() { - check!().for_each(|data: &[u8]| { - let module = ArbitraryModule::arbitrary(&mut arbitrary::Unstructured::new(data)); - let module = match module { - Ok(m) => m, - Err(_) => return, - }; - let code = ContractCode::new(module.0.module.to_bytes(), None); - let near_vm = run_fuzz(&code, VMKind::NearVm).expect("fatal failure"); - let wasmtime = run_fuzz(&code, VMKind::Wasmtime).expect("fatal failure"); - assert_eq!(near_vm, wasmtime); + assert_eq!(wasmer2, wasmtime); }); } @@ -216,32 +202,3 @@ fn wasmer2_is_reproducible() { } }) } - -#[cfg(all(feature = "near_vm", target_arch = "x86_64"))] -#[test] -fn near_vm_is_reproducible() { - use crate::near_vm_runner::NearVM; - use near_primitives::hash::CryptoHash; - use near_vm_engine::Executable; - - bolero::check!().for_each(|data: &[u8]| { - if let Ok(module) = ArbitraryModule::arbitrary(&mut arbitrary::Unstructured::new(data)) { - let code = ContractCode::new(module.0.module.to_bytes(), None); - let config = VMConfig::test(); - let mut first_hash = None; - for _ in 0..3 { - let vm = NearVM::new(config.clone()); - let exec = match vm.compile_uncached(&code) { - Ok(e) => e, - Err(_) => return, - }; - let code = exec.serialize().unwrap(); - let hash = CryptoHash::hash_bytes(&code); - match first_hash { - None => first_hash = Some(hash), - Some(h) => assert_eq!(h, hash), - } - } - } - }) -} diff --git a/runtime/near-vm-runner/src/tests/rs_contract.rs b/runtime/near-vm-runner/src/tests/rs_contract.rs index 6332a87b2e4..52a2abf5b11 100644 --- a/runtime/near-vm-runner/src/tests/rs_contract.rs +++ b/runtime/near-vm-runner/src/tests/rs_contract.rs @@ -151,7 +151,7 @@ def_test_ext!(ext_block_timestamp, "ext_block_timestamp", &42u64.to_le_bytes()); def_test_ext!(ext_storage_usage, "ext_storage_usage", &12u64.to_le_bytes()); // Note, the used_gas is not a global used_gas at the beginning of method, but instead a diff // in used_gas for computing fib(30) in a loop -def_test_ext!(ext_used_gas, "ext_used_gas", &[72, 146, 120, 16, 0, 0, 0, 0]); +def_test_ext!(ext_used_gas, "ext_used_gas", &[111, 10, 200, 15, 0, 0, 0, 0]); def_test_ext!( ext_sha256, "ext_sha256", diff --git a/runtime/near-vm-runner/src/tests/runtime_errors.rs b/runtime/near-vm-runner/src/tests/runtime_errors.rs index 0723fbdda1a..11a1157265e 100644 --- a/runtime/near-vm-runner/src/tests/runtime_errors.rs +++ b/runtime/near-vm-runner/src/tests/runtime_errors.rs @@ -1,6 +1,5 @@ use super::test_builder::test_builder; use expect_test::expect; -#[allow(unused_imports)] // used only when specific features are enabled use near_primitives::version::ProtocolFeature; use std::fmt::Write; @@ -12,7 +11,7 @@ static INFINITE_INITIALIZER_CONTRACT: &str = r#" )"#; #[test] -fn test_infinite_initializer_basic() { +fn test_infinite_initializer() { test_builder() .wat(INFINITE_INITIALIZER_CONTRACT) .gas(10u64.pow(10)) @@ -48,7 +47,7 @@ static SIMPLE_CONTRACT: &str = r#"(module (func (export "main")))"#; #[test] fn test_simple_contract() { test_builder().wat(SIMPLE_CONTRACT).expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 49397511 used gas 49397511 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 42815463 used gas 42815463 "#]]); } @@ -134,7 +133,7 @@ fn test_trap_contract() { .wat(r#"(module (func (export "main") (unreachable)) )"#) .skip_wasmtime() .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 50437017 used gas 50437017 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 43854969 used gas 43854969 Err: WebAssembly trap: An `unreachable` opcode was executed. "#]]); } @@ -151,7 +150,7 @@ fn test_trap_initializer() { ) .skip_wasmtime() .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 53905017 used gas 53905017 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 47322969 used gas 47322969 Err: WebAssembly trap: An `unreachable` opcode was executed. "#]]); } @@ -172,7 +171,7 @@ fn test_div_by_zero_contract() { ) .skip_wasmtime() .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 53166279 used gas 53166279 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 47406987 used gas 47406987 Err: WebAssembly trap: An arithmetic exception, e.g. divided by zero. "#]]); } @@ -193,7 +192,7 @@ fn test_float_to_int_contract() { )) .skip_wasmtime() .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 53427273 used gas 53427273 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 47667981 used gas 47667981 Err: WebAssembly trap: An arithmetic exception, e.g. divided by zero. "#]]); } @@ -217,7 +216,7 @@ fn test_indirect_call_to_null_contract() { .opaque_error() .skip_wasmtime() .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 56678523 used gas 56678523 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 50919231 used gas 50919231 Err: ... "#]]) } @@ -243,7 +242,7 @@ fn test_indirect_call_to_wrong_signature_contract() { ) .skip_wasmtime() .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 61663773 used gas 61663773 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 55904481 used gas 55904481 Err: WebAssembly trap: Call indirect incorrect signature trap. "#]]) } @@ -301,7 +300,7 @@ fn test_guest_panic() { )"#, ) .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 322357878 used gas 322357878 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 315775830 used gas 315775830 Err: Smart contract panicked: explicit guest panic "#]]); } @@ -327,10 +326,9 @@ fn test_stack_overflow() { test_builder() .wat(r#"(module (func $f (export "main") (call $f)))"#) .skip_wasmtime() - .opaque_error() // near-vm returns stack overflow, others return invalid memory access .expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 30376143897 used gas 30376143897 - Err: ... + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 13526101017 used gas 13526101017 + Err: WebAssembly trap: An `unreachable` opcode was executed. "#]]); } @@ -351,15 +349,14 @@ fn test_stack_instrumentation_protocol_upgrade() { .method("f1") .protocol_features(&[ProtocolFeature::CorrectStackLimit]) .skip_wasmtime() - .opaque_error() // near-vm returns stack overflow, others return invalid memory access .expects(&[ expect![[r#" VMOutcome: balance 4 storage_usage 12 return data None burnt gas 6789985365 used gas 6789985365 - Err: ... + Err: WebAssembly trap: An `unreachable` opcode was executed. "#]], expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 31767212013 used gas 31767212013 - Err: ... + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 6789985365 used gas 6789985365 + Err: WebAssembly trap: An `unreachable` opcode was executed. "#]], ]); @@ -378,15 +375,14 @@ fn test_stack_instrumentation_protocol_upgrade() { .method("f2") .protocol_features(&[ProtocolFeature::CorrectStackLimit]) .skip_wasmtime() - .opaque_error() // near-vm returns stack overflow, others return invalid memory access .expects(&[ expect![[r#" VMOutcome: balance 4 storage_usage 12 return data None burnt gas 6789985365 used gas 6789985365 - Err: ... + Err: WebAssembly trap: An `unreachable` opcode was executed. "#]], expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 29698803429 used gas 29698803429 - Err: ... + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 2745316869 used gas 2745316869 + Err: WebAssembly trap: An `unreachable` opcode was executed. "#]], ]); } @@ -546,7 +542,7 @@ static EXTERNAL_CALL_CONTRACT: &str = r#" #[test] fn test_external_call_ok() { test_builder().wat(EXTERNAL_CALL_CONTRACT).expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 326865384 used gas 326865384 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 320283336 used gas 320283336 "#]]); } @@ -575,7 +571,7 @@ fn test_external_call_indirect() { ) )"# ).expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 335491140 used gas 335491140 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 328909092 used gas 328909092 "#]]); } @@ -593,31 +589,13 @@ fn test_address_overflow() { )"#; test_builder().wat(code).skip_wasmtime().skip_wasmer0().expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 54294273 used gas 54294273 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 48534981 used gas 48534981 Err: WebAssembly trap: Memory out of bounds trap. "#]]); // wasmer0 incorrectly doesn't catch overflow during address calculation - test_builder().wat(code).only_wasmer0().expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 55117029 used gas 55117029 - "#]]); -} - -/// Load from address that is within bounds, validating that not all loads do overflow -#[test] -fn test_address_valid() { - let code = r#" -(module - (memory 1) - (func (export "main") - i32.const 10 - i64.load32_u offset=10 align=1 - drop - ) -)"#; - - test_builder().wat(code).expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 54250029 used gas 54250029 + test_builder().wat(code).skip_wasmtime().skip_wasmer2().expect(expect![[r#" + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 48534981 used gas 48534981 "#]]); } @@ -645,12 +623,12 @@ fn test_nan_sign() { )"#; test_builder().wat(code).skip_wasmtime().skip_wasmer0().expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 61570815 used gas 61570815 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 54988767 used gas 54988767 "#]]); // wasmer0 doesn't canonicalize NaNs - test_builder().wat(code).only_wasmer0().expect(expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 60748059 used gas 60748059 + test_builder().wat(code).skip_wasmtime().skip_wasmer2().expect(expect![[r#" + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 54988767 used gas 54988767 Err: WebAssembly trap: An arithmetic exception, e.g. divided by zero. "#]]); } @@ -736,10 +714,10 @@ mod fix_contract_loading_cost_protocol_upgrade { .protocol_features(&[ProtocolFeature::FixContractLoadingCost]) .expects(&[ expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 53989035 used gas 53989035 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 47406987 used gas 47406987 "#]], expect![[r#" - VMOutcome: balance 4 storage_usage 12 return data None burnt gas 53989035 used gas 53989035 + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 47406987 used gas 47406987 "#]], ]); } diff --git a/runtime/near-vm-runner/src/vm_kind.rs b/runtime/near-vm-runner/src/vm_kind.rs index b3f3a6da04e..1f6de45b244 100644 --- a/runtime/near-vm-runner/src/vm_kind.rs +++ b/runtime/near-vm-runner/src/vm_kind.rs @@ -25,10 +25,10 @@ impl VMKind { // Only wasmtime supports non-x86_64 systems #[cfg(all( not(target_arch = "x86_64"), - any(feature = "force_wasmer0", feature = "force_wasmer2", feature = "force_near_vm") + any(feature = "force_wasmer0", feature = "force_wasmer2") ))] compile_error!( - "Wasmer and NearVM only support x86_64, but such a force_* feature was passed to near-vm-runner" + "Wasmer only supports x86_64, but a force_wasmer* feature was passed to near-vm-runner" ); if cfg!(feature = "force_wasmer0") { @@ -40,14 +40,9 @@ impl VMKind { if cfg!(feature = "force_wasmer2") { return VMKind::Wasmer2; } - if cfg!(feature = "force_near_vm") { - return VMKind::NearVm; - } if cfg!(target_arch = "x86_64") { - if checked_feature!("stable", NearVm, protocol_version) { - VMKind::NearVm - } else if checked_feature!("stable", Wasmer2, protocol_version) { + if checked_feature!("stable", Wasmer2, protocol_version) { VMKind::Wasmer2 } else { VMKind::Wasmer0 diff --git a/runtime/runtime-params-estimator/src/estimator_context.rs b/runtime/runtime-params-estimator/src/estimator_context.rs index 924c93b4346..9328fa6ffde 100644 --- a/runtime/runtime-params-estimator/src/estimator_context.rs +++ b/runtime/runtime-params-estimator/src/estimator_context.rs @@ -7,13 +7,14 @@ use near_primitives::hash::CryptoHash; use near_primitives::receipt::Receipt; use near_primitives::runtime::config_store::RuntimeConfigStore; use near_primitives::runtime::migration_data::{MigrationData, MigrationFlags}; +use near_primitives::state::ValueRef; use near_primitives::test_utils::MockEpochInfoProvider; use near_primitives::transaction::{ExecutionStatus, SignedTransaction}; use near_primitives::types::{Gas, MerkleHash}; use near_primitives::version::PROTOCOL_VERSION; use near_store::flat::{ - BlockInfo, FlatStateChanges, FlatStateDelta, FlatStateDeltaMetadata, FlatStateValue, - FlatStorage, FlatStorageManager, + BlockInfo, FlatStateChanges, FlatStateDelta, FlatStateDeltaMetadata, FlatStorage, + FlatStorageManager, }; use near_store::{ShardTries, ShardUId, Store, StoreCompiledContractCache, TrieUpdate}; use near_store::{TrieCache, TrieCachingStorage, TrieConfig}; @@ -164,7 +165,7 @@ impl<'c> EstimatorContext<'c> { let random_data = iter::repeat_with(|| { ( crate::utils::random_vec(delta_key_len), - Some(FlatStateValue::value_ref(b"this is never stored or accessed, we only need it to blow up in-memory deltas")), + Some(ValueRef::new(b"this is never stored or accessed, we only need it to blow up in-memory deltas")), ) }) .take(num_changes_per_delta); diff --git a/runtime/runtime-params-estimator/src/main.rs b/runtime/runtime-params-estimator/src/main.rs index 9b695a448cf..cb733e20aec 100644 --- a/runtime/runtime-params-estimator/src/main.rs +++ b/runtime/runtime-params-estimator/src/main.rs @@ -61,7 +61,7 @@ struct CliArgs { #[clap(long, default_value = "time", value_parser(["icount", "time"]))] metric: String, /// Which VM to test. - #[clap(long, value_parser(["wasmer", "wasmer2", "wasmtime", "near-vm"]))] + #[clap(long, value_parser(["wasmer", "wasmer2", "wasmtime"]))] vm_kind: Option, /// Render existing `costs.txt` as `RuntimeConfig`. #[clap(long)] @@ -289,7 +289,6 @@ fn run_estimation(cli_args: CliArgs) -> anyhow::Result> { Some("wasmer") => VMKind::Wasmer0, Some("wasmer2") => VMKind::Wasmer2, Some("wasmtime") => VMKind::Wasmtime, - Some("near-vm") => VMKind::NearVm, None => VMKind::for_protocol_version(PROTOCOL_VERSION), Some(other) => unreachable!("Unknown vm_kind {}", other), }; diff --git a/tools/state-viewer/src/commands.rs b/tools/state-viewer/src/commands.rs index eca136d0a58..c05c954ddd7 100644 --- a/tools/state-viewer/src/commands.rs +++ b/tools/state-viewer/src/commands.rs @@ -35,6 +35,7 @@ use std::collections::HashMap; use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; +use std::rc::Rc; use std::sync::Arc; pub(crate) fn apply_block( @@ -788,7 +789,7 @@ fn get_trie(store: Store, hash: CryptoHash, shard_id: u32, shard_version: u32) - let trie_config: TrieConfig = Default::default(); let shard_cache = TrieCache::new(&trie_config, shard_uid, true); let trie_storage = TrieCachingStorage::new(store, shard_cache, shard_uid, true, None); - Trie::new(Box::new(trie_storage), hash, None) + Trie::new(Rc::new(trie_storage), hash, None) } pub(crate) fn view_trie( @@ -913,7 +914,7 @@ pub(crate) fn contract_accounts( let storage = TrieDBStorage::new(store.clone(), shard_uid); // We don't need flat state to traverse all accounts. let flat_storage_chunk_view = None; - Trie::new(Box::new(storage), state_root, flat_storage_chunk_view) + Trie::new(Rc::new(storage), state_root, flat_storage_chunk_view) }); filter.write_header(&mut std::io::stdout().lock())?;