sui_adapter_latest/static_programmable_transactions/linkage/
analysis.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::rc::Rc;
5
6use crate::{
7    data_store::PackageStore,
8    execution_mode::ExecutionMode,
9    static_programmable_transactions::{
10        linkage::{
11            config::{LinkageConfig, ResolutionConfig},
12            resolution::{ResolutionTable, VersionConstraint, add_and_unify, get_package},
13            resolved_linkage::{ResolvedLinkage, RootedLinkage},
14        },
15        loading::ast::Type,
16    },
17};
18use sui_protocol_config::ProtocolConfig;
19use sui_types::{base_types::ObjectID, error::ExecutionError, transaction as P};
20
21#[derive(Debug)]
22pub struct LinkageAnalyzer {
23    internal: ResolutionConfig,
24}
25
26impl LinkageAnalyzer {
27    pub fn new<Mode: ExecutionMode>(
28        protocol_config: &ProtocolConfig,
29    ) -> Result<Self, ExecutionError> {
30        let always_include_system_packages = !Mode::packages_are_predefined();
31        let linkage_config = LinkageConfig::legacy_linkage_settings(always_include_system_packages);
32        let binary_config = protocol_config.binary_config(None);
33        Ok(Self {
34            internal: ResolutionConfig {
35                linkage_config,
36                binary_config,
37            },
38        })
39    }
40
41    pub fn compute_call_linkage(
42        &self,
43        move_call: &P::ProgrammableMoveCall,
44        store: &dyn PackageStore,
45    ) -> Result<ResolvedLinkage, ExecutionError> {
46        Ok(ResolvedLinkage::from_resolution_table(
47            self.compute_call_linkage_(move_call, store)?,
48        ))
49    }
50
51    pub fn compute_publication_linkage(
52        &self,
53        deps: &[ObjectID],
54        store: &dyn PackageStore,
55    ) -> Result<ResolvedLinkage, ExecutionError> {
56        Ok(ResolvedLinkage::from_resolution_table(
57            self.compute_publication_linkage_(deps, store)?,
58        ))
59    }
60
61    pub fn config(&self) -> &ResolutionConfig {
62        &self.internal
63    }
64
65    pub fn framework_call_linkage(
66        &self,
67        // Type arguments do not need to be included in the linkage in the current VM.
68        _type_args: &[Type],
69        store: &dyn PackageStore,
70    ) -> Result<RootedLinkage, ExecutionError> {
71        Ok(RootedLinkage {
72            link_context: *sui_types::SUI_FRAMEWORK_PACKAGE_ID,
73            resolved_linkage: Rc::new(ResolvedLinkage::from_resolution_table(
74                self.internal
75                    .linkage_config
76                    .resolution_table_with_native_packages(store)?,
77            )),
78        })
79    }
80
81    fn compute_call_linkage_(
82        &self,
83        move_call: &P::ProgrammableMoveCall,
84        store: &dyn PackageStore,
85    ) -> Result<ResolutionTable, ExecutionError> {
86        let mut resolution_table = self
87            .internal
88            .linkage_config
89            .resolution_table_with_native_packages(store)?;
90        let pkg = get_package(&move_call.package, store)?;
91        let transitive_deps = pkg
92            .linkage_table()
93            .values()
94            .map(|info| info.upgraded_id)
95            .collect::<Vec<_>>();
96        for object_id in transitive_deps.iter() {
97            add_and_unify(
98                object_id,
99                store,
100                &mut resolution_table,
101                VersionConstraint::exact,
102            )?;
103        }
104        add_and_unify(
105            &move_call.package,
106            store,
107            &mut resolution_table,
108            VersionConstraint::exact,
109        )?;
110        Ok(resolution_table)
111    }
112
113    /// Compute the linkage for a publish or upgrade command. This is a special case because
114    fn compute_publication_linkage_(
115        &self,
116        deps: &[ObjectID],
117        store: &dyn PackageStore,
118    ) -> Result<ResolutionTable, ExecutionError> {
119        let mut resolution_table = self
120            .internal
121            .linkage_config
122            .resolution_table_with_native_packages(store)?;
123        for id in deps {
124            add_and_unify(id, store, &mut resolution_table, VersionConstraint::exact)?;
125        }
126        Ok(resolution_table)
127    }
128}