iota_adapter_latest/
type_layout_resolver.rs

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