sui_adapter_latest/static_programmable_transactions/linkage/
analysis.rs

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