diff --git a/crates/simulacrum/src/store/in_mem_store.rs b/crates/simulacrum/src/store/in_mem_store.rs index 6e9de3db8ffb6c..0bc2efc3de946f 100644 --- a/crates/simulacrum/src/store/in_mem_store.rs +++ b/crates/simulacrum/src/store/in_mem_store.rs @@ -269,6 +269,8 @@ impl ChildObjectResolver for InMemoryStore { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, _epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> sui_types::error::SuiResult> { let recv_object = match crate::store::SimulatorStore::get_object(self, receiving_object_id) { diff --git a/crates/sui-core/src/authority.rs b/crates/sui-core/src/authority.rs index 5028fc0e0918c6..92bad50ff3ba5f 100644 --- a/crates/sui-core/src/authority.rs +++ b/crates/sui-core/src/authority.rs @@ -889,6 +889,10 @@ impl AuthorityState { &input_object_kinds, &receiving_objects_refs, epoch_store.epoch(), + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), )?; let (_gas_status, checked_input_objects) = sui_transaction_checks::check_transaction_input( @@ -1556,7 +1560,14 @@ impl AuthorityState { inner_temporary_store, ); self.get_cache_writer() - .write_transaction_outputs(epoch_store.epoch(), transaction_outputs.into()) + .write_transaction_outputs( + epoch_store.epoch(), + transaction_outputs.into(), + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), + ) .await; if certificate.transaction_data().is_end_of_epoch_tx() { @@ -1796,6 +1807,10 @@ impl AuthorityState { &input_object_kinds, &receiving_object_refs, epoch_store.epoch(), + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), )?; // make a gas object if one was not provided @@ -1982,6 +1997,10 @@ impl AuthorityState { &input_object_kinds, &receiving_object_refs, epoch_store.epoch(), + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), )?; // make a gas object if one was not provided @@ -2144,6 +2163,10 @@ impl AuthorityState { &input_object_kinds, &receiving_object_refs, epoch_store.epoch(), + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), )?; // Create and use a dummy gas object if there is no gas object provided. diff --git a/crates/sui-core/src/authority/authority_per_epoch_store.rs b/crates/sui-core/src/authority/authority_per_epoch_store.rs index 0b65711b185bef..0e4923b1d052fa 100644 --- a/crates/sui-core/src/authority/authority_per_epoch_store.rs +++ b/crates/sui-core/src/authority/authority_per_epoch_store.rs @@ -34,7 +34,8 @@ use sui_storage::mutex_table::{MutexGuard, MutexTable}; use sui_types::accumulator::Accumulator; use sui_types::authenticator_state::{get_authenticator_state, ActiveJwk}; use sui_types::base_types::{ - AuthorityName, ConsensusObjectSequenceKey, EpochId, ObjectID, SequenceNumber, TransactionDigest, + AuthorityName, ConsensusObjectSequenceKey, EpochId, FullObjectID, ObjectID, SequenceNumber, + TransactionDigest, }; use sui_types::base_types::{ConciseableName, ObjectRef}; use sui_types::committee::Committee; @@ -1437,7 +1438,7 @@ impl AuthorityPerEpochStore { error: "no assigned shared versions".to_string(), })?; - let initial_shared_version = + let modified_initial_shared_version = if self.epoch_start_config().use_version_assignment_tables_v3() { *initial_shared_version } else { @@ -1447,7 +1448,7 @@ impl AuthorityPerEpochStore { }; // If we found assigned versions, but they are missing the assignment for // this object, it indicates a serious inconsistency! - let Some(version) = assigned_shared_versions.get(&(*id, initial_shared_version)) else { + let Some(version) = assigned_shared_versions.get(&(*id, modified_initial_shared_version)) else { panic!( "Shared object version should have been assigned. key: {key:?}, \ obj id: {id:?}, initial_shared_version: {initial_shared_version:?}, \ @@ -1455,13 +1456,13 @@ impl AuthorityPerEpochStore { ) }; InputKey::VersionedObject { - id: *id, + id: FullObjectID::new(*id, Some(initial_shared_version)), version: *version, } } InputObjectKind::MovePackage(id) => InputKey::Package { id: *id }, InputObjectKind::ImmOrOwnedMoveObject(objref) => InputKey::VersionedObject { - id: objref.0, + id: FullObjectID::new(objref.0, None), version: objref.1, }, }) diff --git a/crates/sui-core/src/authority/authority_store.rs b/crates/sui-core/src/authority/authority_store.rs index 795f238fee2577..638b706b6835ef 100644 --- a/crates/sui-core/src/authority/authority_store.rs +++ b/crates/sui-core/src/authority/authority_store.rs @@ -31,7 +31,8 @@ use sui_types::error::UserInputError; use sui_types::execution::TypeLayoutStore; use sui_types::message_envelope::Message; use sui_types::storage::{ - get_module, BackingPackageStore, MarkerValue, ObjectKey, ObjectOrTombstone, ObjectStore, + get_module, BackingPackageStore, FullObjectKey, MarkerValue, ObjectKey, ObjectOrTombstone, + ObjectStore, }; use sui_types::sui_system_state::get_sui_system_state; use sui_types::{base_types::SequenceNumber, fp_bail, fp_ensure}; @@ -212,9 +213,12 @@ impl AuthorityStore { // We can safely delete all entries in the per epoch marker table since this is only called // at epoch boundaries (during reconfiguration). Therefore any entries that currently // exist can be removed. Because of this we can use the `schedule_delete_all` method. + self.perpetual_tables + .object_per_epoch_marker_table + .schedule_delete_all()?; Ok(self .perpetual_tables - .object_per_epoch_marker_table + .object_per_epoch_marker_table_v2 .schedule_delete_all()?) } @@ -412,40 +416,70 @@ impl AuthorityStore { pub fn get_marker_value( &self, - object_id: &ObjectID, - version: &SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { - let object_key = (epoch_id, ObjectKey(*object_id, *version)); - Ok(self - .perpetual_tables - .object_per_epoch_marker_table - .get(&object_key)?) + if use_object_per_epoch_marker_table_v2 { + Ok(self + .perpetual_tables + .object_per_epoch_marker_table_v2 + .get(&(epoch_id, object_key))?) + } else { + Ok(self + .perpetual_tables + .object_per_epoch_marker_table + .get(&(epoch_id, object_key.into_object_key()))?) + } } pub fn get_latest_marker( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { - let min_key = (epoch_id, ObjectKey::min_for_id(object_id)); - let max_key = (epoch_id, ObjectKey::max_for_id(object_id)); + if use_object_per_epoch_marker_table_v2 { + let min_key = (epoch_id, FullObjectKey::min_for_id(&object_id)); + let max_key = (epoch_id, FullObjectKey::max_for_id(&object_id)); - let marker_entry = self - .perpetual_tables - .object_per_epoch_marker_table - .safe_iter_with_bounds(Some(min_key), Some(max_key)) - .skip_prior_to(&max_key)? - .next(); - match marker_entry { - Some(Ok(((epoch, key), marker))) => { - // because of the iterator bounds these cannot fail - assert_eq!(epoch, epoch_id); - assert_eq!(key.0, *object_id); - Ok(Some((key.1, marker))) + let marker_entry = self + .perpetual_tables + .object_per_epoch_marker_table_v2 + .safe_iter_with_bounds(Some(min_key), Some(max_key)) + .skip_prior_to(&max_key)? + .next(); + match marker_entry { + Some(Ok(((epoch, key), marker))) => { + // because of the iterator bounds these cannot fail + assert_eq!(epoch, epoch_id); + assert_eq!(key.id(), object_id); + Ok(Some((key.version(), marker))) + } + Some(Err(e)) => Err(e.into()), + None => Ok(None), + } + } else { + let min_key = (epoch_id, ObjectKey::min_for_id(&object_id.id())); + let max_key = (epoch_id, ObjectKey::max_for_id(&object_id.id())); + + let marker_entry = self + .perpetual_tables + .object_per_epoch_marker_table + .safe_iter_with_bounds(Some(min_key), Some(max_key)) + .skip_prior_to(&max_key)? + .next(); + match marker_entry { + Some(Ok(((epoch, key), marker))) => { + // because of the iterator bounds these cannot fail + assert_eq!(epoch, epoch_id); + assert_eq!(key.0, object_id.id()); + Ok(Some((key.1, marker))) + } + Some(Err(e)) => Err(e.into()), + None => Ok(None), } - Some(Err(e)) => Err(e.into()), - None => Ok(None), } } @@ -824,6 +858,8 @@ impl AuthorityStore { &self, epoch_id: EpochId, tx_outputs: &[Arc], + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult { let mut written = Vec::with_capacity(tx_outputs.len()); for outputs in tx_outputs { @@ -834,7 +870,12 @@ impl AuthorityStore { let mut write_batch = self.perpetual_tables.transactions.batch(); for outputs in tx_outputs { - self.write_one_transaction_outputs(&mut write_batch, epoch_id, outputs)?; + self.write_one_transaction_outputs( + &mut write_batch, + epoch_id, + outputs, + use_object_per_epoch_marker_table_v2, + )?; } // test crashing before writing the batch fail_point_async!("crash"); @@ -859,6 +900,8 @@ impl AuthorityStore { write_batch: &mut DBBatch, epoch_id: EpochId, tx_outputs: &TransactionOutputs, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult { let TransactionOutputs { transaction, @@ -883,12 +926,21 @@ impl AuthorityStore { // Add batched writes for objects and locks. let effects_digest = effects.digest(); - write_batch.insert_batch( - &self.perpetual_tables.object_per_epoch_marker_table, - markers - .iter() - .map(|(key, marker_value)| ((epoch_id, *key), *marker_value)), - )?; + if use_object_per_epoch_marker_table_v2 { + write_batch.insert_batch( + &self.perpetual_tables.object_per_epoch_marker_table_v2, + markers + .iter() + .map(|(key, marker_value)| ((epoch_id, *key), *marker_value)), + )?; + } else { + write_batch.insert_batch( + &self.perpetual_tables.object_per_epoch_marker_table, + markers + .iter() + .map(|(key, marker_value)| ((epoch_id, key.into_object_key()), *marker_value)), + )?; + } write_batch.insert_batch( &self.perpetual_tables.objects, diff --git a/crates/sui-core/src/authority/authority_store_tables.rs b/crates/sui-core/src/authority/authority_store_tables.rs index 4c5b3f3f28c70b..5bd9f7810bb8d1 100644 --- a/crates/sui-core/src/authority/authority_store_tables.rs +++ b/crates/sui-core/src/authority/authority_store_tables.rs @@ -9,7 +9,7 @@ use sui_types::accumulator::Accumulator; use sui_types::base_types::SequenceNumber; use sui_types::digests::TransactionEventsDigest; use sui_types::effects::TransactionEffects; -use sui_types::storage::MarkerValue; +use sui_types::storage::{FullObjectKey, MarkerValue}; use typed_store::metrics::SamplingInterval; use typed_store::rocks::util::{empty_compaction_filter, reference_count_merge_operator}; use typed_store::rocks::{ @@ -136,6 +136,7 @@ pub struct AuthorityPerpetualTables { /// objects that have been deleted. This table is meant to be pruned per-epoch, and all /// previous epochs other than the current epoch may be pruned safely. pub(crate) object_per_epoch_marker_table: DBMap<(EpochId, ObjectKey), MarkerValue>, + pub(crate) object_per_epoch_marker_table_v2: DBMap<(EpochId, FullObjectKey), MarkerValue>, } impl AuthorityPerpetualTables { @@ -459,6 +460,7 @@ impl AuthorityPerpetualTables { self.expected_network_sui_amount.unsafe_clear()?; self.expected_storage_fund_imbalance.unsafe_clear()?; self.object_per_epoch_marker_table.unsafe_clear()?; + self.object_per_epoch_marker_table_v2.unsafe_clear()?; self.objects.rocksdb.flush()?; Ok(()) } diff --git a/crates/sui-core/src/authority/test_authority_builder.rs b/crates/sui-core/src/authority/test_authority_builder.rs index 256ef7b4980de0..1fbc4baee27eed 100644 --- a/crates/sui-core/src/authority/test_authority_builder.rs +++ b/crates/sui-core/src/authority/test_authority_builder.rs @@ -377,7 +377,14 @@ impl<'a> TestAuthorityBuilder<'a> { state .get_cache_commit() - .commit_transaction_outputs(epoch_store.epoch(), &[*genesis.transaction().digest()]) + .commit_transaction_outputs( + epoch_store.epoch(), + &[*genesis.transaction().digest()], + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), + ) .await; // We want to insert these objects directly instead of relying on genesis because diff --git a/crates/sui-core/src/checkpoints/checkpoint_executor/mod.rs b/crates/sui-core/src/checkpoints/checkpoint_executor/mod.rs index 780e32904bf6d4..1b3acd7f3a4893 100644 --- a/crates/sui-core/src/checkpoints/checkpoint_executor/mod.rs +++ b/crates/sui-core/src/checkpoints/checkpoint_executor/mod.rs @@ -442,7 +442,14 @@ impl CheckpointExecutor { let cache_commit = self.state.get_cache_commit(); debug!(seq = ?checkpoint.sequence_number, "committing checkpoint transactions to disk"); cache_commit - .commit_transaction_outputs(epoch_store.epoch(), all_tx_digests) + .commit_transaction_outputs( + epoch_store.epoch(), + all_tx_digests, + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), + ) .await; epoch_store @@ -657,7 +664,14 @@ impl CheckpointExecutor { let cache_commit = self.state.get_cache_commit(); cache_commit - .commit_transaction_outputs(cur_epoch, &[change_epoch_tx_digest]) + .commit_transaction_outputs( + cur_epoch, + &[change_epoch_tx_digest], + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), + ) .await; fail_point_async!("prune-and-compact"); diff --git a/crates/sui-core/src/execution_cache.rs b/crates/sui-core/src/execution_cache.rs index 1246ab1bd1ea8b..6f94947acb8a2f 100644 --- a/crates/sui-core/src/execution_cache.rs +++ b/crates/sui-core/src/execution_cache.rs @@ -19,14 +19,14 @@ use std::path::Path; use std::sync::Arc; use sui_config::ExecutionCacheConfig; use sui_protocol_config::ProtocolVersion; -use sui_types::base_types::VerifiedExecutionData; +use sui_types::base_types::{FullObjectID, VerifiedExecutionData}; use sui_types::digests::{TransactionDigest, TransactionEffectsDigest, TransactionEventsDigest}; use sui_types::effects::{TransactionEffects, TransactionEvents}; use sui_types::error::{SuiError, SuiResult, UserInputError}; use sui_types::messages_checkpoint::CheckpointSequenceNumber; use sui_types::object::Object; use sui_types::storage::{ - BackingPackageStore, BackingStore, ChildObjectResolver, MarkerValue, ObjectKey, + BackingPackageStore, BackingStore, ChildObjectResolver, FullObjectKey, MarkerValue, ObjectKey, ObjectOrTombstone, ObjectStore, PackageObject, ParentSync, }; use sui_types::sui_system_state::SuiSystemState; @@ -185,6 +185,8 @@ pub trait ExecutionCacheCommit: Send + Sync { &'a self, epoch: EpochId, digests: &'a [TransactionDigest], + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'a, ()>; /// Durably commit transactions (but not their outputs) to the database. @@ -280,6 +282,8 @@ pub trait ObjectCacheRead: Send + Sync { keys: &[InputKey], receiving_objects: HashSet, epoch: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Vec { let (keys_with_version, keys_without_version): (Vec<_>, Vec<_>) = keys .iter() @@ -291,7 +295,7 @@ pub trait ObjectCacheRead: Send + Sync { self.multi_object_exists_by_key( &keys_with_version .iter() - .map(|(_, k)| ObjectKey(k.id(), k.version().unwrap())) + .map(|(_, k)| ObjectKey(k.id().id(), k.version().unwrap())) .collect::>(), ) .into_iter(), @@ -303,6 +307,8 @@ pub trait ObjectCacheRead: Send + Sync { input_key ); // If the key exists at the specified version, then the object is available. + // TODO-DNS does this need to be inverted to check markers first, so that it doesn't incorrectly load + // a fastpath object value for a tx that's expecting a shared object at the same version? if has_key { versioned_results.push((*idx, true)) } else if receiving_objects.contains(input_key) { @@ -313,20 +319,21 @@ pub trait ObjectCacheRead: Send + Sync { // specified version exists or was deleted. We will then let mark it as available // to let the transaction through so it can fail at execution. let is_available = self - .get_object(&input_key.id()) + .get_object(&input_key.id().id()) .map(|obj| obj.version() >= input_key.version().unwrap()) .unwrap_or(false) - || self.have_deleted_owned_object_at_version_or_after( - &input_key.id(), + || self.have_deleted_fastpath_object_at_version_or_after( + input_key.id().id(), input_key.version().unwrap(), epoch, + use_object_per_epoch_marker_table_v2, ); versioned_results.push((*idx, is_available)); } else if self .get_deleted_shared_object_previous_tx_digest( - &input_key.id(), - input_key.version().unwrap(), + FullObjectKey::new(input_key.id(), input_key.version().unwrap()), epoch, + use_object_per_epoch_marker_table_v2, ) .is_some() { @@ -341,7 +348,7 @@ pub trait ObjectCacheRead: Send + Sync { let unversioned_results = keys_without_version.into_iter().map(|(idx, key)| { ( idx, - match self.get_latest_object_ref_or_tombstone(key.id()) { + match self.get_latest_object_ref_or_tombstone(key.id().id()) { None => false, Some(entry) => entry.2.is_alive(), }, @@ -384,25 +391,30 @@ pub trait ObjectCacheRead: Send + Sync { /// Get the marker at a specific version fn get_marker_value( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option; /// Get the latest marker for a given object. fn get_latest_marker( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option<(SequenceNumber, MarkerValue)>; /// If the shared object was deleted, return deletion info for the current live version fn get_last_shared_object_deletion_info( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option<(SequenceNumber, TransactionDigest)> { - match self.get_latest_marker(object_id, epoch_id) { + match self.get_latest_marker(object_id, epoch_id, use_object_per_epoch_marker_table_v2) { Some((version, MarkerValue::SharedDeleted(digest))) => Some((version, digest)), _ => None, } @@ -411,11 +423,12 @@ pub trait ObjectCacheRead: Send + Sync { /// If the shared object was deleted, return deletion info for the specified version. fn get_deleted_shared_object_previous_tx_digest( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option { - match self.get_marker_value(object_id, version, epoch_id) { + match self.get_marker_value(object_key, epoch_id, use_object_per_epoch_marker_table_v2) { Some(MarkerValue::SharedDeleted(digest)) => Some(digest), _ => None, } @@ -423,24 +436,28 @@ pub trait ObjectCacheRead: Send + Sync { fn have_received_object_at_version( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> bool { matches!( - self.get_marker_value(object_id, version, epoch_id), + self.get_marker_value(object_key, epoch_id, use_object_per_epoch_marker_table_v2), Some(MarkerValue::Received) ) } - fn have_deleted_owned_object_at_version_or_after( + fn have_deleted_fastpath_object_at_version_or_after( &self, - object_id: &ObjectID, + object_id: ObjectID, version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> bool { + let full_id = FullObjectID::Fastpath(object_id); // function explicilty assumes "fastpath" matches!( - self.get_latest_marker(object_id, epoch_id), + self.get_latest_marker(full_id, epoch_id, use_object_per_epoch_marker_table_v2), Some((marker_version, MarkerValue::OwnedDeleted)) if marker_version >= version ) } @@ -603,6 +620,8 @@ pub trait ExecutionCacheWrite: Send + Sync { &self, epoch_id: EpochId, tx_outputs: Arc, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'_, ()>; /// Attempt to acquire object locks for all of the owned input locks. @@ -739,6 +758,8 @@ macro_rules! implement_storage_traits { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { let Some(recv_object) = ObjectCacheRead::get_object_by_key( self, @@ -755,9 +776,13 @@ macro_rules! implement_storage_traits { // transaction replay due to possible reordering of transactions during replay. if recv_object.owner != Owner::AddressOwner((*owner).into()) || self.have_received_object_at_version( - receiving_object_id, - receive_object_at_version, + // TODO-DNS Is it safe to assume receiving objects are always fastpath objects? + FullObjectKey::new( + FullObjectID::new(*receiving_object_id, None), + receive_object_at_version, + ), epoch_id, + use_object_per_epoch_marker_table_v2, ) { return Ok(None); diff --git a/crates/sui-core/src/execution_cache/passthrough_cache.rs b/crates/sui-core/src/execution_cache/passthrough_cache.rs index ac3d1a136bc2c4..66cdbb5ca6a3c3 100644 --- a/crates/sui-core/src/execution_cache/passthrough_cache.rs +++ b/crates/sui-core/src/execution_cache/passthrough_cache.rs @@ -17,8 +17,8 @@ use std::sync::Arc; use sui_protocol_config::ProtocolVersion; use sui_storage::package_object_cache::PackageObjectCache; use sui_types::accumulator::Accumulator; -use sui_types::base_types::VerifiedExecutionData; use sui_types::base_types::{EpochId, ObjectID, ObjectRef, SequenceNumber}; +use sui_types::base_types::{FullObjectID, VerifiedExecutionData}; use sui_types::bridge::{get_bridge, Bridge}; use sui_types::digests::{TransactionDigest, TransactionEffectsDigest, TransactionEventsDigest}; use sui_types::effects::{TransactionEffects, TransactionEvents}; @@ -26,7 +26,9 @@ use sui_types::error::SuiResult; use sui_types::message_envelope::Message; use sui_types::messages_checkpoint::CheckpointSequenceNumber; use sui_types::object::Object; -use sui_types::storage::{MarkerValue, ObjectKey, ObjectOrTombstone, ObjectStore, PackageObject}; +use sui_types::storage::{ + FullObjectKey, MarkerValue, ObjectKey, ObjectOrTombstone, ObjectStore, PackageObject, +}; use sui_types::sui_system_state::{get_sui_system_state, SuiSystemState}; use sui_types::transaction::{VerifiedSignedTransaction, VerifiedTransaction}; use tap::TapFallible; @@ -171,22 +173,25 @@ impl ObjectCacheRead for PassthroughCache { fn get_marker_value( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option { self.store - .get_marker_value(object_id, &version, epoch_id) + .get_marker_value(object_key, epoch_id, use_object_per_epoch_marker_table_v2) .expect("db error") } fn get_latest_marker( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option<(SequenceNumber, MarkerValue)> { self.store - .get_latest_marker(object_id, epoch_id) + .get_latest_marker(object_id, epoch_id, use_object_per_epoch_marker_table_v2) .expect("db error") } @@ -258,6 +263,8 @@ impl ExecutionCacheWrite for PassthroughCache { &'a self, epoch_id: EpochId, tx_outputs: Arc, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'a, ()> { async move { let tx_digest = *tx_outputs.transaction.digest(); @@ -277,7 +284,11 @@ impl ExecutionCacheWrite for PassthroughCache { .expect("db error"); self.store - .write_transaction_outputs(epoch_id, &[tx_outputs]) + .write_transaction_outputs( + epoch_id, + &[tx_outputs], + use_object_per_epoch_marker_table_v2, + ) .await .expect("db error"); @@ -355,6 +366,8 @@ impl ExecutionCacheCommit for PassthroughCache { &'a self, _epoch: EpochId, _digests: &'a [TransactionDigest], + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'a, ()> { // Nothing needs to be done since they were already committed in write_transaction_outputs ready(()).boxed() diff --git a/crates/sui-core/src/execution_cache/proxy_cache.rs b/crates/sui-core/src/execution_cache/proxy_cache.rs index 5f0b1fc8c7b711..9d26f13dd9274f 100644 --- a/crates/sui-core/src/execution_cache/proxy_cache.rs +++ b/crates/sui-core/src/execution_cache/proxy_cache.rs @@ -17,15 +17,15 @@ use std::sync::Arc; use std::time::Duration; use sui_protocol_config::ProtocolVersion; use sui_types::accumulator::Accumulator; -use sui_types::base_types::VerifiedExecutionData; use sui_types::base_types::{EpochId, ObjectID, ObjectRef, SequenceNumber}; +use sui_types::base_types::{FullObjectID, VerifiedExecutionData}; use sui_types::bridge::Bridge; use sui_types::digests::{TransactionDigest, TransactionEffectsDigest, TransactionEventsDigest}; use sui_types::effects::{TransactionEffects, TransactionEvents}; use sui_types::error::SuiResult; use sui_types::messages_checkpoint::CheckpointSequenceNumber; use sui_types::object::Object; -use sui_types::storage::{MarkerValue, ObjectKey, ObjectOrTombstone, PackageObject}; +use sui_types::storage::{FullObjectKey, MarkerValue, ObjectKey, ObjectOrTombstone, PackageObject}; use sui_types::sui_system_state::SuiSystemState; use sui_types::transaction::{VerifiedSignedTransaction, VerifiedTransaction}; @@ -172,19 +172,30 @@ impl ObjectCacheRead for ProxyCache { fn get_marker_value( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option { - delegate_method!(self.get_marker_value(object_id, version, epoch_id)) + delegate_method!(self.get_marker_value( + object_key, + epoch_id, + use_object_per_epoch_marker_table_v2 + )) } fn get_latest_marker( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option<(SequenceNumber, MarkerValue)> { - delegate_method!(self.get_latest_marker(object_id, epoch_id)) + delegate_method!(self.get_latest_marker( + object_id, + epoch_id, + use_object_per_epoch_marker_table_v2 + )) } fn get_highest_pruned_checkpoint(&self) -> CheckpointSequenceNumber { @@ -234,8 +245,14 @@ impl ExecutionCacheWrite for ProxyCache { &self, epoch_id: EpochId, tx_outputs: Arc, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'_, ()> { - delegate_method!(self.write_transaction_outputs(epoch_id, tx_outputs)) + delegate_method!(self.write_transaction_outputs( + epoch_id, + tx_outputs, + use_object_per_epoch_marker_table_v2 + )) } fn acquire_transaction_locks<'a>( @@ -305,8 +322,14 @@ impl ExecutionCacheCommit for ProxyCache { &'a self, epoch: EpochId, digests: &'a [TransactionDigest], + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'a, ()> { - delegate_method!(self.commit_transaction_outputs(epoch, digests)) + delegate_method!(self.commit_transaction_outputs( + epoch, + digests, + use_object_per_epoch_marker_table_v2 + )) } fn persist_transactions<'a>(&'a self, digests: &'a [TransactionDigest]) -> BoxFuture<'a, ()> { diff --git a/crates/sui-core/src/execution_cache/unit_tests/writeback_cache_tests.rs b/crates/sui-core/src/execution_cache/unit_tests/writeback_cache_tests.rs index 86398b1ad06ba8..cb1575a2d3e6b1 100644 --- a/crates/sui-core/src/execution_cache/unit_tests/writeback_cache_tests.rs +++ b/crates/sui-core/src/execution_cache/unit_tests/writeback_cache_tests.rs @@ -325,7 +325,7 @@ impl Scenario { .find(|o| **o == object.compute_object_reference()) .expect("received object must have new lock"); self.outputs.markers.push(( - object.compute_object_reference().into(), + object.compute_full_object_reference().into(), MarkerValue::Received, )); } @@ -348,7 +348,7 @@ impl Scenario { assert!(self.transactions.insert(tx), "transaction is not unique"); self.cache() - .write_transaction_outputs(1 /* epoch */, outputs.clone()) + .write_transaction_outputs(1 /* epoch */, outputs.clone(), true) .await; self.count_action(); @@ -357,7 +357,10 @@ impl Scenario { // commit a transaction to the database pub async fn commit(&mut self, tx: TransactionDigest) -> SuiResult { - let res = self.cache().commit_transaction_outputs(1, &[tx]).await; + let res = self + .cache() + .commit_transaction_outputs(1, &[tx], true) + .await; self.count_action(); Ok(res) } @@ -488,9 +491,11 @@ impl Scenario { .unwrap(), *object ); - assert!(self - .cache() - .have_received_object_at_version(id, object.version(), 1)); + assert!(self.cache().have_received_object_at_version( + FullObjectKey::new(object.full_id(), object.version()), + 1, + true + )); } } @@ -553,7 +558,7 @@ async fn test_committed() { s.assert_live(&[1, 2]); s.assert_dirty(&[1, 2]); - s.cache().commit_transaction_outputs(1, &[tx]).await; + s.cache().commit_transaction_outputs(1, &[tx], true).await; s.assert_not_dirty(&[1, 2]); s.assert_cached(&[1, 2]); diff --git a/crates/sui-core/src/execution_cache/writeback_cache.rs b/crates/sui-core/src/execution_cache/writeback_cache.rs index 0783ee082dff5b..17658ef76e186f 100644 --- a/crates/sui-core/src/execution_cache/writeback_cache.rs +++ b/crates/sui-core/src/execution_cache/writeback_cache.rs @@ -63,7 +63,9 @@ use sui_config::ExecutionCacheConfig; use sui_macros::fail_point_async; use sui_protocol_config::ProtocolVersion; use sui_types::accumulator::Accumulator; -use sui_types::base_types::{EpochId, ObjectID, ObjectRef, SequenceNumber, VerifiedExecutionData}; +use sui_types::base_types::{ + EpochId, FullObjectID, ObjectID, ObjectRef, SequenceNumber, VerifiedExecutionData, +}; use sui_types::bridge::{get_bridge, Bridge}; use sui_types::digests::{ ObjectDigest, TransactionDigest, TransactionEffectsDigest, TransactionEventsDigest, @@ -73,7 +75,9 @@ use sui_types::error::{SuiError, SuiResult, UserInputError}; use sui_types::message_envelope::Message; use sui_types::messages_checkpoint::CheckpointSequenceNumber; use sui_types::object::Object; -use sui_types::storage::{MarkerValue, ObjectKey, ObjectOrTombstone, ObjectStore, PackageObject}; +use sui_types::storage::{ + FullObjectKey, MarkerValue, ObjectKey, ObjectOrTombstone, ObjectStore, PackageObject, +}; use sui_types::sui_system_state::{get_sui_system_state, SuiSystemState}; use sui_types::transaction::{VerifiedSignedTransaction, VerifiedTransaction}; use tap::TapOptional; @@ -180,7 +184,7 @@ impl IsNewer for LatestObjectCacheEntry { } } -type MarkerKey = (EpochId, ObjectID); +type MarkerKey = (EpochId, FullObjectID); enum CacheResult { /// Entry is in the cache @@ -547,22 +551,18 @@ impl WritebackCache { async fn write_marker_value( &self, epoch_id: EpochId, - object_key: &ObjectKey, + object_key: FullObjectKey, marker_value: MarkerValue, ) { - tracing::trace!( - "inserting marker value {:?}: {:?}", - object_key, - marker_value - ); + tracing::trace!("inserting marker value {object_key:?}: {marker_value:?}",); fail_point_async!("write_marker_entry"); self.metrics.record_cache_write("marker"); self.dirty .markers - .entry((epoch_id, object_key.0)) + .entry((epoch_id, object_key.id())) .or_default() .value_mut() - .insert(object_key.1, marker_value); + .insert(object_key.version(), marker_value); } // lock both the dirty and committed sides of the cache, and then pass the entries to @@ -734,28 +734,27 @@ impl WritebackCache { fn get_marker_value_cache_only( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, ) -> CacheResult { Self::with_locked_cache_entries( &self.dirty.markers, &self.cached.marker_cache, - &(epoch_id, *object_id), + &(epoch_id, object_key.id()), |dirty_entry, cached_entry| { check_cache_entry_by_version!( self, "marker_by_version", "uncommitted", dirty_entry, - version + object_key.version() ); check_cache_entry_by_version!( self, "marker_by_version", "committed", cached_entry, - version + object_key.version() ); CacheResult::Miss }, @@ -764,13 +763,13 @@ impl WritebackCache { fn get_latest_marker_value_cache_only( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, ) -> CacheResult<(SequenceNumber, MarkerValue)> { Self::with_locked_cache_entries( &self.dirty.markers, &self.cached.marker_cache, - &(epoch_id, *object_id), + &(epoch_id, object_id), |dirty_entry, cached_entry| { check_cache_entry_by_latest!(self, "marker_latest", "uncommitted", dirty_entry); check_cache_entry_by_latest!(self, "marker_latest", "committed", cached_entry); @@ -846,7 +845,7 @@ impl WritebackCache { // Update all markers for (object_key, marker_value) in markers.iter() { - self.write_marker_value(epoch_id, object_key, *marker_value) + self.write_marker_value(epoch_id, *object_key, *marker_value) .await; } @@ -928,7 +927,13 @@ impl WritebackCache { // Commits dirty data for the given TransactionDigest to the db. #[instrument(level = "debug", skip_all)] - async fn commit_transaction_outputs(&self, epoch: EpochId, digests: &[TransactionDigest]) { + async fn commit_transaction_outputs( + &self, + epoch: EpochId, + digests: &[TransactionDigest], + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, + ) { fail_point_async!("writeback-cache-commit"); trace!(?digests); @@ -955,7 +960,7 @@ impl WritebackCache { // a cache eviction could cause a value to disappear briefly, even if we insert to the // cache before removing from the dirty set. self.store - .write_transaction_outputs(epoch, &all_outputs) + .write_transaction_outputs(epoch, &all_outputs, use_object_per_epoch_marker_table_v2) .await .expect("db error"); @@ -1093,8 +1098,8 @@ impl WritebackCache { Self::move_version_from_dirty_to_cache( &self.dirty.markers, &self.cached.marker_cache, - (epoch, object_key.0), - object_key.1, + (epoch, object_key.id()), + object_key.version(), marker_value, ); } @@ -1297,8 +1302,16 @@ impl ExecutionCacheCommit for WritebackCache { &'a self, epoch: EpochId, digests: &'a [TransactionDigest], + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'a, ()> { - WritebackCache::commit_transaction_outputs(self, epoch, digests).boxed() + WritebackCache::commit_transaction_outputs( + self, + epoch, + digests, + use_object_per_epoch_marker_table_v2, + ) + .boxed() } fn persist_transactions<'a>(&'a self, digests: &'a [TransactionDigest]) -> BoxFuture<'a, ()> { @@ -1643,24 +1656,27 @@ impl ObjectCacheRead for WritebackCache { fn get_marker_value( &self, - object_id: &ObjectID, - version: SequenceNumber, + object_key: FullObjectKey, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option { - match self.get_marker_value_cache_only(object_id, version, epoch_id) { + match self.get_marker_value_cache_only(object_key, epoch_id) { CacheResult::Hit(marker) => Some(marker), CacheResult::NegativeHit => None, CacheResult::Miss => self .record_db_get("marker_by_version") - .get_marker_value(object_id, &version, epoch_id) + .get_marker_value(object_key, epoch_id, use_object_per_epoch_marker_table_v2) .expect("db error"), } } fn get_latest_marker( &self, - object_id: &ObjectID, + object_id: FullObjectID, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> Option<(SequenceNumber, MarkerValue)> { match self.get_latest_marker_value_cache_only(object_id, epoch_id) { CacheResult::Hit((v, marker)) => Some((v, marker)), @@ -1669,7 +1685,7 @@ impl ObjectCacheRead for WritebackCache { } CacheResult::Miss => self .record_db_get("marker_latest") - .get_latest_marker(object_id, epoch_id) + .get_latest_marker(object_id, epoch_id, use_object_per_epoch_marker_table_v2) .expect("db error"), } } @@ -2064,6 +2080,8 @@ impl ExecutionCacheWrite for WritebackCache { &self, epoch_id: EpochId, tx_outputs: Arc, + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> BoxFuture<'_, ()> { WritebackCache::write_transaction_outputs(self, epoch_id, tx_outputs).boxed() } diff --git a/crates/sui-core/src/transaction_input_loader.rs b/crates/sui-core/src/transaction_input_loader.rs index 016e8b956cf97c..edba8851ddba63 100644 --- a/crates/sui-core/src/transaction_input_loader.rs +++ b/crates/sui-core/src/transaction_input_loader.rs @@ -14,9 +14,9 @@ use once_cell::unsync::OnceCell; use std::collections::HashMap; use std::sync::Arc; use sui_types::{ - base_types::{EpochId, ObjectRef, SequenceNumber, TransactionDigest}, + base_types::{EpochId, FullObjectID, ObjectRef, SequenceNumber, TransactionDigest}, error::{SuiError, SuiResult, UserInputError}, - storage::ObjectKey, + storage::{FullObjectKey, ObjectKey}, transaction::{ InputObjectKind, InputObjects, ObjectReadResult, ObjectReadResultKind, ReceivingObjectReadResult, ReceivingObjectReadResultKind, ReceivingObjects, TransactionKey, @@ -47,6 +47,8 @@ impl TransactionInputLoader { input_object_kinds: &[InputObjectKind], receiving_objects: &[ObjectRef], epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult<(InputObjects, ReceivingObjects)> { // Length of input_object_kinds have been checked via validity_check() for ProgrammableTransaction. let mut input_results = vec![None; input_object_kinds.len()]; @@ -65,14 +67,21 @@ impl TransactionInputLoader { object: ObjectReadResultKind::Object(package), }); } - InputObjectKind::SharedMoveObject { id, .. } => match self.cache.get_object(id) { + InputObjectKind::SharedMoveObject { + id, + initial_shared_version, + .. + } => match self.cache.get_object(id) { Some(object) => { input_results[i] = Some(ObjectReadResult::new(*kind, object.into())) } None => { - if let Some((version, digest)) = self - .cache - .get_last_shared_object_deletion_info(id, epoch_id) + if let Some((version, digest)) = + self.cache.get_last_shared_object_deletion_info( + FullObjectID::new(*id, Some(*initial_shared_version)), + epoch_id, + use_object_per_epoch_marker_table_v2, + ) { input_results[i] = Some(ObjectReadResult { input_object_kind: *kind, @@ -101,8 +110,11 @@ impl TransactionInputLoader { }); } - let receiving_results = - self.read_receiving_objects_for_signing(receiving_objects, epoch_id)?; + let receiving_results = self.read_receiving_objects_for_signing( + receiving_objects, + epoch_id, + use_object_per_epoch_marker_table_v2, + )?; Ok(( input_results @@ -228,11 +240,18 @@ impl TransactionInputLoader { input_object_kind: *input_object_kind, object: obj.into(), }, - (None, InputObjectKind::SharedMoveObject { id, .. }) => { + (None, InputObjectKind::SharedMoveObject { id, initial_shared_version, .. }) => { assert!(key.1.is_valid()); // Check if the object was deleted by a concurrently certified tx let version = key.1; - if let Some(dependency) = self.cache.get_deleted_shared_object_previous_tx_digest(id, version, epoch_id) { + if let Some(dependency) = self.cache.get_deleted_shared_object_previous_tx_digest( + FullObjectKey::new( + FullObjectID::new(*id, Some(*initial_shared_version)), + version, + ), + epoch_id, + epoch_store.protocol_config().use_object_per_epoch_marker_table_v2_as_option().unwrap_or(false), + ) { ObjectReadResult { input_object_kind: *input, object: ObjectReadResultKind::DeletedSharedObject(version, dependency), @@ -259,16 +278,20 @@ impl TransactionInputLoader { &self, receiving_objects: &[ObjectRef], epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult { let mut receiving_results = Vec::with_capacity(receiving_objects.len()); for objref in receiving_objects { // Note: the digest is checked later in check_transaction_input let (object_id, version, _) = objref; - if self - .cache - .have_received_object_at_version(object_id, *version, epoch_id) - { + // TODO-DNS Is it safe to assume receiving objects are always fastpath objects? + if self.cache.have_received_object_at_version( + FullObjectKey::new(FullObjectID::new(*object_id, None), *version), + epoch_id, + use_object_per_epoch_marker_table_v2, + ) { receiving_results.push(ReceivingObjectReadResult::new( *objref, ReceivingObjectReadResultKind::PreviouslyReceivedObject, diff --git a/crates/sui-core/src/transaction_manager.rs b/crates/sui-core/src/transaction_manager.rs index a81f5cb9e0b341..809c0bdc294afe 100644 --- a/crates/sui-core/src/transaction_manager.rs +++ b/crates/sui-core/src/transaction_manager.rs @@ -13,7 +13,7 @@ use mysten_common::fatal; use mysten_metrics::monitored_scope; use parking_lot::RwLock; use sui_types::{ - base_types::{ObjectID, SequenceNumber, TransactionDigest}, + base_types::{FullObjectID, SequenceNumber, TransactionDigest}, committee::EpochId, digests::TransactionEffectsDigest, error::{SuiError, SuiResult}, @@ -83,10 +83,10 @@ pub struct PendingCertificate { } struct CacheInner { - versioned_cache: LruCache, + versioned_cache: LruCache, // we cache packages separately, because they are more expensive to look up in the db, so we // don't want to evict packages in favor of mutable objects. - unversioned_cache: LruCache, + unversioned_cache: LruCache, max_size: usize, metrics: Arc, @@ -228,7 +228,7 @@ struct Inner { // Stores age info for all transactions depending on each object. // Used for throttling signing and submitting transactions depending on hot objects. // An `IndexMap` is used to ensure that the insertion order is preserved. - input_objects: HashMap, + input_objects: HashMap, // Maps object IDs to the highest observed sequence number of the object. When the value is // None, indicates that the object is immutable, corresponding to an InputKey with no sequence @@ -461,7 +461,8 @@ impl TransactionManager { cert.data().intent_message().value.receiving_objects(); for entry in receiving_object_entries { let key = InputKey::VersionedObject { - id: entry.0, + // TODO-DNS Is it safe to assume receiving objects are always fastpath objects? + id: FullObjectID::new(entry.0, None), version: entry.1, }; receiving_objects.insert(key); @@ -510,6 +511,10 @@ impl TransactionManager { &input_object_cache_misses, receiving_objects, epoch_store.epoch(), + epoch_store + .protocol_config() + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), ) .into_iter() .zip(input_object_cache_misses); @@ -786,8 +791,8 @@ impl TransactionManager { // Returns the number of transactions waiting on each object ID, as well as the age of the oldest transaction in the queue. pub(crate) fn objects_queue_len_and_age( &self, - keys: Vec, - ) -> Vec<(ObjectID, usize, Option)> { + keys: Vec, + ) -> Vec<(FullObjectID, usize, Option)> { let reconfig_lock = self.inner.read(); let inner = reconfig_lock.read(); keys.into_iter() @@ -839,7 +844,10 @@ impl TransactionManager { .transaction_data() .shared_input_objects() .into_iter() - .filter_map(|r| r.mutable.then_some(r.id)) + .filter_map(|r| { + r.mutable + .then_some(FullObjectID::new(r.id, Some(r.initial_shared_version))) + }) .collect(), ) { // When this occurs, most likely transactions piled up on a shared object. @@ -849,7 +857,7 @@ impl TransactionManager { object_id, queue_len ); fp_bail!(SuiError::TooManyTransactionsPendingOnObject { - object_id, + object_id: object_id.id(), queue_len, threshold: overload_config.max_transaction_manager_per_object_queue_length, }); @@ -863,7 +871,7 @@ impl TransactionManager { age.as_millis() ); fp_bail!(SuiError::TooOldTransactionPendingOnObject { - object_id, + object_id: object_id.id(), txn_age_sec: age.as_secs(), threshold: overload_config.max_txn_age_in_queue.as_secs(), }); @@ -1012,6 +1020,7 @@ mod test { use super::*; use prometheus::Registry; use rand::{Rng, RngCore}; + use sui_types::base_types::ObjectID; #[test] #[cfg_attr(msim, ignore)] @@ -1037,7 +1046,7 @@ mod test { // insert 10 unique versioned objects for i in 0..10 { - let object = ObjectID::new([i; 32]); + let object = FullObjectID::new(ObjectID::new([i; 32]), None); let input_key = InputKey::VersionedObject { id: object, version: (i as u64).into(), @@ -1049,7 +1058,7 @@ mod test { // first 5 versioned objects have been evicted for i in 0..5 { - let object = ObjectID::new([i; 32]); + let object = FullObjectID::new(ObjectID::new([i; 32]), None); let input_key = InputKey::VersionedObject { id: object, version: (i as u64).into(), @@ -1065,7 +1074,7 @@ mod test { } // object 9 is available at version 9 - let object = ObjectID::new([9; 32]); + let object = FullObjectID::new(ObjectID::new([9; 32]), None); let input_key = InputKey::VersionedObject { id: object, version: 9.into(), diff --git a/crates/sui-core/src/transaction_outputs.rs b/crates/sui-core/src/transaction_outputs.rs index 43b556525a407f..a706741e472b67 100644 --- a/crates/sui-core/src/transaction_outputs.rs +++ b/crates/sui-core/src/transaction_outputs.rs @@ -3,10 +3,10 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; -use sui_types::base_types::ObjectRef; +use sui_types::base_types::{FullObjectID, ObjectRef}; use sui_types::effects::{TransactionEffects, TransactionEffectsAPI, TransactionEvents}; use sui_types::inner_temporary_store::{InnerTemporaryStore, WrittenObjects}; -use sui_types::storage::{MarkerValue, ObjectKey}; +use sui_types::storage::{FullObjectKey, MarkerValue, ObjectKey}; use sui_types::transaction::{TransactionDataAPI, VerifiedTransaction}; /// TransactionOutputs @@ -15,7 +15,7 @@ pub struct TransactionOutputs { pub effects: TransactionEffects, pub events: TransactionEvents, - pub markers: Vec<(ObjectKey, MarkerValue)>, + pub markers: Vec<(FullObjectKey, MarkerValue)>, pub wrapped: Vec, pub deleted: Vec, pub locks_to_delete: Vec, @@ -57,19 +57,26 @@ impl TransactionOutputs { // object deletions in the marker table. For deleted entries in the marker table we need to // make sure we don't accidentally overwrite entries. let markers: Vec<_> = { - let received = received_objects - .clone() - .map(|objref| (ObjectKey::from(objref), MarkerValue::Received)); + let received = received_objects.clone().map(|objref| { + ( + // TODO-DNS is it safe to assume that received objects are always fastpath? + FullObjectKey::new(FullObjectID::new(objref.0, None), objref.1), + MarkerValue::Received, + ) + }); let deleted = deleted.into_iter().map(|(object_id, version)| { - let object_key = ObjectKey(object_id, version); - if input_objects + let shared_key = input_objects .get(&object_id) - .is_some_and(|object| object.is_shared()) - { - (object_key, MarkerValue::SharedDeleted(tx_digest)) + .filter(|o| o.is_consensus()) + .map(|o| FullObjectKey::new(o.full_id(), version)); + if let Some(shared_key) = shared_key { + (shared_key, MarkerValue::SharedDeleted(tx_digest)) } else { - (object_key, MarkerValue::OwnedDeleted) + ( + FullObjectKey::new(FullObjectID::new(object_id, None), version), + MarkerValue::OwnedDeleted, + ) } }); @@ -78,9 +85,13 @@ impl TransactionOutputs { // NB: that we do _not_ smear shared objects that were taken immutably in the // transaction. let smeared_objects = effects.deleted_mutably_accessed_shared_objects(); - let shared_smears = smeared_objects.into_iter().map(move |object_id| { + let shared_smears = smeared_objects.into_iter().map(|object_id| { + let object = input_objects + .get(&object_id) + // TODO-DNS: Double check, is this `expect` safe? + .expect("deleted object must be in input objects"); ( - ObjectKey(object_id, lamport_version), + FullObjectKey::new(object.full_id(), lamport_version), MarkerValue::SharedDeleted(tx_digest), ) }); diff --git a/crates/sui-core/src/unit_tests/authority_tests.rs b/crates/sui-core/src/unit_tests/authority_tests.rs index dc086129d2bc46..6b9eae0f277ab6 100644 --- a/crates/sui-core/src/unit_tests/authority_tests.rs +++ b/crates/sui-core/src/unit_tests/authority_tests.rs @@ -3239,6 +3239,7 @@ async fn test_store_revert_wrap_move_call() { .commit_transaction_outputs( authority_state.epoch_store_for_testing().epoch(), &[*create_effects.transaction_digest()], + true, ) .await; @@ -3338,6 +3339,7 @@ async fn test_store_revert_unwrap_move_call() { *create_effects.transaction_digest(), *wrap_effects.transaction_digest(), ], + true, ) .await; @@ -3617,6 +3619,7 @@ async fn test_store_revert_add_ofield() { *create_outer_effects.transaction_digest(), *create_inner_effects.transaction_digest(), ], + true, ) .await; @@ -3744,6 +3747,7 @@ async fn test_store_revert_remove_ofield() { *create_inner_effects.transaction_digest(), *add_effects.transaction_digest(), ], + true, ) .await; diff --git a/crates/sui-core/src/unit_tests/shared_object_deletion_tests.rs b/crates/sui-core/src/unit_tests/shared_object_deletion_tests.rs index 05e967aec9e274..a409574ed5305e 100644 --- a/crates/sui-core/src/unit_tests/shared_object_deletion_tests.rs +++ b/crates/sui-core/src/unit_tests/shared_object_deletion_tests.rs @@ -5,12 +5,13 @@ use std::sync::Arc; use sui_types::{ - base_types::{ObjectID, ObjectRef, SequenceNumber, SuiAddress}, + base_types::{FullObjectID, ObjectID, ObjectRef, SequenceNumber, SuiAddress}, crypto::{get_key_pair, AccountKeyPair}, effects::TransactionEffects, execution_status::{CommandArgumentError, ExecutionFailureStatus}, object::Object, programmable_transaction_builder::ProgrammableTransactionBuilder, + storage::FullObjectKey, transaction::{ProgrammableTransaction, Transaction, TEST_ONLY_GAS_UNIT_FOR_PUBLISH}, }; @@ -553,13 +554,12 @@ impl TestRunner { pub fn object_exists_in_marker_table( &mut self, - object_id: &ObjectID, - version: &SequenceNumber, + object_key: FullObjectKey, epoch: EpochId, ) -> Option { self.authority_state .get_object_cache_reader() - .get_deleted_shared_object_previous_tx_digest(object_id, *version, epoch) + .get_deleted_shared_object_previous_tx_digest(object_key, epoch, true) } } @@ -608,7 +608,13 @@ async fn test_delete_shared_object() { assert_eq!( user1 - .object_exists_in_marker_table(&deleted_obj_id, &deleted_obj_ver, 0) + .object_exists_in_marker_table( + FullObjectKey::new( + FullObjectID::new(deleted_obj_id, Some(initial_shared_version)), + deleted_obj_ver + ), + 0 + ) .unwrap(), *effects.transaction_digest(), ); @@ -728,7 +734,13 @@ async fn test_delete_shared_object_immut_mut_mut_interleave() { assert_eq!( user1 - .object_exists_in_marker_table(&deleted_obj_id, &deleted_obj_ver, 0) + .object_exists_in_marker_table( + FullObjectKey::new( + FullObjectID::new(deleted_obj_id, Some(initial_shared_version)), + deleted_obj_ver + ), + 0 + ) .unwrap(), *effects.transaction_digest(), ); @@ -825,7 +837,13 @@ async fn test_delete_shared_object_immut_mut_immut_interleave() { assert_eq!( user1 - .object_exists_in_marker_table(&deleted_obj_id, &deleted_obj_ver, 0) + .object_exists_in_marker_table( + FullObjectKey::new( + FullObjectID::new(deleted_obj_id, Some(initial_shared_version)), + deleted_obj_ver + ), + 0 + ) .unwrap(), *effects.transaction_digest(), ); @@ -1475,7 +1493,13 @@ async fn test_delete_with_shared_after_mutate_enqueued() { let deleted_obj_ver = delete_effects.deleted()[0].1; assert!(user_1 - .object_exists_in_marker_table(&shared_obj_id, &deleted_obj_ver, 0) + .object_exists_in_marker_table( + FullObjectKey::new( + FullObjectID::new(shared_obj_id, Some(initial_shared_version)), + deleted_obj_ver + ), + 0 + ) .is_some()); let mutate_effects = res.get(1).unwrap(); diff --git a/crates/sui-core/src/unit_tests/transaction_deny_tests.rs b/crates/sui-core/src/unit_tests/transaction_deny_tests.rs index b31049319b31db..911ae4eb5edb4c 100644 --- a/crates/sui-core/src/unit_tests/transaction_deny_tests.rs +++ b/crates/sui-core/src/unit_tests/transaction_deny_tests.rs @@ -354,6 +354,7 @@ async fn test_package_denied() { .commit_transaction_outputs( state.epoch_store_for_testing().epoch(), &[tx_c, tx_b, tx_a, tx_c_prime, tx_b_prime], + true, ) .await; diff --git a/crates/sui-core/src/unit_tests/transaction_manager_tests.rs b/crates/sui-core/src/unit_tests/transaction_manager_tests.rs index 7e3e455d8ed4cf..b5f13b1f579933 100644 --- a/crates/sui-core/src/unit_tests/transaction_manager_tests.rs +++ b/crates/sui-core/src/unit_tests/transaction_manager_tests.rs @@ -60,7 +60,7 @@ fn get_input_keys(objects: &[Object]) -> Vec { objects .iter() .map(|object| InputKey::VersionedObject { - id: object.id(), + id: object.full_id(), version: object.version(), }) .collect() @@ -340,7 +340,7 @@ async fn transaction_manager_object_dependency() { // Notify TM about availability of the first shared object. transaction_manager.objects_available( vec![InputKey::VersionedObject { - id: shared_object.id(), + id: shared_object.full_id(), version: shared_version, }], &state.epoch_store_for_testing(), @@ -377,7 +377,7 @@ async fn transaction_manager_object_dependency() { // Make shared_object_2 available. transaction_manager.objects_available( vec![InputKey::VersionedObject { - id: shared_object_2.id(), + id: shared_object_2.full_id(), version: shared_version_2, }], &state.epoch_store_for_testing(), @@ -475,7 +475,7 @@ async fn transaction_manager_receiving_notify_commit() { transaction_manager.notify_commit( txn.digest(), vec![InputKey::VersionedObject { - id: object.id(), + id: object.full_id(), version: object.version().next(), }], &state.epoch_store_for_testing(), @@ -860,7 +860,7 @@ async fn transaction_manager_with_cancelled_transactions() { // Notify TM about availability of the owned object. transaction_manager.objects_available( vec![InputKey::VersionedObject { - id: owned_object.id(), + id: owned_object.full_id(), version: owned_version, }], &state.epoch_store_for_testing(), diff --git a/crates/sui-core/src/unit_tests/transfer_to_object_tests.rs b/crates/sui-core/src/unit_tests/transfer_to_object_tests.rs index ff1b5825455257..12e974b05bcf3f 100644 --- a/crates/sui-core/src/unit_tests/transfer_to_object_tests.rs +++ b/crates/sui-core/src/unit_tests/transfer_to_object_tests.rs @@ -1759,8 +1759,8 @@ async fn test_have_deleted_owned_object() { assert!(cache.get_object(&new_child.0.0).is_some()); // Should not show as deleted for either versions - assert!(!cache.have_deleted_owned_object_at_version_or_after(&new_child.0.0, new_child.0.1, 0)); - assert!(!cache.have_deleted_owned_object_at_version_or_after(&new_child.0.0, child.0.1, 0)); + assert!(!cache.have_deleted_fastpath_object_at_version_or_after(new_child.0.0, new_child.0.1, 0, true)); + assert!(!cache.have_deleted_fastpath_object_at_version_or_after(new_child.0.0, child.0.1, 0, true)); let effects = runner .run({ @@ -1777,13 +1777,13 @@ async fn test_have_deleted_owned_object() { let deleted_child = effects.deleted().into_iter().find(|(id, _, _)| *id == new_child.0 .0).unwrap(); assert!(cache.get_object(&deleted_child.0).is_none()); - assert!(cache.have_deleted_owned_object_at_version_or_after(&deleted_child.0, deleted_child.1, 0)); - assert!(cache.have_deleted_owned_object_at_version_or_after(&deleted_child.0, new_child.0.1, 0)); - assert!(cache.have_deleted_owned_object_at_version_or_after(&deleted_child.0, child.0.1, 0)); + assert!(cache.have_deleted_fastpath_object_at_version_or_after(deleted_child.0, deleted_child.1, 0, true)); + assert!(cache.have_deleted_fastpath_object_at_version_or_after(deleted_child.0, new_child.0.1, 0, true)); + assert!(cache.have_deleted_fastpath_object_at_version_or_after(deleted_child.0, child.0.1, 0, true)); // Should not show as deleted for versions after this though - assert!(!cache.have_deleted_owned_object_at_version_or_after(&deleted_child.0, deleted_child.1.next(), 0)); + assert!(!cache.have_deleted_fastpath_object_at_version_or_after(deleted_child.0, deleted_child.1.next(), 0, true)); // Should not show as deleted for other epochs outside of our current epoch too - assert!(!cache.have_deleted_owned_object_at_version_or_after(&deleted_child.0, deleted_child.1, 1)); + assert!(!cache.have_deleted_fastpath_object_at_version_or_after(deleted_child.0, deleted_child.1, 1, true)); } } } diff --git a/crates/sui-open-rpc/spec/openrpc.json b/crates/sui-open-rpc/spec/openrpc.json index d5110c6494dbfc..6ea764cf8c78c2 100644 --- a/crates/sui-open-rpc/spec/openrpc.json +++ b/crates/sui-open-rpc/spec/openrpc.json @@ -1294,7 +1294,7 @@ "name": "Result", "value": { "minSupportedProtocolVersion": "1", - "maxSupportedProtocolVersion": "71", + "maxSupportedProtocolVersion": "72", "protocolVersion": "6", "featureFlags": { "accept_zklogin_in_multisig": false, @@ -1946,6 +1946,7 @@ "types_is_one_time_witness_type_tag_cost_per_byte": { "u64": "2" }, + "use_object_per_epoch_marker_table_v2": null, "validator_validate_metadata_cost_base": { "u64": "52" }, diff --git a/crates/sui-protocol-config/src/lib.rs b/crates/sui-protocol-config/src/lib.rs index 79801f1b8a8e9b..f4fa79b9672785 100644 --- a/crates/sui-protocol-config/src/lib.rs +++ b/crates/sui-protocol-config/src/lib.rs @@ -18,7 +18,7 @@ use tracing::{info, warn}; /// The minimum and maximum protocol versions supported by this build. const MIN_PROTOCOL_VERSION: u64 = 1; -const MAX_PROTOCOL_VERSION: u64 = 71; +const MAX_PROTOCOL_VERSION: u64 = 72; // Record history of protocol version allocations here: // @@ -204,6 +204,7 @@ const MAX_PROTOCOL_VERSION: u64 = 71; // Add std::uq64_64 module to Move stdlib. // Improve gas/wall time efficiency of some Move stdlib vector functions // Version 71: [SIP-45] Enable consensus amplification. +// Version 72: Enable new marker table version. #[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct ProtocolVersion(u64); @@ -1341,6 +1342,9 @@ pub struct ProtocolConfig { /// SIP-45: K in the formula `amplification_factor = max(0, gas_price / reference_gas_price - K)`. /// This is the threshold for activating consensus amplification. sip_45_consensus_amplification_threshold: Option, + + /// Enables use of v2 of the object per-epoch marker table with FullObjectID keys. + use_object_per_epoch_marker_table_v2: Option, } // feature flags @@ -2266,6 +2270,8 @@ impl ProtocolConfig { gas_budget_based_txn_cost_absolute_cap_commit_count: None, sip_45_consensus_amplification_threshold: None, + + use_object_per_epoch_marker_table_v2: None, // When adding a new constant, set it to None in the earliest version, like this: // new_constant: None, }; @@ -3105,6 +3111,10 @@ impl ProtocolConfig { // Enable bursts for congestion control. (10x the per-commit budget) cfg.allowed_txn_cost_overage_burst_per_object_in_commit = Some(185_000_000); } + 72 => { + // Enable new marker table version. + cfg.use_object_per_epoch_marker_table_v2 = Some(true); + } // Use this template when making changes: // // // modify an existing constant. diff --git a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_72.snap b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_72.snap new file mode 100644 index 00000000000000..5af8e945e6d956 --- /dev/null +++ b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_72.snap @@ -0,0 +1,345 @@ +--- +source: crates/sui-protocol-config/src/lib.rs +expression: "ProtocolConfig::get_for_version(cur, *chain_id)" +--- +version: 72 +feature_flags: + package_upgrades: true + commit_root_state_digest: true + advance_epoch_start_time_in_safe_mode: true + loaded_child_objects_fixed: true + missing_type_is_compatibility_error: true + scoring_decision_with_validity_cutoff: true + consensus_order_end_of_epoch_last: true + disallow_adding_abilities_on_upgrade: true + disable_invariant_violation_check_in_swap_loc: true + advance_to_highest_supported_protocol_version: true + ban_entry_init: true + package_digest_hash_module: true + disallow_change_struct_type_params_on_upgrade: true + no_extraneous_module_bytes: true + narwhal_versioned_metadata: true + zklogin_auth: true + consensus_transaction_ordering: ByGasPrice + simplified_unwrap_then_delete: true + upgraded_multisig_supported: true + txn_base_cost_as_multiplier: true + shared_object_deletion: true + narwhal_new_leader_election_schedule: true + loaded_child_object_format: true + enable_jwk_consensus_updates: true + end_of_epoch_transaction_supported: true + simple_conservation_checks: true + loaded_child_object_format_type: true + receive_objects: true + random_beacon: true + bridge: true + enable_effects_v2: true + narwhal_certificate_v2: true + verify_legacy_zklogin_address: true + recompute_has_public_transfer_in_execution: true + accept_zklogin_in_multisig: true + include_consensus_digest_in_prologue: true + hardened_otw_check: true + allow_receiving_object_id: true + enable_coin_deny_list: true + enable_group_ops_native_functions: true + reject_mutable_random_on_entry_functions: true + per_object_congestion_control_mode: TotalGasBudgetWithCap + consensus_choice: Mysticeti + consensus_network: Tonic + zklogin_max_epoch_upper_bound_delta: 30 + mysticeti_leader_scoring_and_schedule: true + reshare_at_same_initial_version: true + resolve_abort_locations_to_package_id: true + mysticeti_use_committed_subdag_digest: true + record_consensus_determined_version_assignments_in_prologue: true + fresh_vm_on_framework_upgrade: true + prepend_prologue_tx_in_consensus_commit_in_checkpoints: true + mysticeti_num_leaders_per_round: 1 + soft_bundle: true + enable_coin_deny_list_v2: true + rethrow_serialization_type_layout_errors: true + consensus_distributed_vote_scoring_strategy: true + consensus_round_prober: true + validate_identifier_inputs: true + relocate_event_module: true + disallow_new_modules_in_deps_only_packages: true + native_charging_v2: true +max_tx_size_bytes: 131072 +max_input_objects: 2048 +max_size_written_objects: 5000000 +max_size_written_objects_system_tx: 50000000 +max_serialized_tx_effects_size_bytes: 524288 +max_serialized_tx_effects_size_bytes_system_tx: 8388608 +max_gas_payment_objects: 256 +max_modules_in_publish: 64 +max_package_dependencies: 32 +max_arguments: 512 +max_type_arguments: 16 +max_type_argument_depth: 16 +max_pure_argument_size: 16384 +max_programmable_tx_commands: 1024 +move_binary_format_version: 7 +min_move_binary_format_version: 6 +binary_module_handles: 100 +binary_struct_handles: 300 +binary_function_handles: 1500 +binary_function_instantiations: 750 +binary_signatures: 1000 +binary_constant_pool: 4000 +binary_identifiers: 10000 +binary_address_identifiers: 100 +binary_struct_defs: 200 +binary_struct_def_instantiations: 100 +binary_function_defs: 1000 +binary_field_handles: 500 +binary_field_instantiations: 250 +binary_friend_decls: 100 +max_move_object_size: 256000 +max_move_package_size: 102400 +max_publish_or_upgrade_per_ptb: 5 +max_tx_gas: 50000000000 +max_gas_price: 100000 +max_gas_computation_bucket: 5000000 +gas_rounding_step: 1000 +max_loop_depth: 5 +max_generic_instantiation_length: 32 +max_function_parameters: 128 +max_basic_blocks: 1024 +max_value_stack_size: 1024 +max_type_nodes: 256 +max_push_size: 10000 +max_struct_definitions: 200 +max_function_definitions: 1000 +max_fields_in_struct: 32 +max_dependency_depth: 100 +max_num_event_emit: 1024 +max_num_new_move_object_ids: 2048 +max_num_new_move_object_ids_system_tx: 32768 +max_num_deleted_move_object_ids: 2048 +max_num_deleted_move_object_ids_system_tx: 32768 +max_num_transferred_move_object_ids: 2048 +max_num_transferred_move_object_ids_system_tx: 32768 +max_event_emit_size: 256000 +max_event_emit_size_total: 65536000 +max_move_vector_len: 262144 +max_move_identifier_len: 128 +max_move_value_depth: 128 +max_back_edges_per_function: 10000 +max_back_edges_per_module: 10000 +max_verifier_meter_ticks_per_function: 16000000 +max_meter_ticks_per_module: 16000000 +max_meter_ticks_per_package: 16000000 +object_runtime_max_num_cached_objects: 1000 +object_runtime_max_num_cached_objects_system_tx: 16000 +object_runtime_max_num_store_entries: 1000 +object_runtime_max_num_store_entries_system_tx: 16000 +base_tx_cost_fixed: 1000 +package_publish_cost_fixed: 1000 +base_tx_cost_per_byte: 0 +package_publish_cost_per_byte: 80 +obj_access_cost_read_per_byte: 15 +obj_access_cost_mutate_per_byte: 40 +obj_access_cost_delete_per_byte: 40 +obj_access_cost_verify_per_byte: 200 +max_type_to_layout_nodes: 512 +gas_model_version: 9 +obj_data_cost_refundable: 100 +obj_metadata_cost_non_refundable: 50 +storage_rebate_rate: 9900 +storage_fund_reinvest_rate: 500 +reward_slashing_rate: 10000 +storage_gas_price: 76 +max_transactions_per_checkpoint: 10000 +max_checkpoint_size_bytes: 31457280 +buffer_stake_for_protocol_upgrade_bps: 5000 +address_from_bytes_cost_base: 52 +address_to_u256_cost_base: 52 +address_from_u256_cost_base: 52 +config_read_setting_impl_cost_base: 100 +config_read_setting_impl_cost_per_byte: 40 +dynamic_field_hash_type_and_key_cost_base: 100 +dynamic_field_hash_type_and_key_type_cost_per_byte: 2 +dynamic_field_hash_type_and_key_value_cost_per_byte: 2 +dynamic_field_hash_type_and_key_type_tag_cost_per_byte: 2 +dynamic_field_add_child_object_cost_base: 100 +dynamic_field_add_child_object_type_cost_per_byte: 10 +dynamic_field_add_child_object_value_cost_per_byte: 10 +dynamic_field_add_child_object_struct_tag_cost_per_byte: 10 +dynamic_field_borrow_child_object_cost_base: 100 +dynamic_field_borrow_child_object_child_ref_cost_per_byte: 10 +dynamic_field_borrow_child_object_type_cost_per_byte: 10 +dynamic_field_remove_child_object_cost_base: 100 +dynamic_field_remove_child_object_child_cost_per_byte: 2 +dynamic_field_remove_child_object_type_cost_per_byte: 2 +dynamic_field_has_child_object_cost_base: 100 +dynamic_field_has_child_object_with_ty_cost_base: 100 +dynamic_field_has_child_object_with_ty_type_cost_per_byte: 2 +dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: 2 +event_emit_cost_base: 52 +event_emit_value_size_derivation_cost_per_byte: 2 +event_emit_tag_size_derivation_cost_per_byte: 5 +event_emit_output_cost_per_byte: 10 +object_borrow_uid_cost_base: 52 +object_delete_impl_cost_base: 52 +object_record_new_uid_cost_base: 52 +transfer_transfer_internal_cost_base: 52 +transfer_freeze_object_cost_base: 52 +transfer_share_object_cost_base: 52 +transfer_receive_object_cost_base: 52 +tx_context_derive_id_cost_base: 52 +types_is_one_time_witness_cost_base: 52 +types_is_one_time_witness_type_tag_cost_per_byte: 2 +types_is_one_time_witness_type_cost_per_byte: 2 +validator_validate_metadata_cost_base: 20000 +validator_validate_metadata_data_cost_per_byte: 2 +crypto_invalid_arguments_cost: 100 +bls12381_bls12381_min_sig_verify_cost_base: 44064 +bls12381_bls12381_min_sig_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_sig_verify_msg_cost_per_block: 2 +bls12381_bls12381_min_pk_verify_cost_base: 49282 +bls12381_bls12381_min_pk_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_pk_verify_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_keccak256_cost_base: 500 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_sha256_cost_base: 500 +ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_k1_decompress_pubkey_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_cost_base: 1470 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_k1_secp256k1_verify_sha256_cost_base: 1470 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_keccak256_cost_base: 1173 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_sha256_cost_base: 1173 +ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_keccak256_cost_base: 4225 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_sha256_cost_base: 4225 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: 2 +ecvrf_ecvrf_verify_cost_base: 4848 +ecvrf_ecvrf_verify_alpha_string_cost_per_byte: 2 +ecvrf_ecvrf_verify_alpha_string_cost_per_block: 2 +ed25519_ed25519_verify_cost_base: 1802 +ed25519_ed25519_verify_msg_cost_per_byte: 2 +ed25519_ed25519_verify_msg_cost_per_block: 2 +groth16_prepare_verifying_key_bls12381_cost_base: 53838 +groth16_prepare_verifying_key_bn254_cost_base: 82010 +groth16_verify_groth16_proof_internal_bls12381_cost_base: 72090 +groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: 8213 +groth16_verify_groth16_proof_internal_bn254_cost_base: 115502 +groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: 9484 +groth16_verify_groth16_proof_internal_public_input_cost_per_byte: 2 +hash_blake2b256_cost_base: 10 +hash_blake2b256_data_cost_per_byte: 2 +hash_blake2b256_data_cost_per_block: 2 +hash_keccak256_cost_base: 10 +hash_keccak256_data_cost_per_byte: 2 +hash_keccak256_data_cost_per_block: 2 +poseidon_bn254_cost_per_block: 388 +group_ops_bls12381_decode_scalar_cost: 7 +group_ops_bls12381_decode_g1_cost: 2848 +group_ops_bls12381_decode_g2_cost: 3770 +group_ops_bls12381_decode_gt_cost: 3068 +group_ops_bls12381_scalar_add_cost: 10 +group_ops_bls12381_g1_add_cost: 1556 +group_ops_bls12381_g2_add_cost: 3048 +group_ops_bls12381_gt_add_cost: 188 +group_ops_bls12381_scalar_sub_cost: 10 +group_ops_bls12381_g1_sub_cost: 1550 +group_ops_bls12381_g2_sub_cost: 3019 +group_ops_bls12381_gt_sub_cost: 497 +group_ops_bls12381_scalar_mul_cost: 11 +group_ops_bls12381_g1_mul_cost: 4842 +group_ops_bls12381_g2_mul_cost: 9108 +group_ops_bls12381_gt_mul_cost: 27490 +group_ops_bls12381_scalar_div_cost: 91 +group_ops_bls12381_g1_div_cost: 5091 +group_ops_bls12381_g2_div_cost: 9206 +group_ops_bls12381_gt_div_cost: 27804 +group_ops_bls12381_g1_hash_to_base_cost: 2962 +group_ops_bls12381_g2_hash_to_base_cost: 8688 +group_ops_bls12381_g1_hash_to_cost_per_byte: 2 +group_ops_bls12381_g2_hash_to_cost_per_byte: 2 +group_ops_bls12381_g1_msm_base_cost: 62648 +group_ops_bls12381_g2_msm_base_cost: 131192 +group_ops_bls12381_g1_msm_base_cost_per_input: 1333 +group_ops_bls12381_g2_msm_base_cost_per_input: 3216 +group_ops_bls12381_msm_max_len: 32 +group_ops_bls12381_pairing_cost: 26897 +group_ops_bls12381_g1_to_uncompressed_g1_cost: 2099 +group_ops_bls12381_uncompressed_g1_to_g1_cost: 677 +group_ops_bls12381_uncompressed_g1_sum_base_cost: 77 +group_ops_bls12381_uncompressed_g1_sum_cost_per_term: 26 +group_ops_bls12381_uncompressed_g1_sum_max_terms: 1200 +hmac_hmac_sha3_256_cost_base: 52 +hmac_hmac_sha3_256_input_cost_per_byte: 2 +hmac_hmac_sha3_256_input_cost_per_block: 2 +check_zklogin_id_cost_base: 200 +check_zklogin_issuer_cost_base: 200 +bcs_per_byte_serialized_cost: 2 +bcs_legacy_min_output_size_cost: 1 +bcs_failure_cost: 52 +hash_sha2_256_base_cost: 52 +hash_sha2_256_per_byte_cost: 2 +hash_sha2_256_legacy_min_input_len_cost: 1 +hash_sha3_256_base_cost: 52 +hash_sha3_256_per_byte_cost: 2 +hash_sha3_256_legacy_min_input_len_cost: 1 +type_name_get_base_cost: 52 +type_name_get_per_byte_cost: 2 +string_check_utf8_base_cost: 52 +string_check_utf8_per_byte_cost: 2 +string_is_char_boundary_base_cost: 52 +string_sub_string_base_cost: 52 +string_sub_string_per_byte_cost: 2 +string_index_of_base_cost: 52 +string_index_of_per_byte_pattern_cost: 2 +string_index_of_per_byte_searched_cost: 2 +vector_empty_base_cost: 52 +vector_length_base_cost: 52 +vector_push_back_base_cost: 52 +vector_push_back_legacy_per_abstract_memory_unit_cost: 2 +vector_borrow_base_cost: 52 +vector_pop_back_base_cost: 52 +vector_destroy_empty_base_cost: 52 +vector_swap_base_cost: 52 +debug_print_base_cost: 52 +debug_print_stack_trace_base_cost: 52 +execution_version: 3 +consensus_bad_nodes_stake_threshold: 20 +max_jwk_votes_per_validator_per_epoch: 240 +max_age_of_jwk_in_epochs: 1 +random_beacon_reduction_allowed_delta: 800 +random_beacon_reduction_lower_bound: 500 +random_beacon_dkg_timeout_round: 3000 +random_beacon_min_round_interval_ms: 500 +random_beacon_dkg_version: 1 +consensus_max_transaction_size_bytes: 262144 +consensus_max_transactions_in_block_bytes: 524288 +consensus_max_num_transactions_in_block: 512 +consensus_voting_rounds: 40 +max_accumulated_txn_cost_per_object_in_narwhal_commit: 40 +max_deferral_rounds_for_congestion_control: 10 +max_txn_cost_overage_per_object_in_commit: 18446744073709551615 +allowed_txn_cost_overage_burst_per_object_in_commit: 185000000 +min_checkpoint_interval_ms: 200 +checkpoint_summary_version_specific_data: 1 +max_soft_bundle_size: 5 +bridge_should_try_to_finalize_committee: true +max_accumulated_txn_cost_per_object_in_mysticeti_commit: 18500000 +max_accumulated_randomness_txn_cost_per_object_in_mysticeti_commit: 3700000 +gas_budget_based_txn_cost_cap_factor: 400000 +gas_budget_based_txn_cost_absolute_cap_commit_count: 50 +sip_45_consensus_amplification_threshold: 5 +use_object_per_epoch_marker_table_v2: true + diff --git a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_72.snap b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_72.snap new file mode 100644 index 00000000000000..d0e645e6780a93 --- /dev/null +++ b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_72.snap @@ -0,0 +1,348 @@ +--- +source: crates/sui-protocol-config/src/lib.rs +expression: "ProtocolConfig::get_for_version(cur, *chain_id)" +--- +version: 72 +feature_flags: + package_upgrades: true + commit_root_state_digest: true + advance_epoch_start_time_in_safe_mode: true + loaded_child_objects_fixed: true + missing_type_is_compatibility_error: true + scoring_decision_with_validity_cutoff: true + consensus_order_end_of_epoch_last: true + disallow_adding_abilities_on_upgrade: true + disable_invariant_violation_check_in_swap_loc: true + advance_to_highest_supported_protocol_version: true + ban_entry_init: true + package_digest_hash_module: true + disallow_change_struct_type_params_on_upgrade: true + no_extraneous_module_bytes: true + narwhal_versioned_metadata: true + zklogin_auth: true + consensus_transaction_ordering: ByGasPrice + simplified_unwrap_then_delete: true + upgraded_multisig_supported: true + txn_base_cost_as_multiplier: true + shared_object_deletion: true + narwhal_new_leader_election_schedule: true + loaded_child_object_format: true + enable_jwk_consensus_updates: true + end_of_epoch_transaction_supported: true + simple_conservation_checks: true + loaded_child_object_format_type: true + receive_objects: true + random_beacon: true + bridge: true + enable_effects_v2: true + narwhal_certificate_v2: true + verify_legacy_zklogin_address: true + recompute_has_public_transfer_in_execution: true + accept_zklogin_in_multisig: true + include_consensus_digest_in_prologue: true + hardened_otw_check: true + allow_receiving_object_id: true + enable_coin_deny_list: true + enable_group_ops_native_functions: true + reject_mutable_random_on_entry_functions: true + per_object_congestion_control_mode: TotalGasBudgetWithCap + consensus_choice: Mysticeti + consensus_network: Tonic + zklogin_max_epoch_upper_bound_delta: 30 + mysticeti_leader_scoring_and_schedule: true + reshare_at_same_initial_version: true + resolve_abort_locations_to_package_id: true + mysticeti_use_committed_subdag_digest: true + record_consensus_determined_version_assignments_in_prologue: true + fresh_vm_on_framework_upgrade: true + prepend_prologue_tx_in_consensus_commit_in_checkpoints: true + mysticeti_num_leaders_per_round: 1 + soft_bundle: true + enable_coin_deny_list_v2: true + rethrow_serialization_type_layout_errors: true + consensus_distributed_vote_scoring_strategy: true + consensus_round_prober: true + validate_identifier_inputs: true + relocate_event_module: true + uncompressed_g1_group_elements: true + disallow_new_modules_in_deps_only_packages: true + consensus_smart_ancestor_selection: true + consensus_round_prober_probe_accepted_rounds: true + native_charging_v2: true +max_tx_size_bytes: 131072 +max_input_objects: 2048 +max_size_written_objects: 5000000 +max_size_written_objects_system_tx: 50000000 +max_serialized_tx_effects_size_bytes: 524288 +max_serialized_tx_effects_size_bytes_system_tx: 8388608 +max_gas_payment_objects: 256 +max_modules_in_publish: 64 +max_package_dependencies: 32 +max_arguments: 512 +max_type_arguments: 16 +max_type_argument_depth: 16 +max_pure_argument_size: 16384 +max_programmable_tx_commands: 1024 +move_binary_format_version: 7 +min_move_binary_format_version: 6 +binary_module_handles: 100 +binary_struct_handles: 300 +binary_function_handles: 1500 +binary_function_instantiations: 750 +binary_signatures: 1000 +binary_constant_pool: 4000 +binary_identifiers: 10000 +binary_address_identifiers: 100 +binary_struct_defs: 200 +binary_struct_def_instantiations: 100 +binary_function_defs: 1000 +binary_field_handles: 500 +binary_field_instantiations: 250 +binary_friend_decls: 100 +max_move_object_size: 256000 +max_move_package_size: 102400 +max_publish_or_upgrade_per_ptb: 5 +max_tx_gas: 50000000000 +max_gas_price: 100000 +max_gas_computation_bucket: 5000000 +gas_rounding_step: 1000 +max_loop_depth: 5 +max_generic_instantiation_length: 32 +max_function_parameters: 128 +max_basic_blocks: 1024 +max_value_stack_size: 1024 +max_type_nodes: 256 +max_push_size: 10000 +max_struct_definitions: 200 +max_function_definitions: 1000 +max_fields_in_struct: 32 +max_dependency_depth: 100 +max_num_event_emit: 1024 +max_num_new_move_object_ids: 2048 +max_num_new_move_object_ids_system_tx: 32768 +max_num_deleted_move_object_ids: 2048 +max_num_deleted_move_object_ids_system_tx: 32768 +max_num_transferred_move_object_ids: 2048 +max_num_transferred_move_object_ids_system_tx: 32768 +max_event_emit_size: 256000 +max_event_emit_size_total: 65536000 +max_move_vector_len: 262144 +max_move_identifier_len: 128 +max_move_value_depth: 128 +max_back_edges_per_function: 10000 +max_back_edges_per_module: 10000 +max_verifier_meter_ticks_per_function: 16000000 +max_meter_ticks_per_module: 16000000 +max_meter_ticks_per_package: 16000000 +object_runtime_max_num_cached_objects: 1000 +object_runtime_max_num_cached_objects_system_tx: 16000 +object_runtime_max_num_store_entries: 1000 +object_runtime_max_num_store_entries_system_tx: 16000 +base_tx_cost_fixed: 1000 +package_publish_cost_fixed: 1000 +base_tx_cost_per_byte: 0 +package_publish_cost_per_byte: 80 +obj_access_cost_read_per_byte: 15 +obj_access_cost_mutate_per_byte: 40 +obj_access_cost_delete_per_byte: 40 +obj_access_cost_verify_per_byte: 200 +max_type_to_layout_nodes: 512 +gas_model_version: 9 +obj_data_cost_refundable: 100 +obj_metadata_cost_non_refundable: 50 +storage_rebate_rate: 9900 +storage_fund_reinvest_rate: 500 +reward_slashing_rate: 10000 +storage_gas_price: 76 +max_transactions_per_checkpoint: 10000 +max_checkpoint_size_bytes: 31457280 +buffer_stake_for_protocol_upgrade_bps: 5000 +address_from_bytes_cost_base: 52 +address_to_u256_cost_base: 52 +address_from_u256_cost_base: 52 +config_read_setting_impl_cost_base: 100 +config_read_setting_impl_cost_per_byte: 40 +dynamic_field_hash_type_and_key_cost_base: 100 +dynamic_field_hash_type_and_key_type_cost_per_byte: 2 +dynamic_field_hash_type_and_key_value_cost_per_byte: 2 +dynamic_field_hash_type_and_key_type_tag_cost_per_byte: 2 +dynamic_field_add_child_object_cost_base: 100 +dynamic_field_add_child_object_type_cost_per_byte: 10 +dynamic_field_add_child_object_value_cost_per_byte: 10 +dynamic_field_add_child_object_struct_tag_cost_per_byte: 10 +dynamic_field_borrow_child_object_cost_base: 100 +dynamic_field_borrow_child_object_child_ref_cost_per_byte: 10 +dynamic_field_borrow_child_object_type_cost_per_byte: 10 +dynamic_field_remove_child_object_cost_base: 100 +dynamic_field_remove_child_object_child_cost_per_byte: 2 +dynamic_field_remove_child_object_type_cost_per_byte: 2 +dynamic_field_has_child_object_cost_base: 100 +dynamic_field_has_child_object_with_ty_cost_base: 100 +dynamic_field_has_child_object_with_ty_type_cost_per_byte: 2 +dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: 2 +event_emit_cost_base: 52 +event_emit_value_size_derivation_cost_per_byte: 2 +event_emit_tag_size_derivation_cost_per_byte: 5 +event_emit_output_cost_per_byte: 10 +object_borrow_uid_cost_base: 52 +object_delete_impl_cost_base: 52 +object_record_new_uid_cost_base: 52 +transfer_transfer_internal_cost_base: 52 +transfer_freeze_object_cost_base: 52 +transfer_share_object_cost_base: 52 +transfer_receive_object_cost_base: 52 +tx_context_derive_id_cost_base: 52 +types_is_one_time_witness_cost_base: 52 +types_is_one_time_witness_type_tag_cost_per_byte: 2 +types_is_one_time_witness_type_cost_per_byte: 2 +validator_validate_metadata_cost_base: 20000 +validator_validate_metadata_data_cost_per_byte: 2 +crypto_invalid_arguments_cost: 100 +bls12381_bls12381_min_sig_verify_cost_base: 44064 +bls12381_bls12381_min_sig_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_sig_verify_msg_cost_per_block: 2 +bls12381_bls12381_min_pk_verify_cost_base: 49282 +bls12381_bls12381_min_pk_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_pk_verify_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_keccak256_cost_base: 500 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_sha256_cost_base: 500 +ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_k1_decompress_pubkey_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_cost_base: 1470 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_k1_secp256k1_verify_sha256_cost_base: 1470 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_keccak256_cost_base: 1173 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_sha256_cost_base: 1173 +ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_keccak256_cost_base: 4225 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_sha256_cost_base: 4225 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: 2 +ecvrf_ecvrf_verify_cost_base: 4848 +ecvrf_ecvrf_verify_alpha_string_cost_per_byte: 2 +ecvrf_ecvrf_verify_alpha_string_cost_per_block: 2 +ed25519_ed25519_verify_cost_base: 1802 +ed25519_ed25519_verify_msg_cost_per_byte: 2 +ed25519_ed25519_verify_msg_cost_per_block: 2 +groth16_prepare_verifying_key_bls12381_cost_base: 53838 +groth16_prepare_verifying_key_bn254_cost_base: 82010 +groth16_verify_groth16_proof_internal_bls12381_cost_base: 72090 +groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: 8213 +groth16_verify_groth16_proof_internal_bn254_cost_base: 115502 +groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: 9484 +groth16_verify_groth16_proof_internal_public_input_cost_per_byte: 2 +hash_blake2b256_cost_base: 10 +hash_blake2b256_data_cost_per_byte: 2 +hash_blake2b256_data_cost_per_block: 2 +hash_keccak256_cost_base: 10 +hash_keccak256_data_cost_per_byte: 2 +hash_keccak256_data_cost_per_block: 2 +poseidon_bn254_cost_per_block: 388 +group_ops_bls12381_decode_scalar_cost: 7 +group_ops_bls12381_decode_g1_cost: 2848 +group_ops_bls12381_decode_g2_cost: 3770 +group_ops_bls12381_decode_gt_cost: 3068 +group_ops_bls12381_scalar_add_cost: 10 +group_ops_bls12381_g1_add_cost: 1556 +group_ops_bls12381_g2_add_cost: 3048 +group_ops_bls12381_gt_add_cost: 188 +group_ops_bls12381_scalar_sub_cost: 10 +group_ops_bls12381_g1_sub_cost: 1550 +group_ops_bls12381_g2_sub_cost: 3019 +group_ops_bls12381_gt_sub_cost: 497 +group_ops_bls12381_scalar_mul_cost: 11 +group_ops_bls12381_g1_mul_cost: 4842 +group_ops_bls12381_g2_mul_cost: 9108 +group_ops_bls12381_gt_mul_cost: 27490 +group_ops_bls12381_scalar_div_cost: 91 +group_ops_bls12381_g1_div_cost: 5091 +group_ops_bls12381_g2_div_cost: 9206 +group_ops_bls12381_gt_div_cost: 27804 +group_ops_bls12381_g1_hash_to_base_cost: 2962 +group_ops_bls12381_g2_hash_to_base_cost: 8688 +group_ops_bls12381_g1_hash_to_cost_per_byte: 2 +group_ops_bls12381_g2_hash_to_cost_per_byte: 2 +group_ops_bls12381_g1_msm_base_cost: 62648 +group_ops_bls12381_g2_msm_base_cost: 131192 +group_ops_bls12381_g1_msm_base_cost_per_input: 1333 +group_ops_bls12381_g2_msm_base_cost_per_input: 3216 +group_ops_bls12381_msm_max_len: 32 +group_ops_bls12381_pairing_cost: 26897 +group_ops_bls12381_g1_to_uncompressed_g1_cost: 2099 +group_ops_bls12381_uncompressed_g1_to_g1_cost: 677 +group_ops_bls12381_uncompressed_g1_sum_base_cost: 77 +group_ops_bls12381_uncompressed_g1_sum_cost_per_term: 26 +group_ops_bls12381_uncompressed_g1_sum_max_terms: 1200 +hmac_hmac_sha3_256_cost_base: 52 +hmac_hmac_sha3_256_input_cost_per_byte: 2 +hmac_hmac_sha3_256_input_cost_per_block: 2 +check_zklogin_id_cost_base: 200 +check_zklogin_issuer_cost_base: 200 +bcs_per_byte_serialized_cost: 2 +bcs_legacy_min_output_size_cost: 1 +bcs_failure_cost: 52 +hash_sha2_256_base_cost: 52 +hash_sha2_256_per_byte_cost: 2 +hash_sha2_256_legacy_min_input_len_cost: 1 +hash_sha3_256_base_cost: 52 +hash_sha3_256_per_byte_cost: 2 +hash_sha3_256_legacy_min_input_len_cost: 1 +type_name_get_base_cost: 52 +type_name_get_per_byte_cost: 2 +string_check_utf8_base_cost: 52 +string_check_utf8_per_byte_cost: 2 +string_is_char_boundary_base_cost: 52 +string_sub_string_base_cost: 52 +string_sub_string_per_byte_cost: 2 +string_index_of_base_cost: 52 +string_index_of_per_byte_pattern_cost: 2 +string_index_of_per_byte_searched_cost: 2 +vector_empty_base_cost: 52 +vector_length_base_cost: 52 +vector_push_back_base_cost: 52 +vector_push_back_legacy_per_abstract_memory_unit_cost: 2 +vector_borrow_base_cost: 52 +vector_pop_back_base_cost: 52 +vector_destroy_empty_base_cost: 52 +vector_swap_base_cost: 52 +debug_print_base_cost: 52 +debug_print_stack_trace_base_cost: 52 +execution_version: 3 +consensus_bad_nodes_stake_threshold: 20 +max_jwk_votes_per_validator_per_epoch: 240 +max_age_of_jwk_in_epochs: 1 +random_beacon_reduction_allowed_delta: 800 +random_beacon_reduction_lower_bound: 500 +random_beacon_dkg_timeout_round: 3000 +random_beacon_min_round_interval_ms: 500 +random_beacon_dkg_version: 1 +consensus_max_transaction_size_bytes: 262144 +consensus_max_transactions_in_block_bytes: 524288 +consensus_max_num_transactions_in_block: 512 +consensus_voting_rounds: 40 +max_accumulated_txn_cost_per_object_in_narwhal_commit: 40 +max_deferral_rounds_for_congestion_control: 10 +max_txn_cost_overage_per_object_in_commit: 18446744073709551615 +allowed_txn_cost_overage_burst_per_object_in_commit: 185000000 +min_checkpoint_interval_ms: 200 +checkpoint_summary_version_specific_data: 1 +max_soft_bundle_size: 5 +bridge_should_try_to_finalize_committee: true +max_accumulated_txn_cost_per_object_in_mysticeti_commit: 18500000 +max_accumulated_randomness_txn_cost_per_object_in_mysticeti_commit: 3700000 +gas_budget_based_txn_cost_cap_factor: 400000 +gas_budget_based_txn_cost_absolute_cap_commit_count: 50 +sip_45_consensus_amplification_threshold: 5 +use_object_per_epoch_marker_table_v2: true + diff --git a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_72.snap b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_72.snap new file mode 100644 index 00000000000000..ca2f250ef8adf8 --- /dev/null +++ b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_72.snap @@ -0,0 +1,357 @@ +--- +source: crates/sui-protocol-config/src/lib.rs +expression: "ProtocolConfig::get_for_version(cur, *chain_id)" +--- +version: 72 +feature_flags: + package_upgrades: true + commit_root_state_digest: true + advance_epoch_start_time_in_safe_mode: true + loaded_child_objects_fixed: true + missing_type_is_compatibility_error: true + scoring_decision_with_validity_cutoff: true + consensus_order_end_of_epoch_last: true + disallow_adding_abilities_on_upgrade: true + disable_invariant_violation_check_in_swap_loc: true + advance_to_highest_supported_protocol_version: true + ban_entry_init: true + package_digest_hash_module: true + disallow_change_struct_type_params_on_upgrade: true + no_extraneous_module_bytes: true + narwhal_versioned_metadata: true + zklogin_auth: true + consensus_transaction_ordering: ByGasPrice + simplified_unwrap_then_delete: true + upgraded_multisig_supported: true + txn_base_cost_as_multiplier: true + shared_object_deletion: true + narwhal_new_leader_election_schedule: true + loaded_child_object_format: true + enable_jwk_consensus_updates: true + end_of_epoch_transaction_supported: true + simple_conservation_checks: true + loaded_child_object_format_type: true + receive_objects: true + random_beacon: true + bridge: true + enable_effects_v2: true + narwhal_certificate_v2: true + verify_legacy_zklogin_address: true + recompute_has_public_transfer_in_execution: true + accept_zklogin_in_multisig: true + include_consensus_digest_in_prologue: true + hardened_otw_check: true + allow_receiving_object_id: true + enable_poseidon: true + enable_coin_deny_list: true + enable_group_ops_native_functions: true + enable_group_ops_native_function_msm: true + reject_mutable_random_on_entry_functions: true + per_object_congestion_control_mode: TotalGasBudgetWithCap + consensus_choice: Mysticeti + consensus_network: Tonic + zklogin_max_epoch_upper_bound_delta: 30 + mysticeti_leader_scoring_and_schedule: true + reshare_at_same_initial_version: true + resolve_abort_locations_to_package_id: true + mysticeti_use_committed_subdag_digest: true + enable_vdf: true + record_consensus_determined_version_assignments_in_prologue: true + fresh_vm_on_framework_upgrade: true + prepend_prologue_tx_in_consensus_commit_in_checkpoints: true + mysticeti_num_leaders_per_round: 1 + soft_bundle: true + enable_coin_deny_list_v2: true + passkey_auth: true + authority_capabilities_v2: true + rethrow_serialization_type_layout_errors: true + consensus_distributed_vote_scoring_strategy: true + consensus_round_prober: true + validate_identifier_inputs: true + mysticeti_fastpath: true + relocate_event_module: true + uncompressed_g1_group_elements: true + disallow_new_modules_in_deps_only_packages: true + consensus_smart_ancestor_selection: true + consensus_round_prober_probe_accepted_rounds: true + native_charging_v2: true +max_tx_size_bytes: 131072 +max_input_objects: 2048 +max_size_written_objects: 5000000 +max_size_written_objects_system_tx: 50000000 +max_serialized_tx_effects_size_bytes: 524288 +max_serialized_tx_effects_size_bytes_system_tx: 8388608 +max_gas_payment_objects: 256 +max_modules_in_publish: 64 +max_package_dependencies: 32 +max_arguments: 512 +max_type_arguments: 16 +max_type_argument_depth: 16 +max_pure_argument_size: 16384 +max_programmable_tx_commands: 1024 +move_binary_format_version: 7 +min_move_binary_format_version: 6 +binary_module_handles: 100 +binary_struct_handles: 300 +binary_function_handles: 1500 +binary_function_instantiations: 750 +binary_signatures: 1000 +binary_constant_pool: 4000 +binary_identifiers: 10000 +binary_address_identifiers: 100 +binary_struct_defs: 200 +binary_struct_def_instantiations: 100 +binary_function_defs: 1000 +binary_field_handles: 500 +binary_field_instantiations: 250 +binary_friend_decls: 100 +max_move_object_size: 256000 +max_move_package_size: 102400 +max_publish_or_upgrade_per_ptb: 5 +max_tx_gas: 50000000000 +max_gas_price: 100000 +max_gas_computation_bucket: 5000000 +gas_rounding_step: 1000 +max_loop_depth: 5 +max_generic_instantiation_length: 32 +max_function_parameters: 128 +max_basic_blocks: 1024 +max_value_stack_size: 1024 +max_type_nodes: 256 +max_push_size: 10000 +max_struct_definitions: 200 +max_function_definitions: 1000 +max_fields_in_struct: 32 +max_dependency_depth: 100 +max_num_event_emit: 1024 +max_num_new_move_object_ids: 2048 +max_num_new_move_object_ids_system_tx: 32768 +max_num_deleted_move_object_ids: 2048 +max_num_deleted_move_object_ids_system_tx: 32768 +max_num_transferred_move_object_ids: 2048 +max_num_transferred_move_object_ids_system_tx: 32768 +max_event_emit_size: 256000 +max_event_emit_size_total: 65536000 +max_move_vector_len: 262144 +max_move_identifier_len: 128 +max_move_value_depth: 128 +max_back_edges_per_function: 10000 +max_back_edges_per_module: 10000 +max_verifier_meter_ticks_per_function: 16000000 +max_meter_ticks_per_module: 16000000 +max_meter_ticks_per_package: 16000000 +object_runtime_max_num_cached_objects: 1000 +object_runtime_max_num_cached_objects_system_tx: 16000 +object_runtime_max_num_store_entries: 1000 +object_runtime_max_num_store_entries_system_tx: 16000 +base_tx_cost_fixed: 1000 +package_publish_cost_fixed: 1000 +base_tx_cost_per_byte: 0 +package_publish_cost_per_byte: 80 +obj_access_cost_read_per_byte: 15 +obj_access_cost_mutate_per_byte: 40 +obj_access_cost_delete_per_byte: 40 +obj_access_cost_verify_per_byte: 200 +max_type_to_layout_nodes: 512 +gas_model_version: 9 +obj_data_cost_refundable: 100 +obj_metadata_cost_non_refundable: 50 +storage_rebate_rate: 9900 +storage_fund_reinvest_rate: 500 +reward_slashing_rate: 10000 +storage_gas_price: 76 +max_transactions_per_checkpoint: 10000 +max_checkpoint_size_bytes: 31457280 +buffer_stake_for_protocol_upgrade_bps: 5000 +address_from_bytes_cost_base: 52 +address_to_u256_cost_base: 52 +address_from_u256_cost_base: 52 +config_read_setting_impl_cost_base: 100 +config_read_setting_impl_cost_per_byte: 40 +dynamic_field_hash_type_and_key_cost_base: 100 +dynamic_field_hash_type_and_key_type_cost_per_byte: 2 +dynamic_field_hash_type_and_key_value_cost_per_byte: 2 +dynamic_field_hash_type_and_key_type_tag_cost_per_byte: 2 +dynamic_field_add_child_object_cost_base: 100 +dynamic_field_add_child_object_type_cost_per_byte: 10 +dynamic_field_add_child_object_value_cost_per_byte: 10 +dynamic_field_add_child_object_struct_tag_cost_per_byte: 10 +dynamic_field_borrow_child_object_cost_base: 100 +dynamic_field_borrow_child_object_child_ref_cost_per_byte: 10 +dynamic_field_borrow_child_object_type_cost_per_byte: 10 +dynamic_field_remove_child_object_cost_base: 100 +dynamic_field_remove_child_object_child_cost_per_byte: 2 +dynamic_field_remove_child_object_type_cost_per_byte: 2 +dynamic_field_has_child_object_cost_base: 100 +dynamic_field_has_child_object_with_ty_cost_base: 100 +dynamic_field_has_child_object_with_ty_type_cost_per_byte: 2 +dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: 2 +event_emit_cost_base: 52 +event_emit_value_size_derivation_cost_per_byte: 2 +event_emit_tag_size_derivation_cost_per_byte: 5 +event_emit_output_cost_per_byte: 10 +object_borrow_uid_cost_base: 52 +object_delete_impl_cost_base: 52 +object_record_new_uid_cost_base: 52 +transfer_transfer_internal_cost_base: 52 +transfer_freeze_object_cost_base: 52 +transfer_share_object_cost_base: 52 +transfer_receive_object_cost_base: 52 +tx_context_derive_id_cost_base: 52 +types_is_one_time_witness_cost_base: 52 +types_is_one_time_witness_type_tag_cost_per_byte: 2 +types_is_one_time_witness_type_cost_per_byte: 2 +validator_validate_metadata_cost_base: 20000 +validator_validate_metadata_data_cost_per_byte: 2 +crypto_invalid_arguments_cost: 100 +bls12381_bls12381_min_sig_verify_cost_base: 44064 +bls12381_bls12381_min_sig_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_sig_verify_msg_cost_per_block: 2 +bls12381_bls12381_min_pk_verify_cost_base: 49282 +bls12381_bls12381_min_pk_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_pk_verify_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_keccak256_cost_base: 500 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_sha256_cost_base: 500 +ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_k1_decompress_pubkey_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_cost_base: 1470 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_k1_secp256k1_verify_sha256_cost_base: 1470 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_keccak256_cost_base: 1173 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_sha256_cost_base: 1173 +ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_keccak256_cost_base: 4225 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_sha256_cost_base: 4225 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: 2 +ecvrf_ecvrf_verify_cost_base: 4848 +ecvrf_ecvrf_verify_alpha_string_cost_per_byte: 2 +ecvrf_ecvrf_verify_alpha_string_cost_per_block: 2 +ed25519_ed25519_verify_cost_base: 1802 +ed25519_ed25519_verify_msg_cost_per_byte: 2 +ed25519_ed25519_verify_msg_cost_per_block: 2 +groth16_prepare_verifying_key_bls12381_cost_base: 53838 +groth16_prepare_verifying_key_bn254_cost_base: 82010 +groth16_verify_groth16_proof_internal_bls12381_cost_base: 72090 +groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: 8213 +groth16_verify_groth16_proof_internal_bn254_cost_base: 115502 +groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: 9484 +groth16_verify_groth16_proof_internal_public_input_cost_per_byte: 2 +hash_blake2b256_cost_base: 10 +hash_blake2b256_data_cost_per_byte: 2 +hash_blake2b256_data_cost_per_block: 2 +hash_keccak256_cost_base: 10 +hash_keccak256_data_cost_per_byte: 2 +hash_keccak256_data_cost_per_block: 2 +poseidon_bn254_cost_base: 260 +poseidon_bn254_cost_per_block: 388 +group_ops_bls12381_decode_scalar_cost: 7 +group_ops_bls12381_decode_g1_cost: 2848 +group_ops_bls12381_decode_g2_cost: 3770 +group_ops_bls12381_decode_gt_cost: 3068 +group_ops_bls12381_scalar_add_cost: 10 +group_ops_bls12381_g1_add_cost: 1556 +group_ops_bls12381_g2_add_cost: 3048 +group_ops_bls12381_gt_add_cost: 188 +group_ops_bls12381_scalar_sub_cost: 10 +group_ops_bls12381_g1_sub_cost: 1550 +group_ops_bls12381_g2_sub_cost: 3019 +group_ops_bls12381_gt_sub_cost: 497 +group_ops_bls12381_scalar_mul_cost: 11 +group_ops_bls12381_g1_mul_cost: 4842 +group_ops_bls12381_g2_mul_cost: 9108 +group_ops_bls12381_gt_mul_cost: 27490 +group_ops_bls12381_scalar_div_cost: 91 +group_ops_bls12381_g1_div_cost: 5091 +group_ops_bls12381_g2_div_cost: 9206 +group_ops_bls12381_gt_div_cost: 27804 +group_ops_bls12381_g1_hash_to_base_cost: 2962 +group_ops_bls12381_g2_hash_to_base_cost: 8688 +group_ops_bls12381_g1_hash_to_cost_per_byte: 2 +group_ops_bls12381_g2_hash_to_cost_per_byte: 2 +group_ops_bls12381_g1_msm_base_cost: 62648 +group_ops_bls12381_g2_msm_base_cost: 131192 +group_ops_bls12381_g1_msm_base_cost_per_input: 1333 +group_ops_bls12381_g2_msm_base_cost_per_input: 3216 +group_ops_bls12381_msm_max_len: 32 +group_ops_bls12381_pairing_cost: 26897 +group_ops_bls12381_g1_to_uncompressed_g1_cost: 2099 +group_ops_bls12381_uncompressed_g1_to_g1_cost: 677 +group_ops_bls12381_uncompressed_g1_sum_base_cost: 77 +group_ops_bls12381_uncompressed_g1_sum_cost_per_term: 26 +group_ops_bls12381_uncompressed_g1_sum_max_terms: 1200 +hmac_hmac_sha3_256_cost_base: 52 +hmac_hmac_sha3_256_input_cost_per_byte: 2 +hmac_hmac_sha3_256_input_cost_per_block: 2 +check_zklogin_id_cost_base: 200 +check_zklogin_issuer_cost_base: 200 +vdf_verify_vdf_cost: 1500 +vdf_hash_to_input_cost: 100 +bcs_per_byte_serialized_cost: 2 +bcs_legacy_min_output_size_cost: 1 +bcs_failure_cost: 52 +hash_sha2_256_base_cost: 52 +hash_sha2_256_per_byte_cost: 2 +hash_sha2_256_legacy_min_input_len_cost: 1 +hash_sha3_256_base_cost: 52 +hash_sha3_256_per_byte_cost: 2 +hash_sha3_256_legacy_min_input_len_cost: 1 +type_name_get_base_cost: 52 +type_name_get_per_byte_cost: 2 +string_check_utf8_base_cost: 52 +string_check_utf8_per_byte_cost: 2 +string_is_char_boundary_base_cost: 52 +string_sub_string_base_cost: 52 +string_sub_string_per_byte_cost: 2 +string_index_of_base_cost: 52 +string_index_of_per_byte_pattern_cost: 2 +string_index_of_per_byte_searched_cost: 2 +vector_empty_base_cost: 52 +vector_length_base_cost: 52 +vector_push_back_base_cost: 52 +vector_push_back_legacy_per_abstract_memory_unit_cost: 2 +vector_borrow_base_cost: 52 +vector_pop_back_base_cost: 52 +vector_destroy_empty_base_cost: 52 +vector_swap_base_cost: 52 +debug_print_base_cost: 52 +debug_print_stack_trace_base_cost: 52 +execution_version: 3 +consensus_bad_nodes_stake_threshold: 20 +max_jwk_votes_per_validator_per_epoch: 240 +max_age_of_jwk_in_epochs: 1 +random_beacon_reduction_allowed_delta: 800 +random_beacon_reduction_lower_bound: 500 +random_beacon_dkg_timeout_round: 3000 +random_beacon_min_round_interval_ms: 500 +random_beacon_dkg_version: 1 +consensus_max_transaction_size_bytes: 262144 +consensus_max_transactions_in_block_bytes: 524288 +consensus_max_num_transactions_in_block: 512 +consensus_voting_rounds: 40 +max_accumulated_txn_cost_per_object_in_narwhal_commit: 40 +max_deferral_rounds_for_congestion_control: 10 +max_txn_cost_overage_per_object_in_commit: 18446744073709551615 +allowed_txn_cost_overage_burst_per_object_in_commit: 185000000 +min_checkpoint_interval_ms: 200 +checkpoint_summary_version_specific_data: 1 +max_soft_bundle_size: 5 +bridge_should_try_to_finalize_committee: true +max_accumulated_txn_cost_per_object_in_mysticeti_commit: 18500000 +max_accumulated_randomness_txn_cost_per_object_in_mysticeti_commit: 3700000 +gas_budget_based_txn_cost_cap_factor: 400000 +gas_budget_based_txn_cost_absolute_cap_commit_count: 50 +sip_45_consensus_amplification_threshold: 5 +use_object_per_epoch_marker_table_v2: true + diff --git a/crates/sui-replay/src/replay.rs b/crates/sui-replay/src/replay.rs index e3b22d539ec32d..f19fa0e069dde6 100644 --- a/crates/sui-replay/src/replay.rs +++ b/crates/sui-replay/src/replay.rs @@ -1907,6 +1907,8 @@ impl ChildObjectResolver for LocalExec { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, _epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { fn inner( self_: &LocalExec, diff --git a/crates/sui-single-node-benchmark/src/benchmark_context.rs b/crates/sui-single-node-benchmark/src/benchmark_context.rs index 574b0d675bfb51..266c64b7bef676 100644 --- a/crates/sui-single-node-benchmark/src/benchmark_context.rs +++ b/crates/sui-single-node-benchmark/src/benchmark_context.rs @@ -117,6 +117,7 @@ impl BenchmarkContext { .commit_transaction_outputs( effects.executed_epoch(), &[*effects.transaction_digest()], + true, ) .await; let (owner, root_object) = effects @@ -187,7 +188,7 @@ impl BenchmarkContext { // For checkpoint executor, in order to commit a checkpoint it is required previous versions // of objects are already committed. cache_commit - .commit_transaction_outputs(epoch_id, &[*effects.transaction_digest()]) + .commit_transaction_outputs(epoch_id, &[*effects.transaction_digest()], true) .await; } self.refresh_gas_objects(new_gas_objects); diff --git a/crates/sui-single-node-benchmark/src/mock_storage.rs b/crates/sui-single-node-benchmark/src/mock_storage.rs index f16c3acb8675e6..0ce7b8db795471 100644 --- a/crates/sui-single-node-benchmark/src/mock_storage.rs +++ b/crates/sui-single-node-benchmark/src/mock_storage.rs @@ -162,6 +162,8 @@ impl ChildObjectResolver for InMemoryObjectStore { _receiving_object_id: &ObjectID, _receive_object_at_version: SequenceNumber, _epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { unimplemented!() } diff --git a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__genesis_config_snapshot_matches.snap b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__genesis_config_snapshot_matches.snap index c0f72853b5f6b4..928f7c71250784 100644 --- a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__genesis_config_snapshot_matches.snap +++ b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__genesis_config_snapshot_matches.snap @@ -6,7 +6,7 @@ ssfn_config_info: ~ validator_config_info: ~ parameters: chain_start_timestamp_ms: 0 - protocol_version: 71 + protocol_version: 72 allow_insertion_of_extra_objects: true epoch_duration_ms: 86400000 stake_subsidy_start_epoch: 0 @@ -49,3 +49,4 @@ accounts: - 30000000000000000 - 30000000000000000 - 30000000000000000 + diff --git a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap index 3fa9e4e3330b70..4b150ff1097249 100644 --- a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap +++ b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap @@ -3,7 +3,7 @@ source: crates/sui-swarm-config/tests/snapshot_tests.rs expression: genesis.sui_system_object().into_genesis_version_for_tooling() --- epoch: 0 -protocol_version: 71 +protocol_version: 72 system_state_version: 1 validators: total_stake: 20000000000000000 @@ -240,13 +240,13 @@ validators: next_epoch_worker_address: ~ extra_fields: id: - id: "0xcd6cf436267d64b2b5ba20c633881d1a6c7b6a9b006e8c93838e6e912da3b64b" + id: "0xe1736cf478d38b4e97ac9cff325aedd9d71c156d43cf1e49a821a8b20dfe877a" size: 0 voting_power: 10000 - operation_cap_id: "0x92be09c8cf0a9e736a39695425de68e60aab91363695c30237efa54fc8f10b0b" + operation_cap_id: "0x92ca0c15c751ed16f4ba61cf7a2561bcdacea7c14ff8734bb187c305bee96176" gas_price: 1000 staking_pool: - id: "0x5b08312cc36eb96d4ac2abb863f58c4ac610944e31a70c631e8dac5025ff3d96" + id: "0x65826f03944fd73127bd792daed69eddbc1ddc147f8c99da50324c64a90df0e0" activation_epoch: 0 deactivation_epoch: ~ sui_balance: 20000000000000000 @@ -254,14 +254,14 @@ validators: value: 0 pool_token_balance: 20000000000000000 exchange_rates: - id: "0xf5ea2d403686a71778606c202944e3ece8834fd694b4d416ded5e2571c043d1f" + id: "0xae8b647a4c501c2b62396ff783139eb9d60594dcdb68f8b53aa6e612fde7ad55" size: 1 pending_stake: 0 pending_total_sui_withdraw: 0 pending_pool_token_withdraw: 0 extra_fields: id: - id: "0xf93072985e12f9464c80f005a37b485e0e286760593b5f467e7e2fe0bfec362e" + id: "0x9074457c10ce082304550f2edb9e55fc0ec12e5b0ade37806debfb378d9a1b9d" size: 0 commission_rate: 200 next_epoch_stake: 20000000000000000 @@ -269,27 +269,27 @@ validators: next_epoch_commission_rate: 200 extra_fields: id: - id: "0x8d5ea4c7ecfaf945debd1b29d70fd8c8b46ce0393d945f68b41426bd4d38e66f" + id: "0x3307d52632bb86f142fa40561bb2b46365a5612225a0b0891a63809fcdcb691f" size: 0 pending_active_validators: contents: - id: "0x0dead6a70ff01bf106a635d38305ccac21fa0c76ce61c7f856a8a22a57afd10a" + id: "0x60cea2865bd42d6a782798762fa70c2d717be27f8873c1a512882a190629e254" size: 0 pending_removals: [] staking_pool_mappings: - id: "0x3032fd3aad31839c2ae398adf6e8c2d004a90559f42ce019de8e8325e853cfe4" + id: "0xbcdff2f0bca8d3c90783a19a68012d10c6c52c187817395fe91b220957ae65dd" size: 1 inactive_validators: - id: "0x8a5b3d8b3bd756e6f7255df5ceec12332997dac4ccda2fc7a161223a6f8b8318" + id: "0xb126b6b0efdfd66f0a14c159a5828b7844065267efb83637e59922dd28a2dec9" size: 0 validator_candidates: - id: "0x9116819fa6532cc674171d989ef96e1ab4a08b1750fdd77b7da6124d6b2f1344" + id: "0x35e1d26ec23453bfb7007fb2882ced97a1d19a102d2320bfbd136a6e35220688" size: 0 at_risk_validators: contents: [] extra_fields: id: - id: "0x28d3c4849301bb825be9c8bd2479020915a97e8959482bd18b2e34e6a35f9304" + id: "0x30f3634e8f7220afff05b96d87ab9020bc62538f5b0910b9c5d5e12646d944ea" size: 0 storage_fund: total_object_storage_rebates: @@ -306,7 +306,7 @@ parameters: validator_low_stake_grace_period: 7 extra_fields: id: - id: "0x642a5340b910c058025d03bb71d18a6bfb175627ec384b409107fe36c7ac5294" + id: "0x8f0219b14d05d238a48c0f75c3cc9c675acb9b5f6c50e0b7a9b9bbecaaaea232" size: 0 reference_gas_price: 1000 validator_report_records: @@ -320,7 +320,7 @@ stake_subsidy: stake_subsidy_decrease_rate: 1000 extra_fields: id: - id: "0x4d35369e7cd2fafae28fe50468fdc4e3b89a02cd4f9fe7ef5764770fb2a84106" + id: "0x3e45c6ab50494f16b32675da9b00233b08f0ca281c2f763ed5838518045a13b6" size: 0 safe_mode: false safe_mode_storage_rewards: @@ -332,5 +332,6 @@ safe_mode_non_refundable_storage_fee: 0 epoch_start_timestamp_ms: 10 extra_fields: id: - id: "0xc772e5006729cabf62b9598a8bbf168820bf2f175287dd55fb87bb9de12f01a6" + id: "0xf741efb1558fc976c1b7ba102a1c0ad5b814a15913c08fe18c3abf20f74547a2" size: 0 + diff --git a/crates/sui-transactional-test-runner/src/simulator_persisted_store.rs b/crates/sui-transactional-test-runner/src/simulator_persisted_store.rs index 72c021f859db06..ce73f18a2404f3 100644 --- a/crates/sui-transactional-test-runner/src/simulator_persisted_store.rs +++ b/crates/sui-transactional-test-runner/src/simulator_persisted_store.rs @@ -457,6 +457,8 @@ impl ChildObjectResolver for PersistedStore { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, _epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> sui_types::error::SuiResult> { let recv_object = match SimulatorStore::get_object(self, receiving_object_id) { None => return Ok(None), diff --git a/crates/sui-types/src/base_types.rs b/crates/sui-types/src/base_types.rs index 71c5a35ccb07e0..d03d00bf74f866 100644 --- a/crates/sui-types/src/base_types.rs +++ b/crates/sui-types/src/base_types.rs @@ -135,6 +135,32 @@ pub struct ObjectID( AccountAddress, ); +#[serde_as] +#[derive(Debug, Eq, PartialEq, Clone, Copy, PartialOrd, Ord, Hash, Serialize, Deserialize)] +pub enum FullObjectID { + Fastpath(ObjectID), + Consensus(ConsensusObjectSequenceKey), +} + +impl FullObjectID { + pub fn new(object_id: ObjectID, start_version: Option) -> Self { + if let Some(start_version) = start_version { + Self::Consensus((object_id, start_version)) + } else { + Self::Fastpath(object_id) + } + } + + pub fn id(&self) -> ObjectID { + match &self { + FullObjectID::Fastpath(object_id) => *object_id, + FullObjectID::Consensus(consensus_object_sequence_key) => { + consensus_object_sequence_key.0 + } + } + } +} + pub type VersionDigest = (SequenceNumber, ObjectDigest); pub type ObjectRef = (ObjectID, SequenceNumber, ObjectDigest); @@ -155,8 +181,10 @@ pub fn update_object_ref_for_testing(object_ref: ObjectRef) -> ObjectRef { ) } +pub type FullObjectRef = (FullObjectID, SequenceNumber, ObjectDigest); + /// Represents an distinct stream of object versions for a Shared or ConsensusV2 object, -/// based on the object ID and initial shared version. +/// based on the object ID and start version. pub type ConsensusObjectSequenceKey = (ObjectID, SequenceNumber); /// Wrapper around StructTag with a space-efficient representation for common types like coins diff --git a/crates/sui-types/src/in_memory_storage.rs b/crates/sui-types/src/in_memory_storage.rs index 826c45ccec0ccd..36c382135542b6 100644 --- a/crates/sui-types/src/in_memory_storage.rs +++ b/crates/sui-types/src/in_memory_storage.rs @@ -68,6 +68,8 @@ impl ChildObjectResolver for InMemoryStorage { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, _epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + _use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { let recv_object = match self.persistent.get(receiving_object_id).cloned() { None => return Ok(None), diff --git a/crates/sui-types/src/inner_temporary_store.rs b/crates/sui-types/src/inner_temporary_store.rs index b7e62c22304bf1..66f1bfe4d3f7a6 100644 --- a/crates/sui-types/src/inner_temporary_store.rs +++ b/crates/sui-types/src/inner_temporary_store.rs @@ -46,7 +46,7 @@ impl InnerTemporaryStore { InputKey::Package { id: *id } } else { InputKey::VersionedObject { - id: *id, + id: obj.full_id(), version: obj.version(), } } @@ -62,14 +62,14 @@ impl InnerTemporaryStore { // add deleted shared objects to the outputkeys that then get sent to notify_commit let deleted_output_keys = deleted .iter() - .filter(|(id, _)| { + .filter_map(|(id, seq)| { self.input_objects .get(id) - .is_some_and(|obj| obj.is_shared()) + .and_then(|obj| obj.is_shared().then_some((obj.full_id(), *seq))) }) - .map(|(id, seq)| InputKey::VersionedObject { - id: *id, - version: *seq, + .map(|(full_id, seq)| InputKey::VersionedObject { + id: full_id, + version: seq, }); output_keys.extend(deleted_output_keys); @@ -78,8 +78,14 @@ impl InnerTemporaryStore { let smeared_version = self.lamport_version; let deleted_accessed_objects = effects.deleted_mutably_accessed_shared_objects(); for object_id in deleted_accessed_objects.into_iter() { + let id = self + .input_objects + .get(&object_id) + // TODO-DNS: Double check, is this `expect` safe? + .expect("deleted object must be in input objects") + .full_id(); let key = InputKey::VersionedObject { - id: object_id, + id, version: smeared_version, }; output_keys.push(key); diff --git a/crates/sui-types/src/object.rs b/crates/sui-types/src/object.rs index c6de390950517a..f8039d19e25428 100644 --- a/crates/sui-types/src/object.rs +++ b/crates/sui-types/src/object.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; use serde_with::serde_as; use serde_with::Bytes; -use crate::base_types::{MoveObjectType, ObjectIDParseError}; +use crate::base_types::{FullObjectID, FullObjectRef, MoveObjectType, ObjectIDParseError}; use crate::coin::{Coin, CoinMetadata, TreasuryCap}; use crate::crypto::{default_hash, deterministic_random_account_key}; use crate::error::{ExecutionError, ExecutionErrorKind, UserInputError, UserInputResult}; @@ -565,6 +565,10 @@ impl Owner { pub fn is_shared(&self) -> bool { matches!(self, Owner::Shared { .. }) } + + pub fn is_consensus(&self) -> bool { + matches!(self, Owner::Shared { .. } | Owner::ConsensusV2 { .. }) + } } impl PartialEq for Owner { @@ -811,6 +815,10 @@ impl ObjectInner { self.owner.is_shared() } + pub fn is_consensus(&self) -> bool { + self.owner.is_consensus() + } + pub fn get_single_owner(&self) -> Option { self.owner.get_owner_address().ok() } @@ -830,6 +838,10 @@ impl ObjectInner { (self.id(), self.version(), self.digest()) } + pub fn compute_full_object_reference(&self) -> FullObjectRef { + (self.full_id(), self.version(), self.digest()) + } + pub fn digest(&self) -> ObjectDigest { ObjectDigest::new(default_hash(self)) } @@ -843,6 +855,15 @@ impl ObjectInner { } } + pub fn full_id(&self) -> FullObjectID { + let id = self.id(); + if let Some(start_version) = self.owner.start_version() { + FullObjectID::Consensus((id, start_version)) + } else { + FullObjectID::Fastpath(id) + } + } + pub fn version(&self) -> SequenceNumber { use Data::*; diff --git a/crates/sui-types/src/storage/mod.rs b/crates/sui-types/src/storage/mod.rs index 8b06376387860e..37d33cb9e6427c 100644 --- a/crates/sui-types/src/storage/mod.rs +++ b/crates/sui-types/src/storage/mod.rs @@ -7,7 +7,9 @@ mod read_store; mod shared_in_memory_store; mod write_store; -use crate::base_types::{TransactionDigest, VersionNumber}; +use crate::base_types::{ + ConsensusObjectSequenceKey, FullObjectID, FullObjectRef, TransactionDigest, VersionNumber, +}; use crate::committee::EpochId; use crate::error::{ExecutionError, SuiError}; use crate::execution::{DynamicallyLoadedObjectMetadata, ExecutionResults}; @@ -42,7 +44,7 @@ pub use write_store::WriteStore; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum InputKey { VersionedObject { - id: ObjectID, + id: FullObjectID, version: SequenceNumber, }, Package { @@ -51,10 +53,10 @@ pub enum InputKey { } impl InputKey { - pub fn id(&self) -> ObjectID { + pub fn id(&self) -> FullObjectID { match self { InputKey::VersionedObject { id, .. } => *id, - InputKey::Package { id } => *id, + InputKey::Package { id } => FullObjectID::Fastpath(*id), } } @@ -79,7 +81,7 @@ impl From<&Object> for InputKey { InputKey::Package { id: obj.id() } } else { InputKey::VersionedObject { - id: obj.id(), + id: obj.full_id(), version: obj.version(), } } @@ -187,6 +189,8 @@ pub trait ChildObjectResolver { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult>; } @@ -426,6 +430,8 @@ impl ChildObjectResolver for std::sync::Arc { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { ChildObjectResolver::get_object_received_at_version( self.as_ref(), @@ -433,6 +439,7 @@ impl ChildObjectResolver for std::sync::Arc { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } @@ -452,6 +459,8 @@ impl ChildObjectResolver for &S { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { ChildObjectResolver::get_object_received_at_version( *self, @@ -459,6 +468,7 @@ impl ChildObjectResolver for &S { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } @@ -478,6 +488,8 @@ impl ChildObjectResolver for &mut S { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { ChildObjectResolver::get_object_received_at_version( *self, @@ -485,11 +497,11 @@ impl ChildObjectResolver for &mut S { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } -// The primary key type for object storage. #[serde_as] #[derive(Eq, PartialEq, Clone, Copy, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] pub struct ObjectKey(pub ObjectID, pub VersionNumber); @@ -518,6 +530,86 @@ impl From<&ObjectRef> for ObjectKey { } } +#[serde_as] +#[derive(Eq, PartialEq, Clone, Copy, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] +pub struct ConsensusObjectKey(pub ConsensusObjectSequenceKey, pub VersionNumber); + +#[serde_as] +#[derive(Eq, PartialEq, Clone, Copy, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] +pub enum FullObjectKey { + Fastpath(ObjectKey), + Consensus(ConsensusObjectKey), +} + +impl FullObjectKey { + pub fn max_for_id(id: &FullObjectID) -> Self { + match id { + FullObjectID::Fastpath(object_id) => Self::Fastpath(ObjectKey::max_for_id(object_id)), + FullObjectID::Consensus(consensus_object_sequence_key) => Self::Consensus( + ConsensusObjectKey(*consensus_object_sequence_key, VersionNumber::MAX), + ), + } + } + + pub fn min_for_id(id: &FullObjectID) -> Self { + match id { + FullObjectID::Fastpath(object_id) => Self::Fastpath(ObjectKey::min_for_id(object_id)), + FullObjectID::Consensus(consensus_object_sequence_key) => Self::Consensus( + ConsensusObjectKey(*consensus_object_sequence_key, VersionNumber::MIN), + ), + } + } + + pub fn new(object_id: FullObjectID, version: VersionNumber) -> Self { + match object_id { + FullObjectID::Fastpath(object_id) => Self::Fastpath(ObjectKey(object_id, version)), + FullObjectID::Consensus(consensus_object_sequence_key) => { + Self::Consensus(ConsensusObjectKey(consensus_object_sequence_key, version)) + } + } + } + + pub fn id(&self) -> FullObjectID { + match self { + FullObjectKey::Fastpath(object_key) => FullObjectID::Fastpath(object_key.0), + FullObjectKey::Consensus(consensus_object_key) => { + FullObjectID::Consensus(consensus_object_key.0) + } + } + } + + pub fn version(&self) -> VersionNumber { + match self { + FullObjectKey::Fastpath(object_key) => object_key.1, + FullObjectKey::Consensus(consensus_object_key) => consensus_object_key.1, + } + } + + // Returns the equivalent ObjectKey for this FullObjectKey, discarding any initial + // shared version information, if present. + // TODO: Delete this function once marker table migration is complete. + pub fn into_object_key(self) -> ObjectKey { + match self { + FullObjectKey::Fastpath(object_key) => object_key, + FullObjectKey::Consensus(consensus_object_key) => { + ObjectKey(consensus_object_key.0 .0, consensus_object_key.1) + } + } + } +} + +impl From for FullObjectKey { + fn from(object_ref: FullObjectRef) -> Self { + FullObjectKey::from(&object_ref) + } +} + +impl From<&FullObjectRef> for FullObjectKey { + fn from(object_ref: &FullObjectRef) -> Self { + FullObjectKey::new(object_ref.0, object_ref.1) + } +} + #[derive(Clone)] pub enum ObjectOrTombstone { Object(Object), diff --git a/sui-execution/latest/sui-adapter/src/temporary_store.rs b/sui-execution/latest/sui-adapter/src/temporary_store.rs index 8e4223f2485ed3..3fb38b352abd0d 100644 --- a/sui-execution/latest/sui-adapter/src/temporary_store.rs +++ b/sui-execution/latest/sui-adapter/src/temporary_store.rs @@ -970,6 +970,8 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { // You should never be able to try and receive an object after deleting it or writing it in the same // transaction since `Receiving` doesn't have copy. @@ -986,6 +988,7 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } diff --git a/sui-execution/latest/sui-move-natives/src/object_runtime/object_store.rs b/sui-execution/latest/sui-move-natives/src/object_runtime/object_store.rs index 323905b909dc5d..68b345eabe54f2 100644 --- a/sui-execution/latest/sui-move-natives/src/object_runtime/object_store.rs +++ b/sui-execution/latest/sui-move-natives/src/object_runtime/object_store.rs @@ -173,7 +173,15 @@ impl<'a> Inner<'a> { ) -> PartialVMResult> { let child_opt = self .resolver - .get_object_received_at_version(&owner, &child, version, self.current_epoch_id) + .get_object_received_at_version( + &owner, + &child, + version, + self.current_epoch_id, + self.protocol_config + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), + ) .map_err(|msg| { PartialVMError::new(StatusCode::STORAGE_ERROR).with_message(format!("{msg}")) })?; diff --git a/sui-execution/latest/sui-move-natives/src/test_scenario.rs b/sui-execution/latest/sui-move-natives/src/test_scenario.rs index 12926664855711..d9b6700a67ab4d 100644 --- a/sui-execution/latest/sui-move-natives/src/test_scenario.rs +++ b/sui-execution/latest/sui-move-natives/src/test_scenario.rs @@ -74,6 +74,8 @@ impl ChildObjectResolver for InMemoryTestStore { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: sui_types::committee::EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> sui_types::error::SuiResult> { self.0.with_borrow(|store| { store.get_object_received_at_version( @@ -81,6 +83,7 @@ impl ChildObjectResolver for InMemoryTestStore { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) }) } diff --git a/sui-execution/v0/sui-adapter/src/temporary_store.rs b/sui-execution/v0/sui-adapter/src/temporary_store.rs index 1745509129b47a..d88f3983044fbd 100644 --- a/sui-execution/v0/sui-adapter/src/temporary_store.rs +++ b/sui-execution/v0/sui-adapter/src/temporary_store.rs @@ -965,6 +965,8 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { // You should never be able to try and receive an object after deleting it or writing it in the same // transaction since `Receiving` doesn't have copy. @@ -975,6 +977,7 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } diff --git a/sui-execution/v1/sui-adapter/src/temporary_store.rs b/sui-execution/v1/sui-adapter/src/temporary_store.rs index 5b5da393d226ff..e09fb531942bc1 100644 --- a/sui-execution/v1/sui-adapter/src/temporary_store.rs +++ b/sui-execution/v1/sui-adapter/src/temporary_store.rs @@ -1067,6 +1067,8 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { // You should never be able to try and receive an object after deleting it or writing it in the same // transaction since `Receiving` doesn't have copy. @@ -1083,6 +1085,7 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } diff --git a/sui-execution/v1/sui-move-natives/src/object_runtime/mod.rs b/sui-execution/v1/sui-move-natives/src/object_runtime/mod.rs index 0ca90b8ed32ba7..8e2b001e8672c7 100644 --- a/sui-execution/v1/sui-move-natives/src/object_runtime/mod.rs +++ b/sui-execution/v1/sui-move-natives/src/object_runtime/mod.rs @@ -112,6 +112,7 @@ pub(crate) struct LocalProtocolConfig { pub(crate) object_runtime_max_num_store_entries_system_tx: u64, pub(crate) loaded_child_object_format: bool, pub(crate) loaded_child_object_format_type: bool, + pub(crate) use_object_per_epoch_marker_table_v2: bool, } impl LocalProtocolConfig { @@ -137,6 +138,9 @@ impl LocalProtocolConfig { .object_runtime_max_num_store_entries_system_tx(), loaded_child_object_format: config.loaded_child_object_format(), loaded_child_object_format_type: config.loaded_child_object_format_type(), + use_object_per_epoch_marker_table_v2: config + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), } } } diff --git a/sui-execution/v1/sui-move-natives/src/object_runtime/object_store.rs b/sui-execution/v1/sui-move-natives/src/object_runtime/object_store.rs index 09b576d1cb5b3a..c0c4a5003e2154 100644 --- a/sui-execution/v1/sui-move-natives/src/object_runtime/object_store.rs +++ b/sui-execution/v1/sui-move-natives/src/object_runtime/object_store.rs @@ -90,7 +90,13 @@ impl<'a> Inner<'a> { ) -> PartialVMResult> { let child_opt = self .resolver - .get_object_received_at_version(&owner, &child, version, self.current_epoch_id) + .get_object_received_at_version( + &owner, + &child, + version, + self.current_epoch_id, + self.local_config.use_object_per_epoch_marker_table_v2, + ) .map_err(|msg| { PartialVMError::new(StatusCode::STORAGE_ERROR).with_message(format!("{msg}")) })?; diff --git a/sui-execution/v2/sui-adapter/src/temporary_store.rs b/sui-execution/v2/sui-adapter/src/temporary_store.rs index 837d24b1e0e991..34036e507e6111 100644 --- a/sui-execution/v2/sui-adapter/src/temporary_store.rs +++ b/sui-execution/v2/sui-adapter/src/temporary_store.rs @@ -1119,6 +1119,8 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id: &ObjectID, receive_object_at_version: SequenceNumber, epoch_id: EpochId, + // TODO: Delete this parameter once table migration is complete. + use_object_per_epoch_marker_table_v2: bool, ) -> SuiResult> { // You should never be able to try and receive an object after deleting it or writing it in the same // transaction since `Receiving` doesn't have copy. @@ -1135,6 +1137,7 @@ impl<'backing> ChildObjectResolver for TemporaryStore<'backing> { receiving_object_id, receive_object_at_version, epoch_id, + use_object_per_epoch_marker_table_v2, ) } } diff --git a/sui-execution/v2/sui-move-natives/src/object_runtime/object_store.rs b/sui-execution/v2/sui-move-natives/src/object_runtime/object_store.rs index 7d977efac9623c..1fd05ea65697c2 100644 --- a/sui-execution/v2/sui-move-natives/src/object_runtime/object_store.rs +++ b/sui-execution/v2/sui-move-natives/src/object_runtime/object_store.rs @@ -93,7 +93,15 @@ impl<'a> Inner<'a> { ) -> PartialVMResult> { let child_opt = self .resolver - .get_object_received_at_version(&owner, &child, version, self.current_epoch_id) + .get_object_received_at_version( + &owner, + &child, + version, + self.current_epoch_id, + self.protocol_config + .use_object_per_epoch_marker_table_v2_as_option() + .unwrap_or(false), + ) .map_err(|msg| { PartialVMError::new(StatusCode::STORAGE_ERROR).with_message(format!("{msg}")) })?;