From e583d433278cc1d985defe39d1d7f4eeca643e39 Mon Sep 17 00:00:00 2001 From: Aleksandr Logunov Date: Fri, 21 Apr 2023 22:16:21 +0400 Subject: [PATCH] feat: stabilize flat storage for reads (#8761) The code is literally removing `protocol_feature_flat_state` and moving feature to stable protocol. We also disable `test_state_sync` as this is part of refactor we can do in Q2. ## Feature to stabilize Here we stabilize Flat Storage for reads, which means that all state reads in the client during block processing will query flat storage instead of Trie. Flat Storage is another index for blockchain state, reducing number of DB accesses for state read from `2 * key.len()` in the worst case to 2. This will trigger background creation of flat storage, using 8 threads and finishing in 15h for RPC node and 2d for archival node. After that all non-contract reads will go through flat storage, for which special "chunk views" will be created. When protocol upgrade happens, contracts reads will go through flat storage as well. Also compute costs will change as Option 3 suggests [here](https://github.com/near/nearcore/issues/8006#issuecomment-1473718509). It is to be merged separately, but we need to ensure that both costs change and flat storage go into next release together. ## Context Find more details in: - Overview: https://near.github.io/nearcore/architecture/storage/flat_storage.html - Approved NEP: https://github.com/near/NEPs/blob/master/neps/nep-0339.md - Tracking issue: https://github.com/near/nearcore/issues/7327 ## Testing and QA * Flat storage structs are covered by unit tests; * Integration tests check that chain behaviour is preserved and costs are changed as expected; * Flat storage spent ~2 months in betanet with assertion that flat and trie `ValueRef`s are the same; * We were running testnet/mainnet nodes for ~2 months with the same assertion. We checked that performance is not degraded, see e.g. https://nearinc.grafana.net/d/Vg9SREA4k/flat-storage-test?orgId=1&var-chain_id=mainnet&var-node_id=logunov-mainnet-fs-1&from=1677804289279&to=1678088806154 checking that even with finality lag of 50 blocks performance is not impacted. Small exception is that we updated data layout several times during development, but we checked that results are unchanged. ## Checklist - [x] Include compute costs after they are merged - #8924 - [x] https://nayduck.near.org/#/run/2916 - [x] Update CHANGELOG.md to include this protocol feature in the `Unreleased` section. --- CHANGELOG.md | 1 + chain/chain/Cargo.toml | 2 - chain/chain/src/chain.rs | 118 +++++++++--------- chain/chain/src/store.rs | 7 +- chain/client/Cargo.toml | 2 - .../jsonrpc-tests/res/genesis_config.json | 2 +- core/primitives/Cargo.toml | 2 - core/primitives/src/version.rs | 17 +-- core/store/Cargo.toml | 2 - core/store/src/columns.rs | 17 +-- core/store/src/config.rs | 1 - core/store/src/flat/manager.rs | 9 +- core/store/src/flat/storage.rs | 1 - core/store/src/flat/store_helper.rs | 10 +- core/store/src/lib.rs | 3 - core/store/src/metadata.rs | 3 +- core/store/src/trie/split_state.rs | 6 +- genesis-tools/genesis-populate/Cargo.toml | 4 - genesis-tools/genesis-populate/src/lib.rs | 6 +- integration-tests/Cargo.toml | 2 - .../src/tests/client/features.rs | 1 - .../src/tests/client/flat_storage.rs | 112 +++++------------ ...__sanity_checks__receipts_gas_profile.snap | 2 +- .../src/tests/standard_cases/mod.rs | 12 +- integration-tests/src/user/runtime_user.rs | 4 +- nearcore/Cargo.toml | 2 - nearcore/src/migrations.rs | 3 +- nearcore/src/runtime/mod.rs | 15 +-- neard/Cargo.toml | 2 - runtime/near-vm-logic/Cargo.toml | 3 - runtime/near-vm-logic/src/logic.rs | 15 +-- runtime/runtime-params-estimator/Cargo.toml | 5 - .../src/estimator_context.rs | 13 +- runtime/runtime-params-estimator/src/utils.rs | 24 ++-- runtime/runtime/Cargo.toml | 1 - runtime/runtime/src/genesis.rs | 6 +- tools/flat-storage/Cargo.toml | 7 -- tools/mock-node/Cargo.toml | 1 - tools/state-viewer/Cargo.toml | 1 - tools/state-viewer/src/state_dump.rs | 2 - 40 files changed, 151 insertions(+), 295 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beace74b4a0..12bd7e27474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Contract preparation and gas charging for wasm execution also switched to using our own code, as per the finite-wasm specification. Contract execution gas costs will change slightly for expected use cases. This opens up opportunities for further changing the execution gas costs (eg. with different costs per opcode) to lower contract execution cost long-term. * Compute Costs are implemented and stabilized. Compute usage of the chunk is now limited according to the compute costs. [#8915](https://github.com/near/nearcore/pull/8915), [NEP-455](https://github.com/near/NEPs/blob/master/neps/nep-0455.md). * Write related storage compute costs are increased which means they fill a chunk sooner but gas costs are unaffected. [#8924](https://github.com/near/nearcore/pull/8924) +* Flat Storage for reads, reducing number of DB accesses for state read from `2 * key.len()` in the worst case to 2. [#8761](https://github.com/near/nearcore/pull/8761), [NEP-399](https://github.com/near/NEPs/pull/399) ### Non-protocol Changes diff --git a/chain/chain/Cargo.toml b/chain/chain/Cargo.toml index 96cb2af456e..2f06bcb6154 100644 --- a/chain/chain/Cargo.toml +++ b/chain/chain/Cargo.toml @@ -48,7 +48,6 @@ expensive_tests = [] test_features = [] delay_detector = ["delay-detector/delay_detector"] no_cache = ["near-store/no_cache"] -protocol_feature_flat_state = ["near-store/protocol_feature_flat_state"] protocol_feature_reject_blocks_with_outdated_protocol_version = ["near-primitives/protocol_feature_reject_blocks_with_outdated_protocol_version"] nightly = [ @@ -58,7 +57,6 @@ nightly_protocol = [ "near-store/nightly_protocol", "near-primitives/nightly_protocol", "protocol_feature_reject_blocks_with_outdated_protocol_version", - "protocol_feature_flat_state", ] mock_node = [] sandbox = ["near-primitives/sandbox"] diff --git a/chain/chain/src/chain.rs b/chain/chain/src/chain.rs index 0ef73a29a43..be03c6ac43d 100644 --- a/chain/chain/src/chain.rs +++ b/chain/chain/src/chain.rs @@ -630,14 +630,12 @@ impl Chain { // Set the root block of flat state to be the genesis block. Later, when we // init FlatStorages, we will read the from this column in storage, so it // must be set here. - if cfg!(feature = "protocol_feature_flat_state") { - let tmp_store_update = runtime_adapter.set_flat_storage_for_genesis( - genesis.hash(), - genesis.header().height(), - genesis.header().epoch_id(), - )?; - store_update.merge(tmp_store_update); - } + let tmp_store_update = runtime_adapter.set_flat_storage_for_genesis( + genesis.hash(), + genesis.header().height(), + genesis.header().epoch_id(), + )?; + store_update.merge(tmp_store_update); info!(target: "chain", "Init: saved genesis: #{} {} / {:?}", block_head.height, block_head.last_block_hash, state_roots); @@ -3197,37 +3195,37 @@ impl Chain { // We synced shard state on top of _previous_ block for chunk in shard state header and applied state parts to // flat storage. Now we can set flat head to hash of this block and create flat storage. - // TODO (#7327): ensure that no flat storage work is done for `KeyValueRuntime`. - if cfg!(feature = "protocol_feature_flat_state") { - // If block_hash is equal to default - this means that we're all the way back at genesis. - // So we don't have to add the storage state for shard in such case. - // TODO(8438) - add additional test scenarios for this case. - if *block_hash != CryptoHash::default() { - let block_header = self.get_block_header(block_hash)?; - let epoch_id = block_header.epoch_id(); - let shard_uid = self.runtime_adapter.shard_id_to_uid(shard_id, epoch_id)?; - if !matches!( - self.runtime_adapter.get_flat_storage_status(shard_uid), - FlatStorageStatus::Disabled - ) { - // Flat storage must not exist at this point because leftover keys corrupt its state. - assert!(self.runtime_adapter.get_flat_storage_for_shard(shard_uid).is_none()); + // If block_hash is equal to default - this means that we're all the way back at genesis. + // So we don't have to add the storage state for shard in such case. + // TODO(8438) - add additional test scenarios for this case. + if *block_hash != CryptoHash::default() { + let block_header = self.get_block_header(block_hash)?; + let epoch_id = block_header.epoch_id(); + let shard_uid = self.runtime_adapter.shard_id_to_uid(shard_id, epoch_id)?; + + // Check if flat storage is disabled, which may be the case when runtime is implemented with + // `KeyValueRuntime`. + if !matches!( + self.runtime_adapter.get_flat_storage_status(shard_uid), + FlatStorageStatus::Disabled + ) { + // Flat storage must not exist at this point because leftover keys corrupt its state. + assert!(self.runtime_adapter.get_flat_storage_for_shard(shard_uid).is_none()); - let mut store_update = self.runtime_adapter.store().store_update(); - store_helper::set_flat_storage_status( - &mut store_update, - shard_uid, - FlatStorageStatus::Ready(FlatStorageReadyStatus { - flat_head: near_store::flat::BlockInfo { - hash: *block_hash, - prev_hash: *block_header.prev_hash(), - height: block_header.height(), - }, - }), - ); - store_update.commit()?; - self.runtime_adapter.create_flat_storage_for_shard(shard_uid); - } + let mut store_update = self.runtime_adapter.store().store_update(); + store_helper::set_flat_storage_status( + &mut store_update, + shard_uid, + FlatStorageStatus::Ready(FlatStorageReadyStatus { + flat_head: near_store::flat::BlockInfo { + hash: *block_hash, + prev_hash: *block_header.prev_hash(), + height: block_header.height(), + }, + }), + ); + store_update.commit()?; + self.runtime_adapter.create_flat_storage_for_shard(shard_uid); } } @@ -4942,31 +4940,29 @@ impl<'a> ChainUpdate<'a> { shard_uid: ShardUId, trie_changes: &WrappedTrieChanges, ) -> Result<(), Error> { - if cfg!(feature = "protocol_feature_flat_state") { - let delta = FlatStateDelta { - changes: FlatStateChanges::from_state_changes(&trie_changes.state_changes()), - metadata: FlatStateDeltaMetadata { - block: near_store::flat::BlockInfo { hash: block_hash, height, prev_hash }, - }, - }; + let delta = FlatStateDelta { + changes: FlatStateChanges::from_state_changes(&trie_changes.state_changes()), + metadata: FlatStateDeltaMetadata { + block: near_store::flat::BlockInfo { hash: block_hash, height, prev_hash }, + }, + }; - if let Some(chain_flat_storage) = - self.runtime_adapter.get_flat_storage_for_shard(shard_uid) - { - // If flat storage exists, we add a block to it. - let store_update = - chain_flat_storage.add_delta(delta).map_err(|e| StorageError::from(e))?; - self.chain_store_update.merge(store_update); - } else { - let shard_id = shard_uid.shard_id(); - // Otherwise, save delta to disk so it will be used for flat storage creation later. - info!(target: "chain", %shard_id, "Add delta for flat storage creation"); - let mut store_update = self.chain_store_update.store().store_update(); - store_helper::set_delta(&mut store_update, shard_uid, &delta) - .map_err(|e| StorageError::from(e))?; - self.chain_store_update.merge(store_update); - } + if let Some(chain_flat_storage) = self.runtime_adapter.get_flat_storage_for_shard(shard_uid) + { + // If flat storage exists, we add a block to it. + let store_update = + chain_flat_storage.add_delta(delta).map_err(|e| StorageError::from(e))?; + self.chain_store_update.merge(store_update); + } else { + let shard_id = shard_uid.shard_id(); + // Otherwise, save delta to disk so it will be used for flat storage creation later. + info!(target: "chain", %shard_id, "Add delta for flat storage creation"); + let mut store_update = self.chain_store_update.store().store_update(); + store_helper::set_delta(&mut store_update, shard_uid, &delta) + .map_err(|e| StorageError::from(e))?; + self.chain_store_update.merge(store_update); } + Ok(()) } diff --git a/chain/chain/src/store.rs b/chain/chain/src/store.rs index 2efbe9a6f83..1a993828d76 100644 --- a/chain/chain/src/store.rs +++ b/chain/chain/src/store.rs @@ -2568,11 +2568,8 @@ impl<'a> ChainStoreUpdate<'a> { | DBCol::_TransactionRefCount | DBCol::_TransactionResult | DBCol::StateChangesForSplitStates - | DBCol::CachedContractCode => { - unreachable!(); - } - #[cfg(feature = "protocol_feature_flat_state")] - DBCol::FlatState + | DBCol::CachedContractCode + | DBCol::FlatState | DBCol::FlatStateChanges | DBCol::FlatStateDeltaMetadata | DBCol::FlatStorageStatus => { diff --git a/chain/client/Cargo.toml b/chain/client/Cargo.toml index 7add2bb5916..cfc3eeb9a2e 100644 --- a/chain/client/Cargo.toml +++ b/chain/client/Cargo.toml @@ -68,11 +68,9 @@ delay_detector = [ nightly_protocol = [] nightly = [ "nightly_protocol", - "protocol_feature_flat_state", "near-chain/nightly", ] sandbox = [ "near-client-primitives/sandbox", "near-chain/sandbox", ] -protocol_feature_flat_state = ["near-store/protocol_feature_flat_state", "near-chain/protocol_feature_flat_state"] diff --git a/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json b/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json index f682359642b..02b71a6ce8c 100644 --- a/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json +++ b/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json @@ -69,4 +69,4 @@ ], "use_production_config": false, "records": [] -} \ No newline at end of file +} diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index c10d36f92fb..811019cd7eb 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -49,13 +49,11 @@ dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] protocol_feature_fix_staking_threshold = [] protocol_feature_fix_contract_loading_cost = [] protocol_feature_reject_blocks_with_outdated_protocol_version = [] -protocol_feature_flat_state = [] nightly = [ "nightly_protocol", "protocol_feature_fix_staking_threshold", "protocol_feature_fix_contract_loading_cost", "protocol_feature_reject_blocks_with_outdated_protocol_version", - "protocol_feature_flat_state", ] nightly_protocol = [] diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index a56998a460c..d877af6c667 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -144,12 +144,17 @@ pub enum ProtocolFeature { /// /// Meta Transaction NEP-366: https://github.com/near/NEPs/blob/master/neps/nep-0366.md DelegateAction, - + Ed25519Verify, /// Decouple compute and gas costs of operations to safely limit the compute time it takes to /// process the chunk. /// /// Compute Costs NEP-455: https://github.com/near/NEPs/blob/master/neps/nep-0455.md ComputeCosts, + /// Enable flat storage for reads, reducing number of DB accesses from `2 * key.len()` in + /// the worst case to 2. + /// + /// Flat Storage NEP-399: https://github.com/near/NEPs/blob/master/neps/nep-0399.md + FlatStorageReads, /// In case not all validator seats are occupied our algorithm provide incorrect minimal seat /// price - it reports as alpha * sum_stake instead of alpha * sum_stake / (1 - alpha), where @@ -159,11 +164,8 @@ pub enum ProtocolFeature { /// Charge for contract loading before it happens. #[cfg(feature = "protocol_feature_fix_contract_loading_cost")] FixContractLoadingCost, - Ed25519Verify, #[cfg(feature = "protocol_feature_reject_blocks_with_outdated_protocol_version")] RejectBlocksWithOutdatedProtocolVersions, - #[cfg(feature = "protocol_feature_flat_state")] - FlatStorageReads, } /// Both, outgoing and incoming tcp connections to peers, will be rejected if `peer's` @@ -248,8 +250,9 @@ impl ProtocolFeature { ProtocolFeature::Ed25519Verify | ProtocolFeature::ZeroBalanceAccount | ProtocolFeature::DelegateAction => 59, - ProtocolFeature::ComputeCosts => 61, - ProtocolFeature::NearVm => 61, + ProtocolFeature::ComputeCosts + | ProtocolFeature::NearVm + | ProtocolFeature::FlatStorageReads => 61, // Nightly features #[cfg(feature = "protocol_feature_fix_staking_threshold")] @@ -258,8 +261,6 @@ impl ProtocolFeature { ProtocolFeature::FixContractLoadingCost => 129, #[cfg(feature = "protocol_feature_reject_blocks_with_outdated_protocol_version")] ProtocolFeature::RejectBlocksWithOutdatedProtocolVersions => 132, - #[cfg(feature = "protocol_feature_flat_state")] - ProtocolFeature::FlatStorageReads => 135, } } } diff --git a/core/store/Cargo.toml b/core/store/Cargo.toml index 775e5f589cf..8593bddd639 100644 --- a/core/store/Cargo.toml +++ b/core/store/Cargo.toml @@ -60,11 +60,9 @@ io_trace = [] no_cache = [] single_thread_rocksdb = [] # Deactivate RocksDB IO background threads test_features = [] -protocol_feature_flat_state = ["near-primitives/protocol_feature_flat_state"] serialize_all_state_changes = [] nightly_protocol = [] nightly = [ "nightly_protocol", - "protocol_feature_flat_state", ] diff --git a/core/store/src/columns.rs b/core/store/src/columns.rs index 461e394807e..224898578ee 100644 --- a/core/store/src/columns.rs +++ b/core/store/src/columns.rs @@ -260,22 +260,18 @@ pub enum DBCol { /// Flat state contents. Used to get `ValueRef` by trie key faster than doing a trie lookup. /// - *Rows*: `shard_uid` + trie key (Vec) /// - *Column type*: ValueRef - #[cfg(feature = "protocol_feature_flat_state")] FlatState, /// Changes for flat state delta. Stores how flat state should be updated for the given shard and block. /// - *Rows*: `KeyForFlatStateDelta { shard_uid, block_hash }` /// - *Column type*: `FlatStateChanges` - #[cfg(feature = "protocol_feature_flat_state")] FlatStateChanges, /// Metadata for flat state delta. /// - *Rows*: `KeyForFlatStateDelta { shard_uid, block_hash }` /// - *Column type*: `FlatStateDeltaMetadata` - #[cfg(feature = "protocol_feature_flat_state")] FlatStateDeltaMetadata, /// Flat storage status for the corresponding shard. /// - *Rows*: `shard_uid` /// - *Column type*: `FlatStorageStatus` - #[cfg(feature = "protocol_feature_flat_state")] FlatStorageStatus, } @@ -474,9 +470,8 @@ impl DBCol { | DBCol::_TransactionRefCount | DBCol::_TransactionResult // | DBCol::StateChangesForSplitStates - | DBCol::CachedContractCode => false, - #[cfg(feature = "protocol_feature_flat_state")] - DBCol::FlatState + | DBCol::CachedContractCode + | DBCol::FlatState | DBCol::FlatStateChanges | DBCol::FlatStateDeltaMetadata | DBCol::FlatStorageStatus => false, @@ -543,13 +538,9 @@ impl DBCol { DBCol::HeaderHashesByHeight => &[DBKeyType::BlockHeight], DBCol::StateChangesForSplitStates => &[DBKeyType::BlockHash, DBKeyType::ShardId], DBCol::TransactionResultForBlock => &[DBKeyType::OutcomeId, DBKeyType::BlockHash], - #[cfg(feature = "protocol_feature_flat_state")] DBCol::FlatState => &[DBKeyType::ShardUId, DBKeyType::TrieKey], - #[cfg(feature = "protocol_feature_flat_state")] - DBCol::FlatStateChanges => &[DBKeyType::ShardId, DBKeyType::BlockHash], - #[cfg(feature = "protocol_feature_flat_state")] - DBCol::FlatStateDeltaMetadata => &[DBKeyType::ShardId, DBKeyType::BlockHash], - #[cfg(feature = "protocol_feature_flat_state")] + DBCol::FlatStateChanges => &[DBKeyType::ShardUId, DBKeyType::BlockHash], + DBCol::FlatStateDeltaMetadata => &[DBKeyType::ShardUId, DBKeyType::BlockHash], DBCol::FlatStorageStatus => &[DBKeyType::ShardUId], } } diff --git a/core/store/src/config.rs b/core/store/src/config.rs index e1dc776b4c5..a03f8c58ddb 100644 --- a/core/store/src/config.rs +++ b/core/store/src/config.rs @@ -154,7 +154,6 @@ impl StoreConfig { pub const fn col_cache_size(&self, col: crate::DBCol) -> bytesize::ByteSize { match col { crate::DBCol::State => self.col_state_cache_size, - #[cfg(feature = "protocol_feature_flat_state")] crate::DBCol::FlatState => self.col_state_cache_size, _ => bytesize::ByteSize::mib(32), } diff --git a/core/store/src/flat/manager.rs b/core/store/src/flat/manager.rs index 34ef9a773ca..ec2fcb0b1dd 100644 --- a/core/store/src/flat/manager.rs +++ b/core/store/src/flat/manager.rs @@ -39,10 +39,6 @@ impl FlatStorageManager { } pub fn test(store: Store, shard_uids: &[ShardUId], flat_head: CryptoHash) -> Self { - if !cfg!(feature = "protocol_feature_flat_state") { - return Self::new(store); - } - let mut flat_storages = HashMap::default(); for shard_uid in shard_uids { let mut store_update = store.store_update(); @@ -138,10 +134,7 @@ impl FlatStorageManager { } } - // TODO (#7327): change the function signature to Result when - // we stabilize feature protocol_feature_flat_state. We use option now to return None when - // the feature is not enabled. Ideally, it should return an error because it is problematic - // if the flat storage state does not exist + // TODO (#7327): consider returning Result when we expect flat storage to exist pub fn get_flat_storage_for_shard(&self, shard_uid: ShardUId) -> Option { let flat_storages = self.0.flat_storages.lock().expect(POISONED_LOCK_ERR); flat_storages.get(&shard_uid).cloned() diff --git a/core/store/src/flat/storage.rs b/core/store/src/flat/storage.rs index 9da4f78f840..eb74c5a3512 100644 --- a/core/store/src/flat/storage.rs +++ b/core/store/src/flat/storage.rs @@ -326,7 +326,6 @@ impl FlatStorage { } } -#[cfg(feature = "protocol_feature_flat_state")] #[cfg(test)] mod tests { use crate::flat::delta::{FlatStateChanges, FlatStateDelta, FlatStateDeltaMetadata}; diff --git a/core/store/src/flat/store_helper.rs b/core/store/src/flat/store_helper.rs index 47565b7fff2..e78334dac0e 100644 --- a/core/store/src/flat/store_helper.rs +++ b/core/store/src/flat/store_helper.rs @@ -16,9 +16,9 @@ use super::types::{FlatStateValue, FlatStorageStatus}; pub const FLAT_STATE_HEAD_KEY_PREFIX: &[u8; 4] = b"HEAD"; pub const FLAT_STATE_CREATION_STATUS_KEY_PREFIX: &[u8; 6] = b"STATUS"; -/// This is needed to avoid `#[cfg(feature = "protocol_feature_flat_state")]` +/// This was needed to avoid `#[cfg(feature = "protocol_feature_flat_state")]` /// from `DBCol::FlatState*` cascading all over the code. -/// Should be removed along with protocol_feature_flat_state feature. +/// TODO (#7327): remove. pub enum FlatStateColumn { State, Changes, @@ -28,15 +28,12 @@ pub enum FlatStateColumn { impl FlatStateColumn { pub const fn to_db_col(&self) -> crate::DBCol { - #[cfg(feature = "protocol_feature_flat_state")] match self { FlatStateColumn::State => crate::DBCol::FlatState, FlatStateColumn::Changes => crate::DBCol::FlatStateChanges, FlatStateColumn::DeltaMetadata => crate::DBCol::FlatStateDeltaMetadata, FlatStateColumn::Status => crate::DBCol::FlatStorageStatus, } - #[cfg(not(feature = "protocol_feature_flat_state"))] - panic!("protocol_feature_flat_state feature is not enabled") } } @@ -141,9 +138,6 @@ pub fn set_ref( } pub fn get_flat_storage_status(store: &Store, shard_uid: ShardUId) -> FlatStorageStatus { - if !cfg!(feature = "protocol_feature_flat_state") { - return FlatStorageStatus::Disabled; - } store .get_ser(FlatStateColumn::Status.to_db_col(), &shard_uid.to_bytes()) .expect("Error reading flat head from storage") diff --git a/core/store/src/lib.rs b/core/store/src/lib.rs index d575dc1fc1e..ed08491371d 100644 --- a/core/store/src/lib.rs +++ b/core/store/src/lib.rs @@ -82,10 +82,7 @@ impl FromStr for Temperature { } } -#[cfg(feature = "protocol_feature_flat_state")] const STATE_COLUMNS: [DBCol; 2] = [DBCol::State, DBCol::FlatState]; -#[cfg(not(feature = "protocol_feature_flat_state"))] -const STATE_COLUMNS: [DBCol; 1] = [DBCol::State]; const STATE_FILE_END_MARK: u8 = 255; /// Node’s storage holding chain and all other necessary data. diff --git a/core/store/src/metadata.rs b/core/store/src/metadata.rs index 161cc383d94..af4f57fab78 100644 --- a/core/store/src/metadata.rs +++ b/core/store/src/metadata.rs @@ -2,8 +2,7 @@ pub type DbVersion = u32; /// Current version of the database. -pub const DB_VERSION: DbVersion = - if cfg!(feature = "protocol_feature_flat_state") { 36 } else { 35 }; +pub const DB_VERSION: DbVersion = 36; /// Database version at which point DbKind was introduced. const DB_VERSION_WITH_KIND: DbVersion = 34; diff --git a/core/store/src/trie/split_state.rs b/core/store/src/trie/split_state.rs index 4f0af2f8580..4ec7e849ae4 100644 --- a/core/store/src/trie/split_state.rs +++ b/core/store/src/trie/split_state.rs @@ -198,10 +198,8 @@ impl ShardTries { for (shard_uid, update) in updates { let (_, trie_changes, state_changes) = update.finalize()?; let state_root = self.apply_all(&trie_changes, shard_uid, &mut store_update); - if cfg!(feature = "protocol_feature_flat_state") { - FlatStateChanges::from_state_changes(&state_changes) - .apply_to_flat_state(&mut store_update, shard_uid); - } + FlatStateChanges::from_state_changes(&state_changes) + .apply_to_flat_state(&mut store_update, shard_uid); new_state_roots.insert(shard_uid, state_root); } Ok((store_update, new_state_roots)) diff --git a/genesis-tools/genesis-populate/Cargo.toml b/genesis-tools/genesis-populate/Cargo.toml index 721a2c70b5e..57da41051b5 100644 --- a/genesis-tools/genesis-populate/Cargo.toml +++ b/genesis-tools/genesis-populate/Cargo.toml @@ -20,10 +20,6 @@ near-chain.workspace = true near-test-contracts.workspace = true [features] -protocol_feature_flat_state = [ - "nearcore/protocol_feature_flat_state", -] nightly = [ - "protocol_feature_flat_state", "nearcore/nightly", ] diff --git a/genesis-tools/genesis-populate/src/lib.rs b/genesis-tools/genesis-populate/src/lib.rs index 1ecc49d55e3..3ae0cf3f34a 100644 --- a/genesis-tools/genesis-populate/src/lib.rs +++ b/genesis-tools/genesis-populate/src/lib.rs @@ -181,10 +181,8 @@ impl GenesisBuilder { let shard_uid = ShardUId { version: genesis_shard_version, shard_id: shard_idx as u32 }; let mut store_update = tries.store_update(); let root = tries.apply_all(&trie_changes, shard_uid, &mut store_update); - if cfg!(feature = "protocol_feature_flat_state") { - near_store::flat::FlatStateChanges::from_state_changes(&state_changes) - .apply_to_flat_state(&mut store_update, shard_uid); - } + near_store::flat::FlatStateChanges::from_state_changes(&state_changes) + .apply_to_flat_state(&mut store_update, shard_uid); store_update.commit()?; self.roots.insert(shard_idx, root); diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index ba18788be29..8039ef3763f 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -77,14 +77,12 @@ protocol_feature_reject_blocks_with_outdated_protocol_version = [ "near-primitives/protocol_feature_reject_blocks_with_outdated_protocol_version", "near-chain/protocol_feature_reject_blocks_with_outdated_protocol_version" ] -protocol_feature_flat_state = ["nearcore/protocol_feature_flat_state"] nightly = [ "nightly_protocol", "nearcore/nightly", "protocol_feature_fix_contract_loading_cost", "protocol_feature_reject_blocks_with_outdated_protocol_version", - "protocol_feature_flat_state", ] nightly_protocol = ["nearcore/nightly_protocol"] sandbox = [ diff --git a/integration-tests/src/tests/client/features.rs b/integration-tests/src/tests/client/features.rs index 9750e1a0664..fd7752e3366 100644 --- a/integration-tests/src/tests/client/features.rs +++ b/integration-tests/src/tests/client/features.rs @@ -9,7 +9,6 @@ mod delegate_action; #[cfg(feature = "protocol_feature_fix_contract_loading_cost")] mod fix_contract_loading_cost; mod fix_storage_usage; -#[cfg(feature = "protocol_feature_flat_state")] mod flat_storage; mod increase_deployment_cost; mod increase_storage_compute_cost; diff --git a/integration-tests/src/tests/client/flat_storage.rs b/integration-tests/src/tests/client/flat_storage.rs index dcf02168ab9..537c53e89cc 100644 --- a/integration-tests/src/tests/client/flat_storage.rs +++ b/integration-tests/src/tests/client/flat_storage.rs @@ -129,41 +129,31 @@ fn test_flat_storage_creation_sanity() { env.produce_block(0, height); } - if cfg!(feature = "protocol_feature_flat_state") { - // If chain was initialized from scratch, flat storage state should be created. During block processing, flat - // storage head should be moved to block `START_HEIGHT - 3`. - let flat_head_height = START_HEIGHT - 3; - let expected_flat_storage_head = - env.clients[0].chain.get_block_hash_by_height(flat_head_height).unwrap(); - let status = store_helper::get_flat_storage_status(&store, shard_uid); - if let FlatStorageStatus::Ready(FlatStorageReadyStatus { flat_head }) = status { - assert_eq!(flat_head.hash, expected_flat_storage_head); - assert_eq!(flat_head.height, flat_head_height); - } else { - panic!("expected FlatStorageStatus::Ready status, got {status:?}"); - } - - // Deltas for blocks until `START_HEIGHT - 2` should not exist. - for height in 0..START_HEIGHT - 2 { - let block_hash = env.clients[0].chain.get_block_hash_by_height(height).unwrap(); - assert_eq!( - store_helper::get_delta_changes(&store, shard_uid, block_hash), - Ok(None) - ); - } - // Deltas for blocks until `START_HEIGHT` should still exist, - // because they come after flat storage head. - for height in START_HEIGHT - 2..START_HEIGHT { - let block_hash = env.clients[0].chain.get_block_hash_by_height(height).unwrap(); - assert_matches!( - store_helper::get_delta_changes(&store, shard_uid, block_hash), - Ok(Some(_)) - ); - } + // If chain was initialized from scratch, flat storage state should be created. During block processing, flat + // storage head should be moved to block `START_HEIGHT - 3`. + let flat_head_height = START_HEIGHT - 3; + let expected_flat_storage_head = + env.clients[0].chain.get_block_hash_by_height(flat_head_height).unwrap(); + let status = store_helper::get_flat_storage_status(&store, shard_uid); + if let FlatStorageStatus::Ready(FlatStorageReadyStatus { flat_head }) = status { + assert_eq!(flat_head.hash, expected_flat_storage_head); + assert_eq!(flat_head.height, flat_head_height); } else { + panic!("expected FlatStorageStatus::Ready status, got {status:?}"); + } + + // Deltas for blocks until `START_HEIGHT - 2` should not exist. + for height in 0..START_HEIGHT - 2 { + let block_hash = env.clients[0].chain.get_block_hash_by_height(height).unwrap(); + assert_eq!(store_helper::get_delta_changes(&store, shard_uid, block_hash), Ok(None)); + } + // Deltas for blocks until `START_HEIGHT` should still exist, + // because they come after flat storage head. + for height in START_HEIGHT - 2..START_HEIGHT { + let block_hash = env.clients[0].chain.get_block_hash_by_height(height).unwrap(); assert_matches!( - store_helper::get_flat_storage_status(&store, shard_uid), - FlatStorageStatus::Disabled + store_helper::get_delta_changes(&store, shard_uid, block_hash), + Ok(Some(_)) ); } @@ -184,15 +174,6 @@ fn test_flat_storage_creation_sanity() { } assert!(env.clients[0].runtime_adapter.get_flat_storage_for_shard(shard_uid).is_none()); - if !cfg!(feature = "protocol_feature_flat_state") { - assert_matches!( - store_helper::get_flat_storage_status(&store, shard_uid), - FlatStorageStatus::Disabled - ); - // Stop the test here. - return; - } - assert_eq!(store_helper::get_flat_storage_status(&store, shard_uid), FlatStorageStatus::Empty); assert!(!env.clients[0].run_flat_storage_creation_step().unwrap()); // At first, flat storage state should start saving deltas. Deltas for all newly processed blocks should be saved to @@ -258,17 +239,10 @@ fn test_flat_storage_creation_two_shards() { } for &shard_uid in &shard_uids { - if cfg!(feature = "protocol_feature_flat_state") { - assert_matches!( - store_helper::get_flat_storage_status(&store, shard_uid), - FlatStorageStatus::Ready(_) - ); - } else { - assert_matches!( - store_helper::get_flat_storage_status(&store, shard_uid), - FlatStorageStatus::Disabled - ); - } + assert_matches!( + store_helper::get_flat_storage_status(&store, shard_uid), + FlatStorageStatus::Ready(_) + ); } let block_hash = env.clients[0].chain.get_block_hash_by_height(START_HEIGHT - 1).unwrap(); @@ -280,10 +254,6 @@ fn test_flat_storage_creation_two_shards() { .unwrap(); } - if !cfg!(feature = "protocol_feature_flat_state") { - return; - } - // Check that flat storage is not ready for shard 0 but ready for shard 1. let mut env = setup_env(&genesis, store.clone()); assert!(env.clients[0].runtime_adapter.get_flat_storage_for_shard(shard_uids[0]).is_none()); @@ -321,18 +291,10 @@ fn test_flat_storage_creation_start_from_state_part() { env.produce_block(0, height); } - if cfg!(feature = "protocol_feature_flat_state") { - assert_matches!( - store_helper::get_flat_storage_status(&store, shard_uid), - FlatStorageStatus::Ready(_) - ); - } else { - assert_matches!( - store_helper::get_flat_storage_status(&store, shard_uid), - FlatStorageStatus::Disabled - ); - return; - } + assert_matches!( + store_helper::get_flat_storage_status(&store, shard_uid), + FlatStorageStatus::Ready(_) + ); let block_hash = env.clients[0].chain.get_block_hash_by_height(START_HEIGHT - 1).unwrap(); let state_root = @@ -360,7 +322,7 @@ fn test_flat_storage_creation_start_from_state_part() { assert!(!trie_keys[0].is_empty()); assert!(!trie_keys[1].is_empty()); - if cfg!(feature = "protocol_feature_flat_state") { + { // Remove keys of part 1 from the flat state. // Manually set flat storage creation status to the step when it should start from fetching part 1. let status = store_helper::get_flat_storage_status(&store, shard_uid); @@ -414,9 +376,8 @@ fn test_flat_storage_creation_start_from_state_part() { /// Tests the scenario where we start flat storage migration, and get just a few new blocks. /// (in this test we still generate 3 blocks in order to generate deltas). -#[cfg(feature = "protocol_feature_flat_state")] #[test] -fn test_cachup_succeeds_even_if_no_new_blocks() { +fn test_catchup_succeeds_even_if_no_new_blocks() { init_test_logger(); let genesis = Genesis::test(vec!["test0".parse().unwrap()], 1); let store = create_test_store(); @@ -452,7 +413,6 @@ fn test_cachup_succeeds_even_if_no_new_blocks() { } /// Tests the flat storage iterator. Running on a chain with 3 shards, and couple blocks produced. -#[cfg(feature = "protocol_feature_flat_state")] #[test] fn test_flat_storage_iter() { init_test_logger(); @@ -563,11 +523,7 @@ fn test_not_supported_block() { // But the node must not panic as this is normal behaviour. // Ideally it should be tested on chain level, but there is no easy way to // postpone applying chunks reliably. - if cfg!(feature = "protocol_feature_flat_state") { - assert_matches!(get_ref_results[0], Err(StorageError::FlatStorageBlockNotSupported(_))); - } else { - assert_matches!(get_ref_results[0], Ok(Some(_))); - } + assert_matches!(get_ref_results[0], Err(StorageError::FlatStorageBlockNotSupported(_))); // For the second result chunk view is valid, so result is Ok. assert_matches!(get_ref_results[1], Ok(Some(_))); } 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 b7622e589dc..8cfca701ac1 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 @@ -142,7 +142,7 @@ expression: receipts_gas_profile CostGasUsed { cost_category: "WASM_HOST_COST", cost: "READ_CACHED_TRIE_NODE", - gas_used: 13680000000, + gas_used: 4560000000, }, CostGasUsed { cost_category: "WASM_HOST_COST", diff --git a/integration-tests/src/tests/standard_cases/mod.rs b/integration-tests/src/tests/standard_cases/mod.rs index 77d08b3e21b..d69a918444c 100644 --- a/integration-tests/src/tests/standard_cases/mod.rs +++ b/integration-tests/src/tests/standard_cases/mod.rs @@ -1566,11 +1566,9 @@ pub fn test_storage_read_write_costs(node: impl Node, runtime_config: RuntimeCon ]; check_trie_nodes_count(&node, &runtime_config, receipts.clone(), results, false); - if cfg!(feature = "protocol_feature_flat_state") { - let results = vec![ - TrieNodesCount { db_reads: 0, mem_reads: 0 }, - TrieNodesCount { db_reads: 3, mem_reads: 1 }, - ]; - check_trie_nodes_count(&node, &runtime_config, receipts, results, true); - } + let results = vec![ + TrieNodesCount { db_reads: 0, mem_reads: 0 }, + TrieNodesCount { db_reads: 3, mem_reads: 1 }, + ]; + check_trie_nodes_count(&node, &runtime_config, receipts, results, true); } diff --git a/integration-tests/src/user/runtime_user.rs b/integration-tests/src/user/runtime_user.rs index 3e803d97f84..1d0a4cbbed9 100644 --- a/integration-tests/src/user/runtime_user.rs +++ b/integration-tests/src/user/runtime_user.rs @@ -89,7 +89,7 @@ impl RuntimeUser { let mut txs = transactions; loop { let mut client = self.client.write().expect(POISONED_LOCK_ERR); - let trie = if cfg!(feature = "protocol_feature_flat_state") && use_flat_storage { + let trie = if use_flat_storage { client.tries.get_trie_with_block_hash_for_shard( ShardUId::single_shard(), client.state_root, @@ -132,7 +132,7 @@ impl RuntimeUser { ShardUId::single_shard(), &mut update, ); - if cfg!(feature = "protocol_feature_flat_state") && use_flat_storage { + if use_flat_storage { near_store::flat::FlatStateChanges::from_state_changes(&apply_result.state_changes) .apply_to_flat_state(&mut update, ShardUId::single_shard()); } diff --git a/nearcore/Cargo.toml b/nearcore/Cargo.toml index 1f58c687cfb..01f3531a687 100644 --- a/nearcore/Cargo.toml +++ b/nearcore/Cargo.toml @@ -107,7 +107,6 @@ protocol_feature_fix_staking_threshold = [ protocol_feature_fix_contract_loading_cost = [ "near-vm-runner/protocol_feature_fix_contract_loading_cost", ] -protocol_feature_flat_state = ["near-store/protocol_feature_flat_state", "near-chain/protocol_feature_flat_state", "node-runtime/protocol_feature_flat_state"] serialize_all_state_changes = ["near-store/serialize_all_state_changes"] nightly = [ @@ -119,7 +118,6 @@ nightly = [ "near-rosetta-rpc/nightly", "protocol_feature_fix_staking_threshold", "protocol_feature_fix_contract_loading_cost", - "protocol_feature_flat_state", "serialize_all_state_changes", ] nightly_protocol = [ diff --git a/nearcore/src/migrations.rs b/nearcore/src/migrations.rs index f312ee7df0d..09d29a5d87a 100644 --- a/nearcore/src/migrations.rs +++ b/nearcore/src/migrations.rs @@ -120,10 +120,9 @@ impl<'a> near_store::StoreMigrator for Migrator<'a> { near_store::migrations::migrate_33_to_34(store, self.config.client_config.archive) } 34 => near_store::migrations::migrate_34_to_35(store), - #[cfg(feature = "protocol_feature_flat_state")] 35 => { tracing::info!(target: "migrations", "Migrating DB version from 35 to 36. Flat storage data will be created on disk."); - tracing::info!(target: "migrations", "It will happen in parallel with regular block processing. ETA is 5h for RPC node and 10h for archival node."); + tracing::info!(target: "migrations", "It will happen in parallel with regular block processing. ETA is 15h for RPC node and 2d for archival node."); Ok(()) } DB_VERSION.. => unreachable!(), diff --git a/nearcore/src/runtime/mod.rs b/nearcore/src/runtime/mod.rs index 9f3108d4937..102b7c1f02c 100644 --- a/nearcore/src/runtime/mod.rs +++ b/nearcore/src/runtime/mod.rs @@ -1391,10 +1391,8 @@ impl RuntimeAdapter for NightshadeRuntime { let shard_uid = self.get_shard_uid_from_epoch_id(shard_id, epoch_id)?; let mut store_update = tries.store_update(); tries.apply_all(&trie_changes, shard_uid, &mut store_update); - if cfg!(feature = "protocol_feature_flat_state") { - debug!(target: "chain", %shard_id, "Inserting {} values to flat storage", flat_state_delta.len()); - flat_state_delta.apply_to_flat_state(&mut store_update, shard_uid); - } + debug!(target: "chain", %shard_id, "Inserting {} values to flat storage", flat_state_delta.len()); + flat_state_delta.apply_to_flat_state(&mut store_update, shard_uid); self.precompile_contracts(epoch_id, contract_codes)?; Ok(store_update.commit()?) } @@ -1785,7 +1783,7 @@ mod test { // Create flat storage. Naturally it happens on Chain creation, but here we test only Runtime behaviour // and use a mock chain, so we need to initialize flat storage manually. - if cfg!(feature = "protocol_feature_flat_state") { + { let store_update = runtime .set_flat_storage_for_genesis(&genesis_hash, 0, &EpochId::default()) .unwrap(); @@ -2263,7 +2261,7 @@ mod test { } // TODO (#7327): enable test when flat storage will support state sync. - #[cfg(not(feature = "protocol_feature_flat_state"))] + #[ignore] #[test] fn test_state_sync() { init_test_logger(); @@ -3072,10 +3070,7 @@ mod test { .runtime .get_trie_for_shard(0, &env.head.prev_block_hash, Trie::EMPTY_ROOT, true) .unwrap(); - assert_eq!( - trie.flat_storage_chunk_view.is_some(), - cfg!(feature = "protocol_feature_flat_state") - ); + assert!(trie.flat_storage_chunk_view.is_some()); let trie = env .runtime diff --git a/neard/Cargo.toml b/neard/Cargo.toml index 5d071dc4c7d..f28e6e678ce 100644 --- a/neard/Cargo.toml +++ b/neard/Cargo.toml @@ -67,13 +67,11 @@ rosetta_rpc = ["nearcore/rosetta_rpc"] json_rpc = ["nearcore/json_rpc"] protocol_feature_fix_staking_threshold = ["nearcore/protocol_feature_fix_staking_threshold"] serialize_all_state_changes = ["nearcore/serialize_all_state_changes"] -protocol_feature_flat_state = ["nearcore/protocol_feature_flat_state", "near-flat-storage/protocol_feature_flat_state"] nightly = [ "nightly_protocol", "nearcore/nightly", "near-state-viewer/nightly", - "protocol_feature_flat_state", ] nightly_protocol = ["nearcore/nightly_protocol"] diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 494a57dc2f2..bcfe9e31404 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -43,9 +43,6 @@ default = [] protocol_feature_fix_contract_loading_cost = [ "near-primitives/protocol_feature_fix_contract_loading_cost", ] -protocol_feature_flat_state = [ - "near-primitives/protocol_feature_flat_state" -] io_trace = ["tracing"] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 98c7d439cdd..e8114d67508 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -2498,15 +2498,12 @@ impl<'a> VMLogic<'a> { } self.gas_counter.pay_per(storage_read_key_byte, key.len() as u64)?; let nodes_before = self.ext.get_trie_nodes_count(); - let read_mode = if checked_feature!( - "protocol_feature_flat_state", - FlatStorageReads, - self.current_protocol_version - ) { - StorageGetMode::FlatStorage - } else { - StorageGetMode::Trie - }; + let read_mode = + if checked_feature!("stable", FlatStorageReads, self.current_protocol_version) { + StorageGetMode::FlatStorage + } else { + StorageGetMode::Trie + }; let read = self.ext.storage_get(&key, read_mode); let nodes_delta = self .ext diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index c042b2ae802..5a82b54a6db 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -65,15 +65,10 @@ no_cache = [ wasmtime = ["near-vm-runner/force_wasmtime"] nightly = [ "nightly_protocol", - "protocol_feature_flat_state", ] nightly_protocol = [ "near-primitives/nightly_protocol", "near-test-contracts/nightly", ] -protocol_feature_flat_state = [ - "nearcore/protocol_feature_flat_state", - "genesis-populate/protocol_feature_flat_state" -] sandbox = ["node-runtime/sandbox"] io_trace = ["near-store/io_trace", "near-o11y/io_trace", "near-vm-logic/io_trace"] diff --git a/runtime/runtime-params-estimator/src/estimator_context.rs b/runtime/runtime-params-estimator/src/estimator_context.rs index ed2fcf83295..9328fa6ffde 100644 --- a/runtime/runtime-params-estimator/src/estimator_context.rs +++ b/runtime/runtime-params-estimator/src/estimator_context.rs @@ -77,11 +77,8 @@ impl<'c> EstimatorContext<'c> { let flat_head = CryptoHash::hash_borsh(0usize); let flat_storage_manager = FlatStorageManager::test(store.clone(), &shard_uids, flat_head); - if cfg!(feature = "protocol_feature_flat_state") { - let flat_storage = - flat_storage_manager.get_flat_storage_for_shard(shard_uids[0]).unwrap(); - self.generate_deltas(&flat_storage); - } + let flat_storage = flat_storage_manager.get_flat_storage_for_shard(shard_uids[0]).unwrap(); + self.generate_deltas(&flat_storage); let tries = ShardTries::new(store.clone(), trie_config, &shard_uids, flat_storage_manager); @@ -311,10 +308,8 @@ impl Testbed<'_> { let mut store_update = self.tries.store_update(); let shard_uid = ShardUId::single_shard(); self.root = self.tries.apply_all(&apply_result.trie_changes, shard_uid, &mut store_update); - if cfg!(feature = "protocol_feature_flat_state") { - near_store::flat::FlatStateChanges::from_state_changes(&apply_result.state_changes) - .apply_to_flat_state(&mut store_update, shard_uid); - } + near_store::flat::FlatStateChanges::from_state_changes(&apply_result.state_changes) + .apply_to_flat_state(&mut store_update, shard_uid); store_update.commit().unwrap(); self.apply_state.block_height += 1; diff --git a/runtime/runtime-params-estimator/src/utils.rs b/runtime/runtime-params-estimator/src/utils.rs index 48dc210a826..135d3bd7ba7 100644 --- a/runtime/runtime-params-estimator/src/utils.rs +++ b/runtime/runtime-params-estimator/src/utils.rs @@ -205,21 +205,15 @@ pub(crate) fn fn_cost_with_setup( let (gas_cost, ext_costs) = aggregate_per_block_measurements(block_size, measurements, Some(overhead)); - // flat storage check: we only expect TTN costs for writes - // TODO(#7327): This assertion is ignored, we know flat storage doesn't - // work for the estimator. Remove cfg once it once it works. - #[cfg(ignore)] - if cfg!(feature = "protocol_feature_flat_state") { - let is_write = [ExtCosts::storage_write_base, ExtCosts::storage_remove_base] - .iter() - .any(|cost| *ext_costs.get(cost).unwrap_or(&0) > 0); - if !is_write { - assert_eq!( - 0, - *ext_costs.get(&ExtCosts::touching_trie_node).unwrap_or(&0), - "flat storage not working" - ); - } + let is_write = [ExtCosts::storage_write_base, ExtCosts::storage_remove_base] + .iter() + .any(|cost| *ext_costs.get(cost).unwrap_or(&0) > 0); + if !is_write { + assert_eq!( + 0, + *ext_costs.get(&ExtCosts::touching_trie_node).unwrap_or(&0), + "flat storage not working" + ); } (gas_cost, ext_costs[&ext_cost]) diff --git a/runtime/runtime/Cargo.toml b/runtime/runtime/Cargo.toml index 6306e2933e2..2faa6dde3ce 100644 --- a/runtime/runtime/Cargo.toml +++ b/runtime/runtime/Cargo.toml @@ -33,7 +33,6 @@ near-vm-runner.workspace = true [features] default = [] dump_errors_schema = ["near-vm-errors/dump_errors_schema"] -protocol_feature_flat_state = ["near-store/protocol_feature_flat_state", "near-vm-logic/protocol_feature_flat_state"] nightly_protocol = ["near-primitives/nightly_protocol"] no_cpu_compatibility_checks = ["near-vm-runner/no_cpu_compatibility_checks"] diff --git a/runtime/runtime/src/genesis.rs b/runtime/runtime/src/genesis.rs index 6d5ff23df54..8ed48a1cb0b 100644 --- a/runtime/runtime/src/genesis.rs +++ b/runtime/runtime/src/genesis.rs @@ -143,10 +143,8 @@ impl<'a> AutoFlushingTrieUpdate<'a> { old_state_update.finalize().expect("Genesis state update failed"); let mut store_update = self.tries.store_update(); *state_root = self.tries.apply_all(&trie_changes, self.shard_uid, &mut store_update); - if cfg!(feature = "protocol_feature_flat_state") { - FlatStateChanges::from_state_changes(&state_changes) - .apply_to_flat_state(&mut store_update, self.shard_uid); - } + FlatStateChanges::from_state_changes(&state_changes) + .apply_to_flat_state(&mut store_update, self.shard_uid); store_update.commit().expect("Store update failed on genesis initialization"); *state_update = Some(self.tries.new_trie_update(self.shard_uid, *state_root)); *changes = 0; diff --git a/tools/flat-storage/Cargo.toml b/tools/flat-storage/Cargo.toml index 32bf6084c61..cda97369c76 100644 --- a/tools/flat-storage/Cargo.toml +++ b/tools/flat-storage/Cargo.toml @@ -20,10 +20,3 @@ near-epoch-manager.workspace = true near-primitives.workspace = true near-store.workspace = true nearcore.workspace = true - -[features] -protocol_feature_flat_state = [ - "nearcore/protocol_feature_flat_state", - "near-chain/protocol_feature_flat_state", - "near-store/protocol_feature_flat_state", -] diff --git a/tools/mock-node/Cargo.toml b/tools/mock-node/Cargo.toml index 0b0642d965f..d9eaf20065a 100644 --- a/tools/mock-node/Cargo.toml +++ b/tools/mock-node/Cargo.toml @@ -47,5 +47,4 @@ required-features = ["mock_node"] [features] test_features = ["nearcore/test_features"] -protocol_feature_flat_state = ["nearcore/protocol_feature_flat_state"] mock_node = ["near-chain/mock_node", "near-epoch-manager/mock_node"] diff --git a/tools/state-viewer/Cargo.toml b/tools/state-viewer/Cargo.toml index d294750861a..4c414457ba4 100644 --- a/tools/state-viewer/Cargo.toml +++ b/tools/state-viewer/Cargo.toml @@ -52,4 +52,3 @@ nightly = [ "nearcore/nightly" ] nightly_protocol = ["nearcore/nightly_protocol"] -protocol_feature_flat_state = ["nearcore/protocol_feature_flat_state"] diff --git a/tools/state-viewer/src/state_dump.rs b/tools/state-viewer/src/state_dump.rs index e689077a7bf..fb0f721cd4b 100644 --- a/tools/state-viewer/src/state_dump.rs +++ b/tools/state-viewer/src/state_dump.rs @@ -603,8 +603,6 @@ mod test { validate_genesis(&new_genesis).unwrap(); } - // TODO (#7327): enable test when flat storage will support resharding. - #[cfg(not(feature = "protocol_feature_flat_state"))] #[test] fn test_dump_state_shard_upgrade() { use near_client::test_utils::run_catchup;