sui_adapter_latest/
type_layout_resolver.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::data_store::cached_package_store::CachedPackageStore;
5use crate::data_store::legacy::linkage_view::LinkageView;
6use crate::programmable_transactions::context::load_type_from_struct;
7use move_core_types::annotated_value as A;
8use move_core_types::language_storage::StructTag;
9use move_vm_runtime::move_vm::MoveVM;
10use sui_types::base_types::ObjectID;
11use sui_types::error::{SuiErrorKind, SuiResult};
12use sui_types::execution::TypeLayoutStore;
13use sui_types::storage::{BackingPackageStore, PackageObject};
14use sui_types::{error::SuiError, layout_resolver::LayoutResolver};
15
16/// Retrieve a `MoveStructLayout` from a `Type`.
17/// Invocation into the `Session` to leverage the `LinkageView` implementation
18/// common to the runtime.
19pub struct TypeLayoutResolver<'state, 'vm> {
20    vm: &'vm MoveVM,
21    linkage_view: LinkageView<'state>,
22}
23
24/// Implements SuiResolver traits by providing null implementations for module and resource
25/// resolution and delegating backing package resolution to the trait object.
26struct NullSuiResolver<'state>(Box<dyn TypeLayoutStore + 'state>);
27
28impl<'state, 'vm> TypeLayoutResolver<'state, 'vm> {
29    pub fn new(vm: &'vm MoveVM, state_view: Box<dyn TypeLayoutStore + 'state>) -> Self {
30        let linkage_view = LinkageView::new(Box::new(CachedPackageStore::new(Box::new(
31            NullSuiResolver(state_view),
32        ))));
33        Self { vm, linkage_view }
34    }
35}
36
37impl LayoutResolver for TypeLayoutResolver<'_, '_> {
38    fn get_annotated_layout(
39        &mut self,
40        struct_tag: &StructTag,
41    ) -> Result<A::MoveDatatypeLayout, SuiError> {
42        let Ok(ty) = load_type_from_struct(self.vm, &self.linkage_view, &[], struct_tag) else {
43            return Err(SuiErrorKind::FailObjectLayout {
44                st: format!("{}", struct_tag),
45            }
46            .into());
47        };
48        let layout = self.vm.get_runtime().type_to_fully_annotated_layout(&ty);
49        match layout {
50            Ok(A::MoveTypeLayout::Struct(s)) => Ok(A::MoveDatatypeLayout::Struct(s)),
51            Ok(A::MoveTypeLayout::Enum(e)) => Ok(A::MoveDatatypeLayout::Enum(e)),
52            _ => Err(SuiErrorKind::FailObjectLayout {
53                st: format!("{}", struct_tag),
54            }
55            .into()),
56        }
57    }
58}
59
60impl BackingPackageStore for NullSuiResolver<'_> {
61    fn get_package_object(&self, package_id: &ObjectID) -> SuiResult<Option<PackageObject>> {
62        self.0.get_package_object(package_id)
63    }
64}