Skip to content

Commit

Permalink
Redo Effects v2 protocol change (#14085)
Browse files Browse the repository at this point in the history
## Description 

This PR adds a new feature flag in the protocol config to enable effects
v2 (devnet only at the moment).
When effects v2 is enabled, the system will start emitting effects v2
type.
This is done inside TemporaryStore, where depending on the feature flag,
we call different constructors of TransactionEffects.
The previous attempt did not properly gate this change under the feature
flag, which is fixed by this PR (see the second commit in this PR).
In order to be compatible with effects v1 (under old protocol), we need
to reconstruct all the different v1 fields.
These code can be cleaned up once we cut a new sui-execution version.

## Test Plan 

CI

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
lxfind authored Oct 10, 2023
1 parent 8815756 commit 6ade193
Show file tree
Hide file tree
Showing 17 changed files with 614 additions and 307 deletions.
6 changes: 6 additions & 0 deletions crates/sui-core/src/generate_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rand::SeedableRng;
use serde_reflection::{Registry, Result, Samples, Tracer, TracerConfig};
use shared_crypto::intent::{Intent, IntentMessage, PersonalMessage};
use std::{fs::File, io::Write};
use sui_types::effects::{IDOperation, ObjectIn, ObjectOut, TransactionEffects};
use sui_types::execution_status::{
CommandArgumentError, ExecutionFailureStatus, ExecutionStatus, PackageUpgradeError,
TypeArgumentError,
Expand Down Expand Up @@ -159,6 +160,11 @@ fn get_registry() -> Result<Registry> {
tracer.trace_type::<TransactionExpiration>(&samples)?;
tracer.trace_type::<EndOfEpochTransactionKind>(&samples)?;

tracer.trace_type::<IDOperation>(&samples)?;
tracer.trace_type::<ObjectIn>(&samples)?;
tracer.trace_type::<ObjectOut>(&samples)?;
tracer.trace_type::<TransactionEffects>(&samples)?;

// uncomment once GenericSignature is added
tracer.trace_type::<FullCheckpointContents>(&samples)?;
tracer.trace_type::<CheckpointContents>(&samples)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ async fn test_upgrade_package_incorrect_digest() {
async fn test_upgrade_package_compatibility_too_permissive() {
let mut runner = UpgradeStateRunner::new("move_upgrade/base").await;

let TransactionEffects::V1(effects) = runner
let effects = runner
.run({
let mut builder = ProgrammableTransactionBuilder::new();
let cap = builder
Expand Down
104 changes: 50 additions & 54 deletions crates/sui-core/src/unit_tests/transfer_to_object_tests.rs

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions crates/sui-core/tests/staged/sui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,17 @@ ECMHLiveObjectSetDigest:
STRUCT:
- digest:
TYPENAME: Digest
EffectsAuxDataDigest:
NEWTYPESTRUCT:
TYPENAME: Digest
EffectsObjectChange:
STRUCT:
- input_state:
TYPENAME: ObjectIn
- output_state:
TYPENAME: ObjectOut
- id_operation:
TYPENAME: IDOperation
EmptySignInfo:
STRUCT: []
EndOfEpochData:
Expand Down Expand Up @@ -452,6 +463,14 @@ GenesisTransaction:
- objects:
SEQ:
TYPENAME: GenesisObject
IDOperation:
ENUM:
0:
None: UNIT
1:
Created: UNIT
2:
Deleted: UNIT
Identifier:
NEWTYPESTRUCT: STR
Intent:
Expand Down Expand Up @@ -637,6 +656,18 @@ ObjectDigest:
ObjectID:
NEWTYPESTRUCT:
TYPENAME: AccountAddress
ObjectIn:
ENUM:
0:
NotExist: UNIT
1:
Exist:
NEWTYPE:
TUPLE:
- TUPLE:
- TYPENAME: SequenceNumber
- TYPENAME: ObjectDigest
- TYPENAME: Owner
ObjectInfoRequestKind:
ENUM:
0:
Expand All @@ -645,6 +676,22 @@ ObjectInfoRequestKind:
PastObjectInfoDebug:
NEWTYPE:
TYPENAME: SequenceNumber
ObjectOut:
ENUM:
0:
NotExist: UNIT
1:
ObjectWrite:
NEWTYPE:
TUPLE:
- TYPENAME: ObjectDigest
- TYPENAME: Owner
2:
PackageWrite:
NEWTYPE:
TUPLE:
- TYPENAME: SequenceNumber
- TYPENAME: ObjectDigest
Owner:
ENUM:
0:
Expand Down Expand Up @@ -790,6 +837,10 @@ TransactionEffects:
V1:
NEWTYPE:
TYPENAME: TransactionEffectsV1
1:
V2:
NEWTYPE:
TYPENAME: TransactionEffectsV2
TransactionEffectsDigest:
NEWTYPESTRUCT:
TYPENAME: Digest
Expand Down Expand Up @@ -868,6 +919,38 @@ TransactionEffectsV1:
- dependencies:
SEQ:
TYPENAME: TransactionDigest
TransactionEffectsV2:
STRUCT:
- status:
TYPENAME: ExecutionStatus
- executed_epoch: U64
- gas_used:
TYPENAME: GasCostSummary
- transaction_digest:
TYPENAME: TransactionDigest
- gas_object_index:
OPTION: U32
- events_digest:
OPTION:
TYPENAME: TransactionEventsDigest
- dependencies:
SEQ:
TYPENAME: TransactionDigest
- lamport_version:
TYPENAME: SequenceNumber
- changed_objects:
SEQ:
TUPLE:
- TYPENAME: ObjectID
- TYPENAME: EffectsObjectChange
- unchanged_shared_objects:
SEQ:
TUPLE:
- TYPENAME: ObjectID
- TYPENAME: UnchangedSharedKind
- aux_data_digest:
OPTION:
TYPENAME: EffectsAuxDataDigest
TransactionEventsDigest:
NEWTYPESTRUCT:
TYPENAME: Digest
Expand Down Expand Up @@ -962,6 +1045,14 @@ TypedStoreError:
MetricsReporting: UNIT
5:
RetryableTransactionError: UNIT
UnchangedSharedKind:
ENUM:
0:
ReadOnlyRoot:
NEWTYPE:
TUPLE:
- TYPENAME: SequenceNumber
- TYPENAME: ObjectDigest
UpgradeInfo:
STRUCT:
- upgraded_id:
Expand Down
81 changes: 34 additions & 47 deletions crates/sui-json-rpc-types/src/sui_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,56 +638,43 @@ impl TryFrom<TransactionEffects> for SuiTransactionBlockEffects {
type Error = SuiError;

fn try_from(effect: TransactionEffects) -> Result<Self, Self::Error> {
let message_version = effect
.message_version()
.expect("TransactionEffects defines message_version()");

match message_version {
1 => Ok(SuiTransactionBlockEffects::V1(
SuiTransactionBlockEffectsV1 {
status: effect.status().clone().into(),
executed_epoch: effect.executed_epoch(),
modified_at_versions: effect
.modified_at_versions()
Ok(SuiTransactionBlockEffects::V1(
SuiTransactionBlockEffectsV1 {
status: effect.status().clone().into(),
executed_epoch: effect.executed_epoch(),
modified_at_versions: effect
.modified_at_versions()
.into_iter()
.map(|(object_id, sequence_number)| {
SuiTransactionBlockEffectsModifiedAtVersions {
object_id,
sequence_number,
}
})
.collect(),
gas_used: effect.gas_cost_summary().clone(),
shared_objects: to_sui_object_ref(
effect
.input_shared_objects()
.into_iter()
.map(|(object_id, sequence_number)| {
SuiTransactionBlockEffectsModifiedAtVersions {
object_id,
sequence_number,
}
})
.map(|(obj_ref, _)| obj_ref)
.collect(),
gas_used: effect.gas_cost_summary().clone(),
shared_objects: to_sui_object_ref(
effect
.input_shared_objects()
.into_iter()
.map(|(obj_ref, _)| obj_ref)
.collect(),
),
transaction_digest: *effect.transaction_digest(),
created: to_owned_ref(effect.created()),
mutated: to_owned_ref(effect.mutated().to_vec()),
unwrapped: to_owned_ref(effect.unwrapped().to_vec()),
deleted: to_sui_object_ref(effect.deleted().to_vec()),
unwrapped_then_deleted: to_sui_object_ref(
effect.unwrapped_then_deleted().to_vec(),
),
wrapped: to_sui_object_ref(effect.wrapped().to_vec()),
gas_object: OwnedObjectRef {
owner: effect.gas_object().1,
reference: effect.gas_object().0.into(),
},
events_digest: effect.events_digest().copied(),
dependencies: effect.dependencies().to_vec(),
),
transaction_digest: *effect.transaction_digest(),
created: to_owned_ref(effect.created()),
mutated: to_owned_ref(effect.mutated().to_vec()),
unwrapped: to_owned_ref(effect.unwrapped().to_vec()),
deleted: to_sui_object_ref(effect.deleted().to_vec()),
unwrapped_then_deleted: to_sui_object_ref(effect.unwrapped_then_deleted().to_vec()),
wrapped: to_sui_object_ref(effect.wrapped().to_vec()),
gas_object: OwnedObjectRef {
owner: effect.gas_object().1,
reference: effect.gas_object().0.into(),
},
)),

_ => Err(SuiError::UnexpectedVersion(format!(
"Support for TransactionEffects version {} not implemented",
message_version
))),
}
events_digest: effect.events_digest().copied(),
dependencies: effect.dependencies().to_vec(),
},
))
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/sui-open-rpc/spec/openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,7 @@
"disable_invariant_violation_check_in_swap_loc": false,
"disallow_adding_abilities_on_upgrade": false,
"disallow_change_struct_type_params_on_upgrade": false,
"enable_effects_v2": false,
"enable_jwk_consensus_updates": false,
"end_of_epoch_transaction_supported": false,
"loaded_child_object_format": false,
Expand Down
11 changes: 11 additions & 0 deletions crates/sui-protocol-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ struct FeatureFlags {
// Enable receiving sent objects
#[serde(skip_serializing_if = "is_false")]
receive_objects: bool,

#[serde(skip_serializing_if = "is_false")]
enable_effects_v2: bool,
}

fn is_false(b: &bool) -> bool {
Expand Down Expand Up @@ -945,6 +948,10 @@ impl ProtocolConfig {
pub fn create_authenticator_state_in_genesis(&self) -> bool {
self.enable_jwk_consensus_updates()
}

pub fn enable_effects_v2(&self) -> bool {
self.feature_flags.enable_effects_v2
}
}

#[cfg(not(msim))]
Expand Down Expand Up @@ -1514,6 +1521,10 @@ impl ProtocolConfig {
cfg.check_zklogin_id_cost_base = Some(200);
// zklogin::check_zklogin_issuer
cfg.check_zklogin_issuer_cost_base = Some(200);
// Only enable effects v2 on devnet.
if chain != Chain::Mainnet && chain != Chain::Testnet {
cfg.feature_flags.enable_effects_v2 = true;
}
}
// Use this template when making changes:
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ feature_flags:
simple_conservation_checks: true
loaded_child_object_format_type: true
receive_objects: true
enable_effects_v2: true
max_tx_size_bytes: 131072
max_input_objects: 2048
max_size_written_objects: 5000000
Expand Down
54 changes: 54 additions & 0 deletions crates/sui-types/src/digests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,60 @@ impl std::str::FromStr for TransactionEventsDigest {
}
}

#[serde_as]
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Hash, Serialize, Deserialize, JsonSchema)]
pub struct EffectsAuxDataDigest(Digest);

impl EffectsAuxDataDigest {
pub const ZERO: Self = Self(Digest::ZERO);

pub const fn new(digest: [u8; 32]) -> Self {
Self(Digest::new(digest))
}

pub fn random() -> Self {
Self(Digest::random())
}

pub fn next_lexicographical(&self) -> Option<Self> {
self.0.next_lexicographical().map(Self)
}

pub fn into_inner(self) -> [u8; 32] {
self.0.into_inner()
}
}

impl fmt::Debug for EffectsAuxDataDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("EffectsAuxDataDigest")
.field(&self.0)
.finish()
}
}

impl AsRef<[u8]> for EffectsAuxDataDigest {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl AsRef<[u8; 32]> for EffectsAuxDataDigest {
fn as_ref(&self) -> &[u8; 32] {
self.0.as_ref()
}
}

impl std::str::FromStr for EffectsAuxDataDigest {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut result = [0; 32];
result.copy_from_slice(&Base58::decode(s).map_err(|e| anyhow::anyhow!(e))?);
Ok(Self::new(result))
}
}

// Each object has a unique digest
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema)]
pub struct ObjectDigest(Digest);
Expand Down
Loading

1 comment on commit 6ade193

@vercel
Copy link

@vercel vercel bot commented on 6ade193 Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.