Skip to content

Commit

Permalink
[2][7/n][enums/Sui] Misc Sui changes for enums and enums in events
Browse files Browse the repository at this point in the history
  • Loading branch information
tzakian committed May 24, 2024
1 parent c0b029a commit 9f517f0
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 63 deletions.
21 changes: 11 additions & 10 deletions crates/sui-analytics-indexer/src/handlers/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@

use anyhow::Result;
use fastcrypto::encoding::{Base64, Encoding};
use move_core_types::annotated_value::MoveValue;
use sui_types::SYSTEM_PACKAGE_ADDRESSES;

use std::path::Path;
use sui_data_ingestion_core::Worker;
use tokio::sync::Mutex;

use crate::handlers::{get_move_struct, AnalyticsHandler};
use crate::handlers::AnalyticsHandler;
use crate::package_store::{LocalDBPackageStore, PackageCache};
use crate::tables::EventEntry;
use crate::FileType;
use sui_json_rpc_types::SuiMoveStruct;
use sui_json_rpc_types::type_and_fields_from_move_event_data;
use sui_package_resolver::Resolver;
use sui_rest_api::CheckpointData;
use sui_types::digests::TransactionDigest;
Expand Down Expand Up @@ -112,14 +113,14 @@ impl EventHandler {
type_,
contents,
} = event;
let move_struct = get_move_struct(type_, contents, &state.resolver).await?;
let (_struct_tag, sui_move_struct) = match move_struct.into() {
SuiMoveStruct::WithTypes { type_, fields } => {
(type_, SuiMoveStruct::WithFields(fields))
}
fields => (type_.clone(), fields),
};
let event_json = sui_move_struct.to_json_value();
let layout = state
.resolver
.type_layout(move_core_types::language_storage::TypeTag::Struct(
Box::new(type_.clone()),
))
.await?;
let move_value = MoveValue::simple_deserialize(contents, &layout)?;
let (_, event_json) = type_and_fields_from_move_event_data(move_value)?;
let entry = EventEntry {
transaction_digest: digest.base58_encode(),
event_index: idx as u64,
Expand Down
66 changes: 65 additions & 1 deletion crates/sui-analytics-indexer/src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ fn parse_struct_field(
parse_struct(path, move_struct, all_structs)
}
}
MoveValue::Variant(v) => {
for (k, field) in v.fields.iter() {
parse_struct_field(
&format!("{}.{}", path, k),
field.clone(),
curr_struct,
all_structs,
);
}
}
MoveValue::Vector(fields) => {
for (index, field) in fields.iter().enumerate() {
parse_struct_field(
Expand All @@ -276,7 +286,7 @@ fn parse_struct_field(
mod tests {
use crate::handlers::parse_struct;
use move_core_types::account_address::AccountAddress;
use move_core_types::annotated_value::{MoveStruct, MoveValue};
use move_core_types::annotated_value::{MoveStruct, MoveValue, MoveVariant};
use move_core_types::identifier::Identifier;
use move_core_types::language_storage::StructTag;
use std::collections::BTreeMap;
Expand Down Expand Up @@ -321,4 +331,58 @@ mod tests {
);
Ok(())
}

#[tokio::test]
async fn test_wrapped_object_parsing_within_enum() -> anyhow::Result<()> {
let uid_field = MoveValue::Struct(MoveStruct {
type_: StructTag::from_str("0x2::object::UID")?,
fields: vec![(
Identifier::from_str("id")?,
MoveValue::Struct(MoveStruct {
type_: StructTag::from_str("0x2::object::ID")?,
fields: vec![(
Identifier::from_str("bytes")?,
MoveValue::Signer(AccountAddress::from_hex_literal("0x300")?),
)],
}),
)],
});
let balance_field = MoveValue::Struct(MoveStruct {
type_: StructTag::from_str("0x2::balance::Balance")?,
fields: vec![(Identifier::from_str("value")?, MoveValue::U32(10))],
});
let move_enum = MoveVariant {
type_: StructTag::from_str("0x2::test::TestEnum")?,
variant_name: Identifier::from_str("TestVariant")?,
tag: 0,
fields: vec![
(Identifier::from_str("field0")?, MoveValue::U64(10)),
(Identifier::from_str("principal")?, balance_field),
],
};
let move_struct = MoveStruct {
type_: StructTag::from_str("0x2::test::Test")?,
fields: vec![
(Identifier::from_str("id")?, uid_field),
(
Identifier::from_str("enum_field")?,
MoveValue::Variant(move_enum),
),
],
};
let mut all_structs = BTreeMap::new();
parse_struct("$", move_struct, &mut all_structs);
assert_eq!(
all_structs.get("$").unwrap().object_id,
Some(ObjectID::from_hex_literal("0x300")?)
);
assert_eq!(
all_structs
.get("$.enum_field.principal")
.unwrap()
.struct_tag,
Some(StructTag::from_str("0x2::balance::Balance")?)
);
Ok(())
}
}
21 changes: 13 additions & 8 deletions crates/sui-core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use sui_config::node::{AuthorityOverloadConfig, StateDebugDumpConfig};
use sui_config::NodeConfig;
use sui_types::crypto::RandomnessRound;
use sui_types::execution_status::ExecutionStatus;
use sui_types::type_resolver::into_struct_layout;
use sui_types::type_resolver::LayoutResolver;
use tap::{TapFallible, TapOptional};
use tokio::sync::mpsc::unbounded_channel;
Expand Down Expand Up @@ -2232,7 +2233,9 @@ impl AuthorityState {
return Ok(None);
}

let layout = resolver.get_annotated_layout(&move_object.type_().clone().into())?;
let layout = into_struct_layout(
resolver.get_annotated_layout(&move_object.type_().clone().into())?,
)?;
let move_struct = move_object.to_move_struct(&layout)?;

let (name_value, type_, object_id) =
Expand Down Expand Up @@ -2447,12 +2450,12 @@ impl AuthorityState {
let layout = if let (LayoutGenerationOption::Generate, Some(move_obj)) =
(request.generate_layout, object.data.try_as_move())
{
Some(
Some(into_struct_layout(
self.load_epoch_store_one_call_per_task()
.executor()
.type_layout_resolver(Box::new(self.get_backing_package_store().as_ref()))
.get_annotated_layout(&move_obj.type_().clone().into())?,
)
)?)
} else {
None
};
Expand Down Expand Up @@ -3255,11 +3258,13 @@ impl AuthorityState {
.data
.try_as_move()
.map(|object| {
self.load_epoch_store_one_call_per_task()
.executor()
// TODO(cache) - must read through cache
.type_layout_resolver(Box::new(self.get_backing_package_store().as_ref()))
.get_annotated_layout(&object.type_().clone().into())
into_struct_layout(
self.load_epoch_store_one_call_per_task()
.executor()
// TODO(cache) - must read through cache
.type_layout_resolver(Box::new(self.get_backing_package_store().as_ref()))
.get_annotated_layout(&object.type_().clone().into())?,
)
})
.transpose()?;
Ok(layout)
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-core/src/unit_tests/move_package_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ macro_rules! type_origin_table {
{$($module:ident :: $type:ident => $pkg:expr),* $(,)?} => {{
vec![$(TypeOrigin {
module_name: stringify!($module).to_string(),
struct_name: stringify!($type).to_string(),
datatype_name: stringify!($type).to_string(),
package: $pkg,
},)*]
}}
Expand Down
15 changes: 8 additions & 7 deletions crates/sui-e2e-tests/tests/full_node_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::sync::Arc;
use sui::client_commands::{OptsWithGas, SuiClientCommandResult, SuiClientCommands};
use sui_config::node::RunWithRange;
use sui_json_rpc_types::{
type_and_fields_from_move_struct, EventPage, SuiEvent, SuiExecutionStatus,
type_and_fields_from_move_event_data, EventPage, SuiEvent, SuiExecutionStatus,
SuiTransactionBlockEffectsAPI, SuiTransactionBlockResponse, SuiTransactionBlockResponseOptions,
};
use sui_json_rpc_types::{EventFilter, TransactionFilter};
Expand All @@ -36,7 +36,7 @@ use sui_types::error::{SuiError, UserInputError};
use sui_types::event::{Event, EventID};
use sui_types::message_envelope::Message;
use sui_types::messages_grpc::TransactionInfoRequest;
use sui_types::object::{MoveObject, Object, ObjectRead, Owner, PastObjectRead};
use sui_types::object::{Object, ObjectRead, Owner, PastObjectRead};
use sui_types::programmable_transaction_builder::ProgrammableTransactionBuilder;
use sui_types::quorum_driver_types::{
ExecuteTransactionRequest, ExecuteTransactionRequestType, ExecuteTransactionResponse,
Expand All @@ -47,6 +47,7 @@ use sui_types::transaction::{
CallArg, GasData, TransactionData, TransactionKind, TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS,
TEST_ONLY_GAS_UNIT_FOR_SPLIT_COIN, TEST_ONLY_GAS_UNIT_FOR_TRANSFER,
};
use sui_types::type_resolver::get_layout_from_struct_tag;
use sui_types::utils::{
to_sender_signed_transaction, to_sender_signed_transaction_with_multi_signers,
};
Expand Down Expand Up @@ -694,14 +695,14 @@ async fn test_full_node_sub_and_query_move_event_ok() -> Result<(), anyhow::Erro
other => panic!("Failed to get SuiEvent, but {:?}", other),
};
let struct_tag = parse_struct_tag(&struct_tag_str).unwrap();
let layout = MoveObject::get_layout_from_struct_tag(
let layout = get_layout_from_struct_tag(
struct_tag.clone(),
&**node.state().epoch_store_for_testing().module_cache(),
)?;

let expected_parsed_event = Event::move_event_to_move_struct(&bcs, layout).unwrap();
let (_, expected_parsed_event) =
type_and_fields_from_move_struct(&struct_tag, expected_parsed_event);
let expected_parsed_event = Event::move_event_to_move_value(&bcs, layout).unwrap();
let (_, expected_parsed_events) =
type_and_fields_from_move_event_data(expected_parsed_event).unwrap();
let expected_event = SuiEvent {
id: EventID {
tx_digest: digest,
Expand All @@ -711,7 +712,7 @@ async fn test_full_node_sub_and_query_move_event_ok() -> Result<(), anyhow::Erro
transaction_module: ident_str!("devnet_nft").into(),
sender,
type_: struct_tag,
parsed_json: expected_parsed_event.to_json_value(),
parsed_json: expected_parsed_events,
bcs,
timestamp_ms: None,
};
Expand Down
8 changes: 7 additions & 1 deletion crates/sui-framework/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,17 @@ fn serialize_modules_to_file<'a>(
for module in modules {
let module_name = module.self_id().short_str_lossless();
for def in module.struct_defs() {
let sh = module.struct_handle_at(def.struct_handle);
let sh = module.datatype_handle_at(def.struct_handle);
let sn = module.identifier_at(sh.name);
members.push(format!("{sn}\n\tpublic struct\n\t{module_name}"));
}

for def in module.enum_defs() {
let eh = module.datatype_handle_at(def.enum_handle);
let en = module.identifier_at(eh.name);
members.push(format!("{en}\n\tpublic enum\n\t{module_name}"));
}

for def in module.function_defs() {
let fh = module.function_handle_at(def.function);
let fn_ = module.identifier_at(fh.name);
Expand Down
7 changes: 4 additions & 3 deletions crates/sui-framework/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ pub async fn compare_system_package<S: ObjectStore>(
}

let compatibility = Compatibility {
check_struct_and_pub_function_linking: true,
check_struct_layout: true,
check_datatype_and_pub_function_linking: true,
check_datatype_layout: true,
check_friend_linking: false,
// Checking `entry` linkage is required because system packages are updated in-place, and a
// transaction that was rolled back to make way for reconfiguration should still be runnable
Expand All @@ -237,7 +237,8 @@ pub async fn compare_system_package<S: ObjectStore>(
// fail if one of its mutable inputs was being used in another private `entry` function.
check_private_entry_linking: true,
disallowed_new_abilities: AbilitySet::singleton(Ability::Key),
disallow_change_struct_type_params: true,
disallow_change_datatype_type_params: true,
disallow_new_variants: true,
};

let new_pkg = new_object
Expand Down
16 changes: 5 additions & 11 deletions crates/sui-indexer/src/models/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ use std::str::FromStr;
use std::sync::Arc;

use diesel::prelude::*;

use move_core_types::annotated_value::MoveTypeLayout;
use move_core_types::identifier::Identifier;
use sui_json_rpc_types::{SuiEvent, SuiMoveStruct};

use sui_json_rpc_types::{type_and_fields_from_move_event_data, SuiEvent};
use sui_package_resolver::{PackageStore, Resolver};
use sui_types::base_types::{ObjectID, SuiAddress};
use sui_types::digests::TransactionDigest;
Expand Down Expand Up @@ -168,15 +167,10 @@ impl StoredEvent {
"Failed to convert to sui event with Error: {e}",
))
})?;
let move_struct_layout = match move_type_layout {
MoveTypeLayout::Struct(s) => Ok(s),
_ => Err(IndexerError::ResolveMoveStructError(
"MoveTypeLayout is not Struct".to_string(),
)),
}?;
let move_object = BoundedVisitor::deserialize_struct(&self.bcs, &move_struct_layout)
let move_object = BoundedVisitor::deserialize_value(&self.bcs, &move_type_layout)
.map_err(|e| IndexerError::SerdeError(e.to_string()))?;
let (_, parsed_json) = type_and_fields_from_move_event_data(move_object)
.map_err(|e| IndexerError::SerdeError(e.to_string()))?;
let parsed_json = SuiMoveStruct::from(move_object).to_json_value();
let tx_digest =
TransactionDigest::try_from(self.transaction_digest.as_slice()).map_err(|e| {
IndexerError::SerdeError(format!(
Expand Down
15 changes: 8 additions & 7 deletions crates/sui-indexer/src/models/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::Arc;

use diesel::prelude::*;

use move_core_types::annotated_value::MoveTypeLayout;
use move_core_types::annotated_value::{MoveDatatypeLayout, MoveTypeLayout};
use move_core_types::language_storage::TypeTag;
use sui_json_rpc_types::{
BalanceChange, ObjectChange, SuiEvent, SuiTransactionBlock, SuiTransactionBlockEffects,
Expand Down Expand Up @@ -554,26 +554,27 @@ pub async fn tx_events_to_sui_tx_events(
"Failed to convert to sui event with Error: {e}",
))
})?;
let event_move_struct_layouts = event_move_type_layouts
let event_move_datatype_layouts = event_move_type_layouts
.into_iter()
.filter_map(|move_type_layout| match move_type_layout {
MoveTypeLayout::Struct(s) => Some(s),
MoveTypeLayout::Struct(s) => Some(MoveDatatypeLayout::Struct(s)),
MoveTypeLayout::Enum(e) => Some(MoveDatatypeLayout::Enum(e)),
_ => None,
})
.collect::<Vec<_>>();
assert!(tx_events_data_len == event_move_struct_layouts.len());
assert!(tx_events_data_len == event_move_datatype_layouts.len());
let sui_events = tx_events
.data
.into_iter()
.enumerate()
.zip(event_move_struct_layouts)
.map(|((seq, tx_event), move_struct_layout)| {
.zip(event_move_datatype_layouts)
.map(|((seq, tx_event), move_datatype_layout)| {
SuiEvent::try_from(
tx_event,
tx_digest,
seq as u64,
Some(timestamp),
move_struct_layout,
move_datatype_layout,
)
})
.collect::<Result<Vec<_>, _>>()?;
Expand Down
4 changes: 2 additions & 2 deletions crates/sui-move-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ impl CompiledPackage {
}
let mut layout_builder = SerdeLayoutBuilder::new(self);
for typ in &package_types {
layout_builder.build_struct_layout(typ).unwrap();
layout_builder.build_data_layout(typ).unwrap();
}
layout_builder.into_registry()
}
Expand Down Expand Up @@ -615,7 +615,7 @@ impl PackageHooks for SuiPackageHooks {
&self,
manifest: &SourceManifest,
) -> anyhow::Result<PackageIdentifier> {
if manifest.package.edition == Some(Edition::DEVELOPMENT) {
if !cfg!(debug_assertions) && manifest.package.edition == Some(Edition::DEVELOPMENT) {
return Err(Edition::DEVELOPMENT.unknown_edition_error());
}
Ok(manifest.package.name)
Expand Down
5 changes: 4 additions & 1 deletion crates/sui-replay/src/displays/transaction_displays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,10 @@ fn resolve_to_layout(
}
TypeTag::Struct(inner) => {
let mut layout_resolver = executor.type_layout_resolver(Box::new(store_factory));
MoveTypeLayout::Struct(layout_resolver.get_annotated_layout(inner).unwrap())
layout_resolver
.get_annotated_layout(inner)
.unwrap()
.into_layout()
}
TypeTag::Bool => MoveTypeLayout::Bool,
TypeTag::U8 => MoveTypeLayout::U8,
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-tool/src/pkg_dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn dump_package(output_dir: &Path, id: SuiAddress, pkg: &[u8]) -> Result<()> {
.iter()
.map(|o| {
(
format!("{}::{}", o.module_name, o.struct_name),
format!("{}::{}", o.module_name, o.datatype_name),
o.package.to_string(),
)
})
Expand Down
Loading

0 comments on commit 9f517f0

Please sign in to comment.