From 68279926c19872619adefab8be6560453d1e824f Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 2 Jul 2024 09:52:45 -0700 Subject: [PATCH] Commit per epoch config load to effects v2 --- .../deny_list_v1/coin_deny_and_undeny.exp | 3 ++ .../coin_deny_multiple_per_module.exp | 2 + .../tests/deny_list_v1/coin_deny_tto.exp | 2 + .../coin_deny_and_undeny_receiver.exp | 4 ++ .../coin_deny_and_undeny_sender.exp | 3 ++ .../tests/deny_list_v2/coin_global_pause.exp | 6 +++ crates/sui-types/src/deny_list_v2.rs | 44 +++++++++-------- crates/sui-types/src/effects/effects_v2.rs | 48 ++++++++++++------- crates/sui-types/src/effects/mod.rs | 11 +++-- .../src/effects/test_effects_builder.rs | 3 +- crates/sui-types/src/storage/mod.rs | 3 +- .../src/programmable_transactions/context.rs | 5 +- .../latest/sui-adapter/src/temporary_store.rs | 25 ++++++++-- .../v0/sui-adapter/src/temporary_store.rs | 2 +- .../v1/sui-adapter/src/temporary_store.rs | 3 +- .../v2/sui-adapter/src/temporary_store.rs | 3 +- 16 files changed, 117 insertions(+), 50 deletions(-) diff --git a/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_and_undeny.exp b/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_and_undeny.exp index 40ef07305f8df..3871b936ffd6c 100644 --- a/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_and_undeny.exp +++ b/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_and_undeny.exp @@ -6,6 +6,7 @@ A: object(0,0), B: object(0,1) task 1 'publish'. lines 12-34: created: object(1,0), object(1,1), object(1,2), object(1,3), object(1,4), object(1,5) mutated: object(0,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 18316000, storage_rebate: 0, non_refundable_storage_fee: 0 task 2 'view-object'. lines 36-36: @@ -133,6 +134,7 @@ Contents: sui::coin::TreasuryCap { task 8 'run'. lines 49-51: created: object(8,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3936800, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 9 'run'. lines 52-54: @@ -153,4 +155,5 @@ gas summary: computation_cost: 1000000, storage_cost: 9522800, storage_rebate: task 13 'transfer-object'. lines 64-64: mutated: object(0,1), object(8,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 2462400, storage_rebate: 1459656, non_refundable_storage_fee: 14744 diff --git a/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_multiple_per_module.exp b/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_multiple_per_module.exp index a3643e00fc989..787102f5090c0 100644 --- a/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_multiple_per_module.exp +++ b/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_multiple_per_module.exp @@ -6,6 +6,7 @@ A: object(0,0) task 1 'publish'. lines 9-54: created: object(1,0), object(1,1), object(1,2), object(1,3), object(1,4), object(1,5), object(1,6), object(1,7), object(1,8), object(1,9), object(1,10) mutated: object(0,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 33082800, storage_rebate: 0, non_refundable_storage_fee: 0 task 2 'view-object'. lines 56-56: @@ -259,4 +260,5 @@ Error: Error checking transaction input objects: AddressDeniedForCoin { address: task 15 'transfer-object'. lines 85-85: mutated: object(0,0), object(1,2) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 2416800, storage_rebate: 2392632, non_refundable_storage_fee: 24168 diff --git a/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_tto.exp b/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_tto.exp index 2e68efa1dcbad..b4c792f24bab4 100644 --- a/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_tto.exp +++ b/crates/sui-adapter-transactional-tests/tests/deny_list_v1/coin_deny_tto.exp @@ -6,6 +6,7 @@ A: object(0,0) task 1 'publish'. lines 8-46: created: object(1,0), object(1,1), object(1,2), object(1,3), object(1,4), object(1,5), object(1,6) mutated: object(0,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 21766400, storage_rebate: 0, non_refundable_storage_fee: 0 task 2 'view-object'. lines 48-48: @@ -156,4 +157,5 @@ gas summary: computation_cost: 1000000, storage_cost: 9522800, storage_rebate: task 12 'run'. lines 72-72: mutated: object(0,0), object(1,0), object(1,2) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3807600, storage_rebate: 3769524, non_refundable_storage_fee: 38076 diff --git a/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_receiver.exp b/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_receiver.exp index 7e76eed9511b8..0346f766948e9 100644 --- a/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_receiver.exp +++ b/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_receiver.exp @@ -6,11 +6,13 @@ A: object(0,0), B: object(0,1) task 1 'publish'. lines 12-37: created: object(1,0), object(1,1), object(1,2), object(1,3), object(1,4), object(1,5) mutated: object(0,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 18392000, storage_rebate: 0, non_refundable_storage_fee: 0 task 2 'run'. lines 38-40: created: object(2,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3936800, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 3 'run'. lines 41-43: @@ -22,6 +24,7 @@ gas summary: computation_cost: 1000000, storage_cost: 12190400, storage_rebate: task 4 'run'. lines 44-44: created: object(4,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3936800, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 5 'advance-epoch'. lines 46-48: @@ -45,4 +48,5 @@ Epoch advanced: 2 task 10 'run'. lines 60-60: created: object(10,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3936800, storage_rebate: 2437776, non_refundable_storage_fee: 24624 diff --git a/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_sender.exp b/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_sender.exp index 99dcab62bea37..ad339e422faf8 100644 --- a/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_sender.exp +++ b/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_deny_and_undeny_sender.exp @@ -6,6 +6,7 @@ A: object(0,0), B: object(0,1) task 1 'publish'. lines 13-49: created: object(1,0), object(1,1), object(1,2), object(1,3), object(1,4), object(1,5) mutated: object(0,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 19539600, storage_rebate: 0, non_refundable_storage_fee: 0 task 2 'view-object'. lines 50-52: @@ -23,6 +24,7 @@ Contents: sui::coin::DenyCapV2 { task 3 'run'. lines 53-55: created: object(3,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3936800, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 4 'run'. lines 56-58: @@ -54,4 +56,5 @@ gas summary: computation_cost: 1000000, storage_cost: 988000, storage_rebate: 9 task 10 'transfer-object'. lines 74-74: mutated: object(0,1), object(3,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 2462400, storage_rebate: 1459656, non_refundable_storage_fee: 14744 diff --git a/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_global_pause.exp b/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_global_pause.exp index 20ebffb1b51c2..513a9ddb66ca9 100644 --- a/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_global_pause.exp +++ b/crates/sui-adapter-transactional-tests/tests/deny_list_v2/coin_global_pause.exp @@ -6,21 +6,25 @@ A: object(0,0), B: object(0,1) task 1 'publish'. lines 10-72: created: object(1,0), object(1,1), object(1,2), object(1,3), object(1,4), object(1,5) mutated: object(0,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 22032400, storage_rebate: 0, non_refundable_storage_fee: 0 task 2 'run'. lines 73-75: created: object(2,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 3936800, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 3 'run'. lines 76-78: created: object(3,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 4119200, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 4 'run'. lines 79-81: created: object(4,0) mutated: object(0,0), object(1,1) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 4119200, storage_rebate: 2437776, non_refundable_storage_fee: 24624 task 5 'run'. lines 82-84: @@ -47,6 +51,7 @@ task 10 'run'. lines 98-98: mutated: object(0,0) unwrapped: object(10,0) deleted: object(3,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 2462400, storage_rebate: 2618352, non_refundable_storage_fee: 26448 task 11 'advance-epoch'. lines 100-103: @@ -94,4 +99,5 @@ task 21 'run'. lines 131-131: mutated: object(0,0) unwrapped: object(1,1) deleted: object(18,0) +unchanged_shared: 0x0000000000000000000000000000000000000000000000000000000000000403 gas summary: computation_cost: 1000000, storage_cost: 2462400, storage_rebate: 2618352, non_refundable_storage_fee: 26448 diff --git a/crates/sui-types/src/deny_list_v2.rs b/crates/sui-types/src/deny_list_v2.rs index 7f12ebee6d38f..d9e275357e4a2 100644 --- a/crates/sui-types/src/deny_list_v2.rs +++ b/crates/sui-types/src/deny_list_v2.rs @@ -4,8 +4,7 @@ use crate::base_types::{EpochId, ObjectID, SuiAddress}; use crate::config::{Config, Setting}; use crate::deny_list_v1::{ - get_deny_list_root_object, input_object_coin_types_for_denylist_check, - DENY_LIST_COIN_TYPE_INDEX, DENY_LIST_MODULE, + input_object_coin_types_for_denylist_check, DENY_LIST_COIN_TYPE_INDEX, DENY_LIST_MODULE, }; use crate::dynamic_field::{get_dynamic_field_from_store, DOFWrapper}; use crate::error::{ExecutionError, ExecutionErrorKind, UserInputError, UserInputResult}; @@ -13,7 +12,7 @@ use crate::id::UID; use crate::object::Object; use crate::storage::ObjectStore; use crate::transaction::{CheckedInputObjects, ReceivingObjects}; -use crate::{MoveTypeTagTrait, SUI_FRAMEWORK_PACKAGE_ID}; +use crate::{MoveTypeTagTrait, SUI_DENY_LIST_OBJECT_ID, SUI_FRAMEWORK_PACKAGE_ID}; use move_core_types::ident_str; use move_core_types::language_storage::{StructTag, TypeTag}; use serde::de::DeserializeOwned; @@ -120,11 +119,13 @@ pub fn check_coin_deny_list_v2_during_signing( Ok(()) } +/// Returns 1) whether the coin deny list check passed, and 2) the number of regulated transfers. pub fn check_coin_deny_list_v2_during_execution( written_objects: &BTreeMap, cur_epoch: EpochId, object_store: &dyn ObjectStore, -) -> Result<(), ExecutionError> { +) -> (Result<(), ExecutionError>, u64) { + let mut num_regulated_transfers = 0; let mut new_coin_owners = BTreeMap::new(); for obj in written_objects.values() { if obj.is_gas_coin() { @@ -140,38 +141,43 @@ pub fn check_coin_deny_list_v2_during_execution( .entry(coin_type.to_canonical_string(false)) .or_insert_with(BTreeSet::new) .insert(owner); + num_regulated_transfers += 1; } for (coin_type, owners) in new_coin_owners { let Some(deny_list) = get_per_type_coin_deny_list_v2(&coin_type, object_store) else { continue; }; if check_global_pause(&deny_list, object_store, Some(cur_epoch)) { - return Err(ExecutionError::new( - ExecutionErrorKind::CoinTypeGlobalPause { coin_type }, - None, - )); + return ( + Err(ExecutionError::new( + ExecutionErrorKind::CoinTypeGlobalPause { coin_type }, + None, + )), + num_regulated_transfers, + ); } for owner in owners { if check_address_denied_by_config(&deny_list, owner, object_store, Some(cur_epoch)) { - return Err(ExecutionError::new( - ExecutionErrorKind::AddressDeniedForCoin { - address: owner, - coin_type, - }, - None, - )); + return ( + Err(ExecutionError::new( + ExecutionErrorKind::AddressDeniedForCoin { + address: owner, + coin_type, + }, + None, + )), + num_regulated_transfers, + ); } } } - Ok(()) + (Ok(()), num_regulated_transfers) } pub fn get_per_type_coin_deny_list_v2( coin_type: &String, object_store: &dyn ObjectStore, ) -> Option { - let deny_list_root = - get_deny_list_root_object(object_store).expect("Deny list root object not found"); let config_key = DOFWrapper { name: ConfigKey { per_type_index: DENY_LIST_COIN_TYPE_INDEX, @@ -180,7 +186,7 @@ pub fn get_per_type_coin_deny_list_v2( }; // TODO: Consider caching the config object UID to avoid repeat deserialization. let config: Config = - get_dynamic_field_from_store(object_store, deny_list_root.id(), &config_key).ok()?; + get_dynamic_field_from_store(object_store, SUI_DENY_LIST_OBJECT_ID, &config_key).ok()?; Some(config) } diff --git a/crates/sui-types/src/effects/effects_v2.rs b/crates/sui-types/src/effects/effects_v2.rs index fae3bc3f66dbc..f1dfa90d56ab2 100644 --- a/crates/sui-types/src/effects/effects_v2.rs +++ b/crates/sui-types/src/effects/effects_v2.rs @@ -16,9 +16,9 @@ use crate::gas::GasCostSummary; use crate::is_system_package; use crate::object::{Owner, OBJECT_START_VERSION}; use serde::{Deserialize, Serialize}; -use std::collections::BTreeMap; #[cfg(debug_assertions)] use std::collections::HashSet; +use std::collections::{BTreeMap, BTreeSet}; /// The response from processing a transaction or a certified transaction #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)] @@ -107,22 +107,28 @@ impl TransactionEffectsAPI for TransactionEffectsV2 { } _ => None, }) - .chain(self.unchanged_shared_objects.iter().map( - |(id, change_kind)| match change_kind { - UnchangedSharedKind::ReadOnlyRoot((version, digest)) => { - InputSharedObject::ReadOnly((*id, *version, *digest)) - } - UnchangedSharedKind::MutateDeleted(seqno) => { - InputSharedObject::MutateDeleted(*id, *seqno) - } - UnchangedSharedKind::ReadDeleted(seqno) => { - InputSharedObject::ReadDeleted(*id, *seqno) - } - UnchangedSharedKind::Cancelled(seqno) => { - InputSharedObject::Cancelled(*id, *seqno) - } - }, - )) + .chain( + self.unchanged_shared_objects + .iter() + .filter_map(|(id, change_kind)| match change_kind { + UnchangedSharedKind::ReadOnlyRoot((version, digest)) => { + Some(InputSharedObject::ReadOnly((*id, *version, *digest))) + } + UnchangedSharedKind::MutateDeleted(seqno) => { + Some(InputSharedObject::MutateDeleted(*id, *seqno)) + } + UnchangedSharedKind::ReadDeleted(seqno) => { + Some(InputSharedObject::ReadDeleted(*id, *seqno)) + } + UnchangedSharedKind::Cancelled(seqno) => { + Some(InputSharedObject::Cancelled(*id, *seqno)) + } + // We can not expose the per epoch config object as input shared object, + // since it does not require sequencing, and hence shall not be considered + // as a normal input shared object. + UnchangedSharedKind::PerEpochConfig => None, + }), + ) .collect() } @@ -405,6 +411,7 @@ impl TransactionEffectsV2 { executed_epoch: EpochId, gas_used: GasCostSummary, shared_objects: Vec, + loaded_per_epoch_config_objects: BTreeSet, transaction_digest: TransactionDigest, lamport_version: SequenceNumber, changed_objects: BTreeMap, @@ -435,6 +442,11 @@ impl TransactionEffectsV2 { Some((id, UnchangedSharedKind::Cancelled(version))) } }) + .chain( + loaded_per_epoch_config_objects + .into_iter() + .map(|id| (id, UnchangedSharedKind::PerEpochConfig)), + ) .collect(); let changed_objects: Vec<_> = changed_objects.into_iter().collect(); @@ -595,4 +607,6 @@ pub enum UnchangedSharedKind { ReadDeleted(SequenceNumber), /// Shared objects in cancelled transaction. The sequence number embed cancellation reason. Cancelled(SequenceNumber), + /// Read of a per-epoch config object that should remain the same during an epoch. + PerEpochConfig, } diff --git a/crates/sui-types/src/effects/mod.rs b/crates/sui-types/src/effects/mod.rs index 696a20b4de30b..6389f86b5c32d 100644 --- a/crates/sui-types/src/effects/mod.rs +++ b/crates/sui-types/src/effects/mod.rs @@ -25,7 +25,7 @@ use enum_dispatch::enum_dispatch; pub use object_change::{EffectsObjectChange, ObjectIn, ObjectOut}; use serde::{Deserialize, Serialize}; use shared_crypto::intent::{Intent, IntentScope}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; pub use test_effects_builder::TestEffectsBuilder; mod effects_v1; @@ -126,6 +126,7 @@ impl TransactionEffects { executed_epoch: EpochId, gas_used: GasCostSummary, shared_objects: Vec, + loaded_per_epoch_config_objects: BTreeSet, transaction_digest: TransactionDigest, lamport_version: SequenceNumber, changed_objects: BTreeMap, @@ -138,6 +139,7 @@ impl TransactionEffects { executed_epoch, gas_used, shared_objects, + loaded_per_epoch_config_objects, transaction_digest, lamport_version, changed_objects, @@ -313,11 +315,12 @@ pub trait TransactionEffectsAPI { /// It includes objects that are mutated, wrapped and deleted. /// This API is only available on effects v2 and above. fn old_object_metadata(&self) -> Vec<(ObjectRef, Owner)>; - /// Returns the list of shared objects used in the input, with full object reference - /// and use kind. This is needed in effects because in transaction we only have object ID + /// Returns the list of sequenced shared objects used in the input. + /// This is needed in effects because in transaction we only have object ID /// for shared objects. Their version and digest can only be figured out after sequencing. /// Also provides the use kind to indicate whether the object was mutated or read-only. - /// Down the road it could also indicate use-of-deleted. + /// It does not include per epoch config objects since they do not require sequencing. + /// TODO: Rename this function to indicate sequencing requirement. fn input_shared_objects(&self) -> Vec; fn created(&self) -> Vec<(ObjectRef, Owner)>; fn mutated(&self) -> Vec<(ObjectRef, Owner)>; diff --git a/crates/sui-types/src/effects/test_effects_builder.rs b/crates/sui-types/src/effects/test_effects_builder.rs index be51c318b1a2d..027a131e0c18a 100644 --- a/crates/sui-types/src/effects/test_effects_builder.rs +++ b/crates/sui-types/src/effects/test_effects_builder.rs @@ -10,7 +10,7 @@ use crate::gas::GasCostSummary; use crate::message_envelope::Message; use crate::object::Owner; use crate::transaction::{InputObjectKind, SenderSignedData, TransactionDataAPI}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; pub struct TestEffectsBuilder { transaction: SenderSignedData, @@ -139,6 +139,7 @@ impl TestEffectsBuilder { executed_epoch, GasCostSummary::default(), shared_objects, + BTreeSet::new(), self.transaction.digest(), lamport_version, changed_objects, diff --git a/crates/sui-types/src/storage/mod.rs b/crates/sui-types/src/storage/mod.rs index 670570f889f47..ae30f42f5c50b 100644 --- a/crates/sui-types/src/storage/mod.rs +++ b/crates/sui-types/src/storage/mod.rs @@ -208,10 +208,11 @@ pub trait Storage { wrapped_object_containers: BTreeMap, ); + /// Check coin denylist during execution, and returns the number of regulated transfers. fn check_coin_deny_list( &self, written_objects: &BTreeMap, - ) -> Result<(), ExecutionError>; + ) -> (Result<(), ExecutionError>, u64); } pub type PackageFetchResults = Result, Vec>; diff --git a/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs b/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs index 73cf58857351f..19940d394a478 100644 --- a/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs +++ b/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs @@ -830,7 +830,10 @@ mod checked { } if protocol_config.enable_coin_deny_list_v2() { - state_view.check_coin_deny_list(&written_objects)?; + let (result, _num_regulated_transfers) = + state_view.check_coin_deny_list(&written_objects); + // TODO: Charge gas based on the number of regulated transfers. + result?; } let user_events = user_events diff --git a/sui-execution/latest/sui-adapter/src/temporary_store.rs b/sui-execution/latest/sui-adapter/src/temporary_store.rs index d9d881fedbc9c..f133269564ac6 100644 --- a/sui-execution/latest/sui-adapter/src/temporary_store.rs +++ b/sui-execution/latest/sui-adapter/src/temporary_store.rs @@ -32,6 +32,7 @@ use sui_types::{ object::{Data, Object}, storage::{BackingPackageStore, ChildObjectResolver, ParentSync, Storage}, transaction::InputObjects, + SUI_DENY_LIST_OBJECT_ID, }; use sui_types::{is_system_package, SUI_SYSTEM_STATE_OBJECT_ID}; @@ -65,6 +66,10 @@ pub struct TemporaryStore<'backing> { // TODO: Now that we track epoch here, there are a few places we don't need to pass it around. /// The current epoch. cur_epoch: EpochId, + + /// The set of per-epoch config objects that were loaded during execution, and are not in the + /// input objects. This allows us to commit them to the effects. + loaded_per_epoch_config_objects: RwLock>, } impl<'backing> TemporaryStore<'backing> { @@ -109,6 +114,7 @@ impl<'backing> TemporaryStore<'backing> { runtime_packages_loaded_from_db: RwLock::new(BTreeMap::new()), receiving_objects, cur_epoch, + loaded_per_epoch_config_objects: RwLock::new(BTreeSet::new()), } } @@ -235,6 +241,8 @@ impl<'backing> TemporaryStore<'backing> { let object_changes = self.get_object_changes(); let lamport_version = self.lamport_timestamp; + // TODO: Cleanup this clone. Potentially add unchanged_shraed_objects directly to InnerTempStore. + let loaded_per_epoch_config_objects = self.loaded_per_epoch_config_objects.read().clone(); let inner = self.into_inner(); let effects = TransactionEffects::new_from_execution_v2( @@ -243,6 +251,7 @@ impl<'backing> TemporaryStore<'backing> { gas_cost_summary, // TODO: Provide the list of read-only shared objects directly. shared_object_refs, + loaded_per_epoch_config_objects, *transaction_digest, lamport_version, object_changes, @@ -1015,13 +1024,21 @@ impl<'backing> Storage for TemporaryStore<'backing> { fn check_coin_deny_list( &self, written_objects: &BTreeMap, - ) -> Result<(), ExecutionError> { - // TODO: How do we track runtime loaded objects for replay? - check_coin_deny_list_v2_during_execution( + ) -> (Result<(), ExecutionError>, u64) { + let (result, num_regulated_transfers) = check_coin_deny_list_v2_during_execution( written_objects, self.cur_epoch, self.store.as_object_store(), - ) + ); + // The denylist object is only loaded if there are regulated transfers. + // And also if we already have it in the input there is no need to commit it again in the effects. + if num_regulated_transfers > 0 && !self.input_objects.contains_key(&SUI_DENY_LIST_OBJECT_ID) + { + self.loaded_per_epoch_config_objects + .write() + .insert(SUI_DENY_LIST_OBJECT_ID); + } + (result, num_regulated_transfers) } } diff --git a/sui-execution/v0/sui-adapter/src/temporary_store.rs b/sui-execution/v0/sui-adapter/src/temporary_store.rs index 178eac796d943..5a090cd230d27 100644 --- a/sui-execution/v0/sui-adapter/src/temporary_store.rs +++ b/sui-execution/v0/sui-adapter/src/temporary_store.rs @@ -1005,7 +1005,7 @@ impl<'backing> Storage for TemporaryStore<'backing> { fn check_coin_deny_list( &self, _written_objects: &BTreeMap, - ) -> Result<(), ExecutionError> { + ) -> (Result<(), ExecutionError>, u64) { unreachable!("Coin denylist v2 is not supported in sui-execution v0"); } } diff --git a/sui-execution/v1/sui-adapter/src/temporary_store.rs b/sui-execution/v1/sui-adapter/src/temporary_store.rs index 7a5a7257b4525..b719d482df56b 100644 --- a/sui-execution/v1/sui-adapter/src/temporary_store.rs +++ b/sui-execution/v1/sui-adapter/src/temporary_store.rs @@ -358,6 +358,7 @@ impl<'backing> TemporaryStore<'backing> { gas_cost_summary, // TODO: Provide the list of read-only shared objects directly. shared_object_refs, + BTreeSet::new(), *transaction_digest, lamport_version, object_changes, @@ -1116,7 +1117,7 @@ impl<'backing> Storage for TemporaryStore<'backing> { fn check_coin_deny_list( &self, _written_objects: &BTreeMap, - ) -> Result<(), ExecutionError> { + ) -> (Result<(), ExecutionError>, u64) { unreachable!("Coin denylist v2 is not supported in sui-execution v1"); } } diff --git a/sui-execution/v2/sui-adapter/src/temporary_store.rs b/sui-execution/v2/sui-adapter/src/temporary_store.rs index 39d4dd7198c8c..3fedd389502e3 100644 --- a/sui-execution/v2/sui-adapter/src/temporary_store.rs +++ b/sui-execution/v2/sui-adapter/src/temporary_store.rs @@ -376,6 +376,7 @@ impl<'backing> TemporaryStore<'backing> { gas_cost_summary, // TODO: Provide the list of read-only shared objects directly. shared_object_refs, + BTreeSet::new(), *transaction_digest, lamport_version, object_changes, @@ -1168,7 +1169,7 @@ impl<'backing> Storage for TemporaryStore<'backing> { fn check_coin_deny_list( &self, _written_objects: &BTreeMap, - ) -> Result<(), ExecutionError> { + ) -> (Result<(), ExecutionError>, u64) { unreachable!("Coin denylist v2 is not supported in sui-execution v2"); } }