sui_adapter_latest/
type_layout_resolver.rs1use crate::data_store::cached_package_store::CachedPackageStore;
5use crate::data_store::transaction_package_store::TransactionPackageStore;
6use crate::static_programmable_transactions::linkage::config::{LinkageConfig, ResolutionConfig};
7use crate::static_programmable_transactions::linkage::resolved_linkage::ExecutableLinkage;
8use move_core_types::annotated_value as A;
9use move_core_types::language_storage::StructTag;
10use move_vm_runtime::runtime::MoveRuntime;
11use sui_protocol_config::ProtocolConfig;
12use sui_types::TypeTag;
13use sui_types::base_types::ObjectID;
14use sui_types::error::{SuiErrorKind, SuiResult};
15use sui_types::execution::TypeLayoutStore;
16use sui_types::storage::{BackingPackageStore, PackageObject};
17use sui_types::{error::SuiError, layout_resolver::LayoutResolver};
18
19pub struct TypeLayoutResolver<'state, 'runtime> {
21 vm: &'runtime MoveRuntime,
22 protocol_config: &'runtime ProtocolConfig,
23 state_view: Box<dyn TypeLayoutStore + 'state>,
24}
25
26struct NullSuiResolver<'a, 'state>(&'a (dyn TypeLayoutStore + 'state));
29
30impl<'state, 'runtime> TypeLayoutResolver<'state, 'runtime> {
31 pub fn new(
32 vm: &'runtime MoveRuntime,
33 protocol_config: &'runtime ProtocolConfig,
34 state_view: Box<dyn TypeLayoutStore + 'state>,
35 ) -> Self {
36 Self {
37 vm,
38 protocol_config,
39 state_view,
40 }
41 }
42}
43
44impl LayoutResolver for TypeLayoutResolver<'_, '_> {
45 fn get_annotated_layout(
46 &mut self,
47 struct_tag: &StructTag,
48 ) -> Result<A::MoveDatatypeLayout, SuiError> {
49 let ids = struct_tag.all_addresses().into_iter().map(ObjectID::from);
50 let null_resolver = NullSuiResolver(&self.state_view);
51 let resolver =
52 CachedPackageStore::new(self.vm, TransactionPackageStore::new(&null_resolver));
53 let config = ResolutionConfig::new(
54 LinkageConfig::new(
55 self.protocol_config
56 .include_special_package_amendments_as_option()
57 .clone(),
58 true,
59 ),
60 self.protocol_config.binary_config(None),
61 );
62 let tag_linkage = ExecutableLinkage::type_linkage(config, ids, &resolver)?;
63 let link_context = tag_linkage.linkage_context()?;
64 let data_store = TransactionPackageStore::new(&null_resolver);
65 let Ok(vm) = self.vm.make_vm(data_store, link_context) else {
66 return Err(SuiErrorKind::FailObjectLayout {
67 st: format!("{}", struct_tag),
68 }
69 .into());
70 };
71
72 let type_tag = TypeTag::Struct(Box::new(struct_tag.clone()));
73 match vm.annotated_type_layout(&type_tag) {
74 Ok(A::MoveTypeLayout::Struct(s)) => Ok(A::MoveDatatypeLayout::Struct(s)),
75 Ok(A::MoveTypeLayout::Enum(e)) => Ok(A::MoveDatatypeLayout::Enum(e)),
76 _ => Err(SuiErrorKind::FailObjectLayout {
77 st: format!("{}", struct_tag),
78 }
79 .into()),
80 }
81 }
82}
83
84impl BackingPackageStore for NullSuiResolver<'_, '_> {
85 fn get_package_object(&self, package_id: &ObjectID) -> SuiResult<Option<PackageObject>> {
86 self.0.get_package_object(package_id)
87 }
88}