sui_adapter_v0/
type_layout_resolver.rs

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