Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move(visitor): expose underlying byte slice #19517

Merged
merged 16 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 21 additions & 24 deletions crates/sui-analytics-indexer/src/handlers/df_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use std::collections::HashMap;
use std::path::Path;
use sui_data_ingestion_core::Worker;
use sui_indexer::errors::IndexerError;
use sui_types::SYSTEM_PACKAGE_ADDRESSES;
use sui_types::object::bounded_visitor::BoundedVisitor;
use sui_types::{TypeTag, SYSTEM_PACKAGE_ADDRESSES};
use tap::tap::TapFallible;
use tokio::sync::Mutex;
use tracing::warn;
Expand All @@ -17,10 +18,11 @@ use sui_json_rpc_types::SuiMoveValue;
use sui_package_resolver::Resolver;
use sui_rest_api::{CheckpointData, CheckpointTransaction};
use sui_types::base_types::ObjectID;
use sui_types::dynamic_field::{DynamicFieldInfo, DynamicFieldName, DynamicFieldType};
use sui_types::dynamic_field::visitor as DFV;
use sui_types::dynamic_field::{DynamicFieldName, DynamicFieldType};
use sui_types::object::Object;

use crate::handlers::{get_move_struct, AnalyticsHandler};
use crate::handlers::AnalyticsHandler;
use crate::package_store::{LocalDBPackageStore, PackageCache};
use crate::tables::DynamicFieldEntry;
use crate::FileType;
Expand Down Expand Up @@ -114,28 +116,23 @@ impl DynamicFieldHandler {
if !move_object.type_().is_dynamic_field() {
return Ok(());
}
let move_struct = if let Some((tag, contents)) = object
.struct_tag()
.and_then(|tag| object.data.try_as_move().map(|mo| (tag, mo.contents())))
{
let move_struct = get_move_struct(&tag, contents, &state.resolver).await?;
Some(move_struct)
} else {
None
};
let Some(move_struct) = move_struct else {
return Ok(());
};
let (name_value, type_, object_id) =
DynamicFieldInfo::parse_move_object(&move_struct).tap_err(|e| warn!("{e}"))?;
let name_type = move_object.type_().try_extract_field_name(&type_)?;

let bcs_name = bcs::to_bytes(&name_value.clone().undecorate()).map_err(|e| {
IndexerError::SerdeError(format!(
"Failed to serialize dynamic field name {:?}: {e}",
name_value
))
})?;
let layout = state
.resolver
.type_layout(move_object.type_().clone().into())
.await?;
let object_id = object.id();

let field = DFV::FieldVisitor::deserialize(move_object.contents(), &layout)?;

let type_ = field.kind;
let name_type: TypeTag = field.name_layout.into();
let bcs_name = field.name_bytes.to_owned();

let name_value = BoundedVisitor::deserialize_value(field.name_bytes, field.name_layout)
.tap_err(|e| {
warn!("{e}");
})?;
let name = DynamicFieldName {
type_: name_type,
value: SuiMoveValue::from(name_value).to_json_value(),
Expand Down
67 changes: 43 additions & 24 deletions crates/sui-core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ use std::{
use sui_config::node::{AuthorityOverloadConfig, StateDebugDumpConfig};
use sui_config::NodeConfig;
use sui_types::crypto::RandomnessRound;
use sui_types::dynamic_field::visitor as DFV;
use sui_types::execution_status::ExecutionStatus;
use sui_types::inner_temporary_store::PackageStoreWithFallback;
use sui_types::layout_resolver::into_struct_layout;
use sui_types::layout_resolver::LayoutResolver;
use sui_types::messages_consensus::{AuthorityCapabilitiesV1, AuthorityCapabilitiesV2};
use sui_types::object::bounded_visitor::BoundedVisitor;
use tap::{TapFallible, TapOptional};
use tokio::sync::mpsc::unbounded_channel;
use tokio::sync::{mpsc, oneshot, RwLock};
Expand Down Expand Up @@ -83,7 +85,7 @@ use sui_types::crypto::{default_hash, AuthoritySignInfo, Signer};
use sui_types::deny_list_v1::check_coin_deny_list_v1;
use sui_types::digests::ChainIdentifier;
use sui_types::digests::TransactionEventsDigest;
use sui_types::dynamic_field::{DynamicFieldInfo, DynamicFieldName, DynamicFieldType};
use sui_types::dynamic_field::{DynamicFieldInfo, DynamicFieldName};
use sui_types::effects::{
InputSharedObject, SignedTransactionEffects, TransactionEffects, TransactionEffectsAPI,
TransactionEvents, VerifiedCertifiedTransactionEffects, VerifiedSignedTransactionEffects,
Expand Down Expand Up @@ -2381,34 +2383,59 @@ impl AuthorityState {
let Some(move_object) = o.data.try_as_move().cloned() else {
return Ok(None);
};

// We only index dynamic field objects
if !move_object.type_().is_dynamic_field() {
return Ok(None);
}

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

let (name_value, type_, object_id) =
DynamicFieldInfo::parse_move_object(&move_struct).tap_err(|e| warn!("{e}"))?;
let field =
DFV::FieldVisitor::deserialize(move_object.contents(), &layout).map_err(|e| {
SuiError::ObjectDeserializationError {
error: e.to_string(),
}
})?;

let name_type = move_object.type_().try_extract_field_name(&type_)?;
let type_ = field.kind;
let name_type: TypeTag = field.name_layout.into();
let bcs_name = field.name_bytes.to_owned();

let bcs_name = bcs::to_bytes(&name_value.clone().undecorate()).map_err(|e| {
SuiError::ObjectSerializationError {
error: format!("{e}"),
}
})?;
let name_value = BoundedVisitor::deserialize_value(field.name_bytes, field.name_layout)
.map_err(|e| {
warn!("{e}");
SuiError::ObjectDeserializationError {
error: e.to_string(),
}
})?;

let name = DynamicFieldName {
type_: name_type,
value: SuiMoveValue::from(name_value).to_json_value(),
};

Ok(Some(match type_ {
DynamicFieldType::DynamicObject => {
let value_metadata = field.value_metadata().map_err(|e| {
warn!("{e}");
SuiError::ObjectDeserializationError {
error: e.to_string(),
}
})?;

Ok(Some(match value_metadata {
DFV::ValueMetadata::DynamicField(object_type) => DynamicFieldInfo {
name,
bcs_name,
type_,
object_type: object_type.to_canonical_string(/* with_prefix */ true),
object_id: o.id(),
version: o.version(),
digest: o.digest(),
},

DFV::ValueMetadata::DynamicObjectField(object_id) => {
// Find the actual object from storage using the object id obtained from the wrapper.

// Try to find the object in the written objects first.
Expand All @@ -2431,6 +2458,7 @@ impl AuthorityState {
let object_type = object.data.type_().unwrap().clone();
(version, digest, object_type)
};

DynamicFieldInfo {
name,
bcs_name,
Expand All @@ -2441,15 +2469,6 @@ impl AuthorityState {
digest,
}
}
DynamicFieldType::DynamicField { .. } => DynamicFieldInfo {
name,
bcs_name,
type_,
object_type: move_object.into_type().into_type_params()[1].to_string(),
object_id: o.id(),
version: o.version(),
digest: o.digest(),
},
}))
}

Expand Down
57 changes: 19 additions & 38 deletions crates/sui-core/src/rest_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sui_types::base_types::ObjectID;
use sui_types::base_types::SequenceNumber;
use sui_types::base_types::SuiAddress;
use sui_types::digests::TransactionDigest;
use sui_types::dynamic_field::{DynamicFieldInfo, DynamicFieldType};
use sui_types::dynamic_field::visitor as DFV;
use sui_types::full_checkpoint_content::CheckpointData;
use sui_types::layout_resolver::LayoutResolver;
use sui_types::messages_checkpoint::CheckpointContents;
Expand Down Expand Up @@ -671,45 +671,26 @@ fn try_create_dynamic_field_info(
return Ok(None);
}

let (name_value, dynamic_field_type, object_id) = {
let layout = sui_types::layout_resolver::into_struct_layout(
resolver
.get_annotated_layout(&move_object.type_().clone().into())
.map_err(StorageError::custom)?,
)
.map_err(StorageError::custom)?;

let move_struct = move_object
.to_move_struct(&layout)
.map_err(StorageError::serialization)?;

// SAFETY: move struct has already been validated to be of type DynamicField
DynamicFieldInfo::parse_move_object(&move_struct).unwrap()
};

let name_type = move_object
.type_()
.try_extract_field_name(&dynamic_field_type)
.expect("object is of type Field");

let name_value = name_value
.undecorate()
.simple_serialize()
.expect("serialization cannot fail");

let dynamic_object_id = match dynamic_field_type {
DynamicFieldType::DynamicObject => Some(object_id),
DynamicFieldType::DynamicField => None,
};
let layout = resolver
.get_annotated_layout(&move_object.type_().clone().into())
.map_err(StorageError::custom)?
.into_layout();

let field_info = DynamicFieldIndexInfo {
name_type,
name_value,
dynamic_field_type,
dynamic_object_id,
};
let field = DFV::FieldVisitor::deserialize(move_object.contents(), &layout)
.map_err(StorageError::custom)?;

Ok(Some(field_info))
let value_metadata = field.value_metadata().map_err(StorageError::custom)?;

Ok(Some(DynamicFieldIndexInfo {
name_type: field.name_layout.into(),
name_value: field.name_bytes.to_owned(),
dynamic_field_type: field.kind,
dynamic_object_id: if let DFV::ValueMetadata::DynamicObjectField(id) = value_metadata {
Some(id)
} else {
None
},
}))
}

fn try_create_coin_index_info(object: &Object) -> Option<(CoinIndexKey, CoinIndexInfo)> {
Expand Down
Loading
Loading