sui_adapter_latest/static_programmable_transactions/linkage/
analysis.rs1use 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_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 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}