Skip to content

Commit 846833b

Browse files
committed
Add resolution cache to avoid loading defining package if not needed
1 parent 2f7c7f4 commit 846833b

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,9 +1343,12 @@ mod checked {
13431343

13441344
// Load the package that the struct is defined in, in storage
13451345
let defining_id = ObjectID::from_address(*address);
1346+
let loading_id = linkage_view
1347+
.linkage_context_for_defining_id(defining_id)
1348+
.unwrap_or(defining_id);
13461349

13471350
let data_store = SuiDataStore::new(linkage_view, new_packages);
1348-
let move_package = get_package(&data_store, defining_id)?;
1351+
let move_package = get_package(&data_store, loading_id)?;
13491352

13501353
// Save the link context as we need to set it while loading the struct and we don't want to
13511354
// clobber it.

sui-execution/latest/sui-adapter/src/programmable_transactions/linkage_view.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ pub struct LinkageView<'state> {
3939
/// Cache of past package addresses that have been the link context -- if a package is in this
4040
/// set, then we will not try to load its type origin table when setting it as a context (again).
4141
past_contexts: RefCell<HashSet<ObjectID>>,
42+
/// A mapping from the defining ID of a type to a valid linkage context that has already been
43+
/// set. This is used to avoid double-loading packages for types that are already in the
44+
/// cache. Note that there may be multiple "valid" resolutions for a given defining ID, but we
45+
/// only care about having one of them so first one wins.
46+
context_resolution_cache: RefCell<BTreeMap<ObjectID, ObjectID>>,
4247
}
4348

4449
#[derive(Debug)]
@@ -57,6 +62,7 @@ impl<'state> LinkageView<'state> {
5762
linkage_info: None,
5863
type_origin_cache: RefCell::new(HashMap::new()),
5964
past_contexts: RefCell::new(HashSet::new()),
65+
context_resolution_cache: RefCell::new(BTreeMap::new()),
6066
}
6167
}
6268

@@ -126,6 +132,16 @@ impl<'state> LinkageView<'state> {
126132
package: defining_id,
127133
} in context.type_origin_table()
128134
{
135+
if !self
136+
.context_resolution_cache
137+
.borrow()
138+
.contains_key(defining_id)
139+
{
140+
self.context_resolution_cache
141+
.borrow_mut()
142+
.insert(*defining_id, storage_id);
143+
}
144+
129145
let Ok(module_name) = Identifier::from_str(module_name) else {
130146
invariant_violation!("Module name isn't an identifier: {module_name}");
131147
};
@@ -141,6 +157,13 @@ impl<'state> LinkageView<'state> {
141157
Ok(runtime_id)
142158
}
143159

160+
pub fn linkage_context_for_defining_id(&self, defining_id: ObjectID) -> Option<ObjectID> {
161+
self.context_resolution_cache
162+
.borrow()
163+
.get(&defining_id)
164+
.cloned()
165+
}
166+
144167
pub fn original_package_id(&self) -> Option<AccountAddress> {
145168
Some(self.linkage_info.as_ref()?.runtime_id)
146169
}

0 commit comments

Comments
 (0)