Skip to content

Commit e004e16

Browse files
authored
[sui-adapter] abstract package metadata for linkage (#27430)
## Description Parametrize `PackageStore` by a `Package` type, and introduce package metadata trait constraint on this. This then parametrizes linkage analysis by the `PackageStore` and `PackageMetadata` accessor traits. This preserves existing behavior, and will allow us to use a non-VM/runtime-backed store (i.e., `BackingPackageStore`-backed store) for analysis at signing time in the PRs stacked on this. ## Test plan CI --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] gRPC: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] Indexing Framework:
1 parent 4a228cf commit e004e16

9 files changed

Lines changed: 108 additions & 80 deletions

File tree

sui-execution/latest/sui-adapter/src/data_store/cached_package_store.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ impl<'state, 'runtime> CachedPackageStore<'state, 'runtime> {
8686
}
8787

8888
impl PackageStore for CachedPackageStore<'_, '_> {
89-
fn get_package(&self, id: &ObjectID) -> SuiResult<Option<Arc<VerifiedPackage>>> {
89+
type Package = Arc<VerifiedPackage>;
90+
91+
fn get_package(&self, id: &ObjectID) -> SuiResult<Option<Self::Package>> {
9092
self.get_package(id)
9193
}
9294

sui-execution/latest/sui-adapter/src/data_store/mod.rs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,26 @@ pub mod cached_package_store;
55
pub mod transaction_package_store;
66

77
use move_core_types::identifier::IdentStr;
8-
use move_vm_runtime::validation::verification::ast::Package as VerifiedPackage;
9-
use std::sync::Arc;
8+
use move_vm_runtime::{
9+
shared::types::{OriginalId, VersionId},
10+
validation::verification::ast::Package as VerifiedPackage,
11+
};
12+
use std::{collections::BTreeMap, sync::Arc};
1013
use sui_types::{base_types::ObjectID, error::SuiResult};
1114

12-
// A unifying trait that allows us to resolve a type to its defining ID as well as load packages.
13-
// Some move packages that can be "loaded" via this may not be objects just yet (e.g., if
14-
// they were published in the current transaction). Note that this needs to load `MovePackage`s and
15-
// not `MovePackageObject`s because of this.
15+
/// The VM-independent package metadata required for linkage analysis.
16+
pub trait PackageMetadata {
17+
fn version(&self) -> u64;
18+
fn version_id(&self) -> ObjectID;
19+
fn original_id(&self) -> ObjectID;
20+
fn linkage_table(&self) -> BTreeMap<OriginalId, VersionId>;
21+
}
22+
23+
/// Access to package information needed for linkage analysis.
1624
pub trait PackageStore {
17-
fn get_package(&self, id: &ObjectID) -> SuiResult<Option<Arc<VerifiedPackage>>>;
25+
type Package: PackageMetadata;
26+
27+
fn get_package(&self, id: &ObjectID) -> SuiResult<Option<Self::Package>>;
1828

1929
fn resolve_type_to_defining_id(
2030
&self,
@@ -23,3 +33,27 @@ pub trait PackageStore {
2333
type_name: &IdentStr,
2434
) -> SuiResult<Option<ObjectID>>;
2535
}
36+
37+
/// A package store whose loaded packages have been verified by the Move VM.
38+
///
39+
/// Some move packages that can be loaded through this store may not be objects yet (for example,
40+
/// packages published in the current transaction).
41+
pub type VerifiedPackageStore<'a> = dyn PackageStore<Package = Arc<VerifiedPackage>> + 'a;
42+
43+
impl PackageMetadata for Arc<VerifiedPackage> {
44+
fn version(&self) -> u64 {
45+
VerifiedPackage::version(self.as_ref())
46+
}
47+
48+
fn version_id(&self) -> ObjectID {
49+
VerifiedPackage::version_id(self.as_ref()).into()
50+
}
51+
52+
fn original_id(&self) -> ObjectID {
53+
VerifiedPackage::original_id(self.as_ref()).into()
54+
}
55+
56+
fn linkage_table(&self) -> BTreeMap<OriginalId, VersionId> {
57+
VerifiedPackage::linkage_table(self.as_ref()).clone()
58+
}
59+
}

sui-execution/latest/sui-adapter/src/static_programmable_transactions/env.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! the `Env` provides consistent access to shared components such as the VM or the protocol config.
77
88
use crate::{
9-
data_store::{PackageStore, cached_package_store::CachedPackageStore},
9+
data_store::{VerifiedPackageStore, cached_package_store::CachedPackageStore},
1010
execution_mode::ExecutionMode,
1111
execution_value::ExecutionState,
1212
static_programmable_transactions::{
@@ -646,7 +646,7 @@ fn to_identifier<E: ExecutionErrorTrait>(name: String) -> Result<Identifier, E>
646646

647647
fn convert_vm_error<E: ExecutionErrorTrait>(
648648
error: VMError,
649-
store: &dyn PackageStore,
649+
store: &VerifiedPackageStore<'_>,
650650
linkage: Option<&ExecutableLinkage>,
651651
_protocol_config: &ProtocolConfig,
652652
) -> E {

sui-execution/latest/sui-adapter/src/static_programmable_transactions/linkage/analysis.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use crate::{
5-
data_store::PackageStore,
5+
data_store::VerifiedPackageStore,
66
execution_mode::ExecutionMode,
77
execution_value::ExecutionState,
88
static_programmable_transactions::{
@@ -17,6 +17,7 @@ use crate::{
1717
use move_binary_format::file_format::Visibility;
1818
use move_core_types::identifier::IdentStr;
1919
use move_vm_runtime::validation::verification::ast::Package as VerifiedPackage;
20+
use std::sync::Arc;
2021
use sui_protocol_config::ProtocolConfig;
2122
use sui_types::{
2223
base_types::ObjectID, error::ExecutionErrorTrait, execution_status::ExecutionErrorKind,
@@ -49,7 +50,7 @@ impl LinkageAnalyzer {
4950
module_name: &IdentStr,
5051
function_name: &IdentStr,
5152
type_args: &[Type],
52-
store: &dyn PackageStore,
53+
store: &VerifiedPackageStore<'_>,
5354
) -> Result<ExecutableLinkage, E> {
5455
Ok(ExecutableLinkage::new(
5556
ResolvedLinkage::from_resolution_table(self.compute_call_linkage_(
@@ -65,7 +66,7 @@ impl LinkageAnalyzer {
6566
pub fn compute_publication_linkage<E: ExecutionErrorTrait>(
6667
&self,
6768
deps: &[ObjectID],
68-
store: &dyn PackageStore,
69+
store: &VerifiedPackageStore<'_>,
6970
) -> Result<ResolvedLinkage, E> {
7071
Ok(ResolvedLinkage::from_resolution_table(
7172
self.compute_publication_linkage_(deps, store)?,
@@ -79,7 +80,7 @@ impl LinkageAnalyzer {
7980
pub fn compute_input_type_resolution_linkage<E: ExecutionErrorTrait>(
8081
&self,
8182
tx: &ProgrammableTransaction,
82-
package_store: &dyn PackageStore,
83+
package_store: &VerifiedPackageStore<'_>,
8384
object_store: &dyn ExecutionState,
8485
) -> Result<ExecutableLinkage, E> {
8586
input_type_resolution_analysis::compute_resolution_linkage(
@@ -96,16 +97,16 @@ impl LinkageAnalyzer {
9697
module_name: &IdentStr,
9798
function_name: &IdentStr,
9899
type_args: &[Type],
99-
store: &dyn PackageStore,
100+
store: &VerifiedPackageStore<'_>,
100101
) -> Result<ResolutionTable, E> {
101102
let mut resolution_table = self.internal.resolution_table_with_native_packages(store)?;
102103

103104
fn add_package<E: ExecutionErrorTrait>(
104105
object_id: &ObjectID,
105-
store: &dyn PackageStore,
106+
store: &VerifiedPackageStore<'_>,
106107
resolution_table: &mut ResolutionTable,
107-
self_resolution_fn: fn(&VerifiedPackage) -> Option<VersionConstraint>,
108-
dep_resolution_fn: fn(&VerifiedPackage) -> Option<VersionConstraint>,
108+
self_resolution_fn: fn(&Arc<VerifiedPackage>) -> Option<VersionConstraint>,
109+
dep_resolution_fn: fn(&Arc<VerifiedPackage>) -> Option<VersionConstraint>,
109110
) -> Result<(), E> {
110111
let pkg = get_package(object_id, store)?;
111112
let transitive_deps = resolution_table
@@ -171,7 +172,7 @@ impl LinkageAnalyzer {
171172
fn compute_publication_linkage_<E: ExecutionErrorTrait>(
172173
&self,
173174
deps: &[ObjectID],
174-
store: &dyn PackageStore,
175+
store: &VerifiedPackageStore<'_>,
175176
) -> Result<ResolutionTable, E> {
176177
let mut resolution_table = self.internal.resolution_table_with_native_packages(store)?;
177178
for id in deps {
@@ -183,7 +184,7 @@ impl LinkageAnalyzer {
183184

184185
mod input_type_resolution_analysis {
185186
use crate::{
186-
data_store::PackageStore,
187+
data_store::VerifiedPackageStore,
187188
execution_value::ExecutionState,
188189
static_programmable_transactions::linkage::{
189190
analysis::LinkageAnalyzer,
@@ -206,7 +207,7 @@ mod input_type_resolution_analysis {
206207
pub(super) fn compute_resolution_linkage<E: ExecutionErrorTrait>(
207208
analyzer: &LinkageAnalyzer,
208209
tx: &ProgrammableTransaction,
209-
package_store: &dyn PackageStore,
210+
package_store: &VerifiedPackageStore<'_>,
210211
object_store: &dyn ExecutionState,
211212
) -> Result<ExecutableLinkage, E> {
212213
let ProgrammableTransaction { inputs, commands } = tx;
@@ -230,7 +231,7 @@ mod input_type_resolution_analysis {
230231
fn input<E: ExecutionErrorTrait>(
231232
resolution_table: &mut ResolutionTable,
232233
arg: &CallArg,
233-
package_store: &dyn PackageStore,
234+
package_store: &VerifiedPackageStore<'_>,
234235
object_store: &dyn ExecutionState,
235236
) -> Result<(), E> {
236237
match arg {
@@ -268,7 +269,7 @@ mod input_type_resolution_analysis {
268269
fn command<E: ExecutionErrorTrait>(
269270
resolution_table: &mut ResolutionTable,
270271
command: &Command,
271-
package_store: &dyn PackageStore,
272+
package_store: &VerifiedPackageStore<'_>,
272273
) -> Result<(), E> {
273274
let mut add_ty_input = |ty: &TypeInput| -> Result<(), E> {
274275
let tag = ty.to_type_tag().map_err(|e| {

sui-execution/latest/sui-adapter/src/static_programmable_transactions/linkage/config.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44
use std::{collections::BTreeMap, rc::Rc, sync::Arc};
55

66
use crate::{
7-
data_store::PackageStore,
7+
data_store::{PackageMetadata, PackageStore},
88
static_programmable_transactions::linkage::resolution::{
99
ResolutionTable, VersionConstraint, add_and_unify,
1010
},
1111
};
1212
use move_binary_format::binary_config::BinaryConfig;
13-
use move_vm_runtime::{
14-
shared::types::{OriginalId, VersionId},
15-
validation::verification::ast::Package as VerifiedPackage,
16-
};
13+
use move_vm_runtime::shared::types::{OriginalId, VersionId};
1714
use sui_protocol_config::Amendments;
1815
use sui_types::{
1916
MOVE_STDLIB_PACKAGE_ID, SUI_FRAMEWORK_PACKAGE_ID, SUI_SYSTEM_PACKAGE_ID, base_types::ObjectID,
@@ -69,9 +66,12 @@ impl ResolutionConfig {
6966
&self.0.binary_config
7067
}
7168

72-
pub(crate) fn resolution_table_with_native_packages<E: ExecutionErrorTrait>(
69+
pub(crate) fn resolution_table_with_native_packages<
70+
E: ExecutionErrorTrait,
71+
S: PackageStore + ?Sized,
72+
>(
7373
&self,
74-
store: &dyn PackageStore,
74+
store: &S,
7575
) -> Result<ResolutionTable, E> {
7676
let mut resolution_table = ResolutionTable::empty(self.clone());
7777
if self.0.linkage_config.always_include_system_packages {
@@ -80,8 +80,8 @@ impl ResolutionConfig {
8080
{
8181
use crate::static_programmable_transactions::linkage::resolution::get_package;
8282
let package = get_package(id, store)?;
83-
debug_assert_eq!(package.version_id(), **id);
84-
debug_assert_eq!(package.original_id(), **id);
83+
debug_assert_eq!(package.version_id(), *id);
84+
debug_assert_eq!(package.original_id(), *id);
8585
}
8686
add_and_unify(id, store, &mut resolution_table, VersionConstraint::exact)?;
8787
}
@@ -90,10 +90,12 @@ impl ResolutionConfig {
9090
Ok(resolution_table)
9191
}
9292

93-
pub(crate) fn linkage_table(&self, pkg: &VerifiedPackage) -> BTreeMap<OriginalId, VersionId> {
94-
let linkage_table = pkg.linkage_table().clone();
93+
pub(crate) fn linkage_table<P: PackageMetadata>(
94+
&self,
95+
pkg: &P,
96+
) -> BTreeMap<OriginalId, VersionId> {
9597
self.linkage_config()
96-
.apply_linkage_amendments(pkg.version_id(), linkage_table)
98+
.apply_linkage_amendments(*pkg.version_id(), pkg.linkage_table())
9799
}
98100
}
99101

sui-execution/latest/sui-adapter/src/static_programmable_transactions/linkage/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub mod resolved_linkage;
88
pub mod single_linkage;
99

1010
use crate::{
11-
data_store::PackageStore,
11+
data_store::VerifiedPackageStore,
1212
execution_mode::ExecutionMode,
1313
static_programmable_transactions::{
1414
linkage::analysis::LinkageAnalyzer, loading::ast as loading,
@@ -21,7 +21,7 @@ use sui_protocol_config::ProtocolConfig;
2121
pub fn refine_linkage<Mode: ExecutionMode>(
2222
mut txn: loading::Transaction,
2323
linkage_analysis: &LinkageAnalyzer,
24-
package_store: &dyn PackageStore,
24+
package_store: &VerifiedPackageStore<'_>,
2525
protocol_config: &ProtocolConfig,
2626
) -> Result<loading::Transaction, Mode::Error> {
2727
if !protocol_config.enable_unified_linkage() {

sui-execution/latest/sui-adapter/src/static_programmable_transactions/linkage/resolution.rs

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use crate::{
5-
data_store::PackageStore, static_programmable_transactions::linkage::config::ResolutionConfig,
5+
data_store::{PackageMetadata, PackageStore},
6+
static_programmable_transactions::linkage::config::ResolutionConfig,
67
};
7-
use move_vm_runtime::validation::verification::ast::Package as VerifiedPackage;
88
use std::{
99
borrow::Borrow,
1010
collections::{BTreeMap, btree_map::Entry},
11-
sync::Arc,
12-
};
13-
use sui_types::{
14-
base_types::ObjectID, error::ExecutionErrorTrait, execution_status::ExecutionErrorKind,
1511
};
12+
use sui_types::base_types::ObjectID;
13+
use sui_types::{error::ExecutionErrorTrait, execution_status::ExecutionErrorKind};
1614

1715
/// Unifiers. These are used to determine how to unify two packages.
1816
#[derive(Debug, Clone)]
@@ -48,12 +46,9 @@ impl ResolutionTable {
4846
/// Given a list of object IDs, generate a `ResolvedLinkage` for them.
4947
/// Since this linkage analysis should only be used for types, all packages are resolved
5048
/// "upwards" (i.e., later versions of the package are preferred).
51-
pub fn add_type_linkages_to_table<I, E>(
52-
&mut self,
53-
ids: I,
54-
store: &dyn PackageStore,
55-
) -> Result<(), E>
49+
pub fn add_type_linkages_to_table<I, E, S>(&mut self, ids: I, store: &S) -> Result<(), E>
5650
where
51+
S: PackageStore + ?Sized,
5752
E: ExecutionErrorTrait,
5853
I: IntoIterator,
5954
I::Item: Borrow<ObjectID>,
@@ -65,7 +60,7 @@ impl ResolutionTable {
6560
.linkage_table(&pkg)
6661
.into_values()
6762
.map(ObjectID::from);
68-
let package_id = pkg.version_id().into();
63+
let package_id = pkg.version_id();
6964
add_and_unify(&package_id, store, self, VersionConstraint::at_least)?;
7065
for object_id in transitive_deps {
7166
add_and_unify(&object_id, store, self, VersionConstraint::at_least)?;
@@ -82,18 +77,12 @@ impl VersionConstraint {
8277
}
8378
}
8479

85-
pub fn exact(pkg: &VerifiedPackage) -> Option<VersionConstraint> {
86-
Some(VersionConstraint::Exact(
87-
pkg.version(),
88-
pkg.version_id().into(),
89-
))
80+
pub(crate) fn exact<P: PackageMetadata>(pkg: &P) -> Option<VersionConstraint> {
81+
Some(VersionConstraint::Exact(pkg.version(), pkg.version_id()))
9082
}
9183

92-
pub fn at_least(pkg: &VerifiedPackage) -> Option<VersionConstraint> {
93-
Some(VersionConstraint::AtLeast(
94-
pkg.version(),
95-
pkg.version_id().into(),
96-
))
84+
pub(crate) fn at_least<P: PackageMetadata>(pkg: &P) -> Option<VersionConstraint> {
85+
Some(VersionConstraint::AtLeast(pkg.version(), pkg.version_id()))
9786
}
9887

9988
pub fn unify<E: ExecutionErrorTrait>(
@@ -162,10 +151,10 @@ impl VersionConstraint {
162151

163152
/// Load a package from the store, and update the type origin map with the types in that
164153
/// package.
165-
pub(crate) fn get_package<E: ExecutionErrorTrait>(
154+
pub(crate) fn get_package<E: ExecutionErrorTrait, S: PackageStore + ?Sized>(
166155
object_id: &ObjectID,
167-
store: &dyn PackageStore,
168-
) -> Result<Arc<VerifiedPackage>, E> {
156+
store: &S,
157+
) -> Result<S::Package, E> {
169158
store
170159
.get_package(object_id)
171160
.map_err(|e| E::new_with_source(ExecutionErrorKind::PublishUpgradeMissingDependency, e))?
@@ -174,11 +163,11 @@ pub(crate) fn get_package<E: ExecutionErrorTrait>(
174163

175164
// Add a package to the unification table, unifying it with any existing package in the table.
176165
// Errors if the packages cannot be unified (e.g., if one is exact and the other is not).
177-
pub(crate) fn add_and_unify<E: ExecutionErrorTrait>(
166+
pub(crate) fn add_and_unify<E: ExecutionErrorTrait, S: PackageStore + ?Sized>(
178167
object_id: &ObjectID,
179-
store: &dyn PackageStore,
168+
store: &S,
180169
resolution_table: &mut ResolutionTable,
181-
resolution_fn: fn(&VerifiedPackage) -> Option<VersionConstraint>,
170+
resolution_fn: fn(&S::Package) -> Option<VersionConstraint>,
182171
) -> Result<(), E> {
183172
let package = get_package(object_id, store)?;
184173

@@ -187,7 +176,7 @@ pub(crate) fn add_and_unify<E: ExecutionErrorTrait>(
187176
// resolution table, and this does not contribute to the linkage analysis.
188177
return Ok(());
189178
};
190-
let original_pkg_id = package.original_id().into();
179+
let original_pkg_id = package.original_id();
191180

192181
if let Entry::Vacant(e) = resolution_table.resolution_table.entry(original_pkg_id) {
193182
e.insert(resolution);

0 commit comments

Comments
 (0)