Skip to content

Commit 4da3d3b

Browse files
Timothy Zakiantzakian
Timothy Zakian
authored andcommitted
[3/n][object runtime type tags] Add type tags to object runtime update adapter to handle them.
1 parent e04baee commit 4da3d3b

File tree

20 files changed

+388
-157
lines changed

20 files changed

+388
-157
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Mysten Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//# init --addresses Test=0x0
5+
6+
//# publish
7+
module Test::M1 {
8+
public struct X has key {
9+
id: UID,
10+
}
11+
12+
fun init(ctx: &mut TxContext) {
13+
sui::transfer::transfer(X { id: object::new(ctx) }, ctx.sender());
14+
}
15+
}
16+
17+
//# view-object 1,1
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs
3+
---
4+
processed 3 tasks
5+
6+
task 1, lines 6-15:
7+
//# publish
8+
created: object(1,0), object(1,1)
9+
mutated: object(0,0)
10+
gas summary: computation_cost: 1000000, storage_cost: 6216800, storage_rebate: 0, non_refundable_storage_fee: 0
11+
12+
task 2, line 17:
13+
//# view-object 1,1
14+
Owner: Account Address ( _ )
15+
Version: 2
16+
Contents: Test::M1::X {
17+
id: sui::object::UID {
18+
id: sui::object::ID {
19+
bytes: fake(1,1),
20+
},
21+
},
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Mysten Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//# init --addresses Test=0x0
5+
6+
//# publish
7+
module Test::M1 {
8+
public struct Event has copy, drop, store {
9+
x: u64,
10+
}
11+
12+
fun init(_ctx: &mut TxContext) {
13+
sui::event::emit(Event { x: 1 });
14+
}
15+
}
16+
17+
//# view-object 1,0
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs
3+
---
4+
processed 3 tasks
5+
6+
task 1, lines 6-15:
7+
//# publish
8+
events: Event { package_id: Test, transaction_module: Identifier("M1"), sender: _, type_: StructTag { address: Test, module: Identifier("M1"), name: Identifier("Event"), type_params: [] }, contents: [1, 0, 0, 0, 0, 0, 0, 0] }
9+
created: object(1,0)
10+
mutated: object(0,0)
11+
gas summary: computation_cost: 1000000, storage_cost: 4689200, storage_rebate: 0, non_refundable_storage_fee: 0
12+
13+
task 2, line 17:
14+
//# view-object 1,0
15+
1,0::M1

crates/sui-open-rpc/spec/openrpc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,7 @@
13731373
"soft_bundle": false,
13741374
"throughput_aware_consensus_submission": false,
13751375
"txn_base_cost_as_multiplier": false,
1376+
"type_tags_in_object_runtime": false,
13761377
"uncompressed_g1_group_elements": false,
13771378
"upgraded_multisig_supported": false,
13781379
"validate_identifier_inputs": false,

crates/sui-protocol-config/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,10 @@ struct FeatureFlags {
684684
// If true, resolves all type input ids to be defining ID based in the adapter
685685
#[serde(skip_serializing_if = "is_false")]
686686
resolve_type_input_ids_to_defining_id: bool,
687+
688+
// Signifies the cut-over of using type tags instead of `Type`s in the object runtime.
689+
#[serde(skip_serializing_if = "is_false")]
690+
type_tags_in_object_runtime: bool,
687691
}
688692

689693
fn is_false(b: &bool) -> bool {
@@ -1958,6 +1962,10 @@ impl ProtocolConfig {
19581962
pub fn resolve_type_input_ids_to_defining_id(&self) -> bool {
19591963
self.feature_flags.resolve_type_input_ids_to_defining_id
19601964
}
1965+
1966+
pub fn type_tags_in_object_runtime(&self) -> bool {
1967+
self.feature_flags.type_tags_in_object_runtime
1968+
}
19611969
}
19621970

19631971
#[cfg(not(msim))]
@@ -3495,6 +3503,7 @@ impl ProtocolConfig {
34953503
}
34963504
83 => {
34973505
cfg.feature_flags.resolve_type_input_ids_to_defining_id = true;
3506+
cfg.feature_flags.type_tags_in_object_runtime = true;
34983507
}
34993508
// Use this template when making changes:
35003509
//

crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_83.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ feature_flags:
8080
enforce_checkpoint_timestamp_monotonicity: true
8181
max_ptb_value_size_v2: true
8282
resolve_type_input_ids_to_defining_id: true
83+
type_tags_in_object_runtime: true
8384
max_tx_size_bytes: 131072
8485
max_input_objects: 2048
8586
max_size_written_objects: 5000000

crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_83.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ feature_flags:
9090
enforce_checkpoint_timestamp_monotonicity: true
9191
max_ptb_value_size_v2: true
9292
resolve_type_input_ids_to_defining_id: true
93+
type_tags_in_object_runtime: true
9394
max_tx_size_bytes: 131072
9495
max_input_objects: 2048
9596
max_size_written_objects: 5000000

crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_83.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ feature_flags:
9595
enforce_checkpoint_timestamp_monotonicity: true
9696
max_ptb_value_size_v2: true
9797
resolve_type_input_ids_to_defining_id: true
98+
type_tags_in_object_runtime: true
9899
max_tx_size_bytes: 131072
99100
max_input_objects: 2048
100101
max_size_written_objects: 5000000

external-crates/move/crates/move-vm-runtime/src/native_functions.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use move_core_types::{
2020
};
2121
use move_vm_config::runtime::VMRuntimeLimitsConfig;
2222
use move_vm_types::{
23-
loaded_data::runtime_types::Type, natives::function::NativeResult, values::Value,
23+
data_store::DataStore, loaded_data::runtime_types::Type, natives::function::NativeResult,
24+
values::Value,
2425
};
2526
use std::{
2627
cell::RefCell,
@@ -158,6 +159,46 @@ impl<'b> NativeContext<'_, 'b> {
158159
}
159160
}
160161

162+
// TODO: This is a bit hacky right now since we need to pass the store, however this is only
163+
// used in test scenarios so we have some special knowledge that makes this work. In the new VM
164+
// however this is _MUCH_ nicer as we don't need to pass the datastore as the VM's linkage
165+
// tables must have the type present.
166+
pub fn type_tag_to_fully_annotated_layout(
167+
&self,
168+
tag: &TypeTag,
169+
store: &impl DataStore,
170+
) -> PartialVMResult<Option<A::MoveTypeLayout>> {
171+
match self
172+
.resolver
173+
.loader()
174+
.get_fully_annotated_type_layout(tag, store)
175+
{
176+
Ok(ty_layout) => Ok(Some(ty_layout)),
177+
Err(e) if e.major_status().status_type() == StatusType::InvariantViolation => {
178+
Err(e.to_partial())
179+
}
180+
Err(_) => Ok(None),
181+
}
182+
}
183+
184+
// TODO: This is a bit hacky right now since we need to pass the store, however this is only
185+
// used in test scenarios so we have some special knowledge that makes this work. In the new VM
186+
// however this is _MUCH_ nicer as we don't need to pass the datastore as the VM's linkage
187+
// tables must have the type present.
188+
pub fn type_tag_to_layout(
189+
&self,
190+
tag: &TypeTag,
191+
store: &impl DataStore,
192+
) -> PartialVMResult<Option<R::MoveTypeLayout>> {
193+
match self.resolver.loader().get_type_layout(tag, store) {
194+
Ok(ty_layout) => Ok(Some(ty_layout)),
195+
Err(e) if e.major_status().status_type() == StatusType::InvariantViolation => {
196+
Err(e.to_partial())
197+
}
198+
Err(_) => Ok(None),
199+
}
200+
}
201+
161202
pub fn type_to_abilities(&self, ty: &Type) -> PartialVMResult<AbilitySet> {
162203
self.resolver.loader().abilities(ty)
163204
}

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

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ mod checked {
1515
},
1616
gas_charger::GasCharger,
1717
gas_meter::SuiGasMeter,
18-
programmable_transactions::{data_store::SuiDataStore, linkage_view::LinkageView},
18+
programmable_transactions::{
19+
data_store::{PackageStore, SuiDataStore},
20+
linkage_view::LinkageView,
21+
},
1922
type_resolver::TypeTagResolver,
2023
};
2124
use move_binary_format::{
@@ -59,7 +62,7 @@ mod checked {
5962
metrics::LimitsMetrics,
6063
move_package::MovePackage,
6164
object::{Authenticator, Data, MoveObject, Object, ObjectInner, Owner},
62-
storage::{BackingPackageStore, DenyListResult, PackageObject},
65+
storage::DenyListResult,
6366
transaction::{Argument, CallArg, ObjectArg},
6467
};
6568
use tracing::instrument;
@@ -285,10 +288,10 @@ mod checked {
285288
.unwrap_or(*package_id));
286289
}
287290

288-
let package = package_for_linkage(&self.linkage_view, package_id)
291+
let move_package = get_package(&self.linkage_view, package_id)
289292
.map_err(|e| self.convert_vm_error(e))?;
290293

291-
self.linkage_view.set_linkage(package.move_package())
294+
self.linkage_view.set_linkage(&move_package)
292295
}
293296

294297
/// Load a type using the context's current session.
@@ -341,7 +344,12 @@ mod checked {
341344
}
342345
let new_events = events
343346
.into_iter()
344-
.map(|(ty, tag, value)| {
347+
.map(|(tag, value)| {
348+
let ty = unwrap_type_tag_load(
349+
self.protocol_config,
350+
self.load_type_from_struct(&tag)
351+
.map_err(|e| self.convert_vm_error(e)),
352+
)?;
345353
let layout = self
346354
.vm
347355
.get_runtime()
@@ -704,7 +712,7 @@ mod checked {
704712
let Self {
705713
protocol_config,
706714
vm,
707-
linkage_view,
715+
mut linkage_view,
708716
mut native_extensions,
709717
tx_context,
710718
gas_charger,
@@ -839,12 +847,6 @@ mod checked {
839847
loaded_runtime_objects.extend(loaded_child_objects);
840848

841849
let mut written_objects = BTreeMap::new();
842-
for package in new_packages {
843-
let package_obj = Object::new_from_package(package, tx_digest);
844-
let id = package_obj.id();
845-
created_object_ids.insert(id);
846-
written_objects.insert(id, package_obj);
847-
}
848850
for (id, additional_write) in additional_writes {
849851
let AdditionalWrite {
850852
recipient,
@@ -872,7 +874,24 @@ mod checked {
872874
}
873875
}
874876

875-
for (id, (recipient, ty, value)) in writes {
877+
for (id, (recipient, tag, value)) in writes {
878+
let ty = unwrap_type_tag_load(
879+
protocol_config,
880+
load_type_from_struct(
881+
vm,
882+
&mut linkage_view,
883+
&new_packages,
884+
&StructTag::from(tag.clone()),
885+
)
886+
.map_err(|e| {
887+
convert_vm_error(
888+
e,
889+
vm,
890+
&linkage_view,
891+
protocol_config.resolve_abort_locations_to_package_id(),
892+
)
893+
}),
894+
)?;
876895
let abilities = vm.get_runtime().get_type_abilities(&ty).map_err(|e| {
877896
convert_vm_error(
878897
e,
@@ -910,6 +929,13 @@ mod checked {
910929
written_objects.insert(id, object);
911930
}
912931

932+
for package in new_packages {
933+
let package_obj = Object::new_from_package(package, tx_digest);
934+
let id = package_obj.id();
935+
created_object_ids.insert(id);
936+
written_objects.insert(id, package_obj);
937+
}
938+
913939
// Before finishing, ensure that any shared object taken by value by the transaction is either:
914940
// 1. Mutated (and still has a shared ownership); or
915941
// 2. Deleted.
@@ -1023,7 +1049,6 @@ mod checked {
10231049

10241050
/// Special case errors for type arguments to Move functions
10251051
pub fn convert_type_argument_error(&self, idx: usize, error: VMError) -> ExecutionError {
1026-
use move_core_types::vm_status::StatusCode;
10271052
use sui_types::execution_status::TypeArgumentError;
10281053
match error.major_status() {
10291054
StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH => {
@@ -1284,22 +1309,17 @@ mod checked {
12841309

12851310
/// Fetch the package at `package_id` with a view to using it as a link context. Produces an error
12861311
/// if the object at that ID does not exist, or is not a package.
1287-
fn package_for_linkage(
1288-
linkage_view: &LinkageView,
1312+
fn get_package(
1313+
package_store: &dyn PackageStore,
12891314
package_id: ObjectID,
1290-
) -> VMResult<PackageObject> {
1291-
use move_binary_format::errors::PartialVMError;
1292-
use move_core_types::vm_status::StatusCode;
1293-
1294-
match linkage_view.get_package_object(&package_id) {
1315+
) -> VMResult<Rc<MovePackage>> {
1316+
match package_store.get_package(&package_id) {
12951317
Ok(Some(package)) => Ok(package),
12961318
Ok(None) => Err(PartialVMError::new(StatusCode::LINKER_ERROR)
12971319
.with_message(format!("Cannot find link context {package_id} in store"))
12981320
.finish(Location::Undefined)),
12991321
Err(err) => Err(PartialVMError::new(StatusCode::LINKER_ERROR)
1300-
.with_message(format!(
1301-
"Error loading link context {package_id} from store: {err}"
1302-
))
1322+
.with_message(format!("Error loading {package_id} from store: {err}"))
13031323
.finish(Location::Undefined)),
13041324
}
13051325
}
@@ -1323,22 +1343,27 @@ mod checked {
13231343

13241344
// Load the package that the struct is defined in, in storage
13251345
let defining_id = ObjectID::from_address(*address);
1326-
let package = package_for_linkage(linkage_view, defining_id)?;
1346+
1347+
let data_store = SuiDataStore::new(linkage_view, new_packages);
1348+
let move_package = get_package(&data_store, defining_id)?;
1349+
1350+
// Save the link context as we need to set it while loading the struct and we don't want to
1351+
// clobber it.
1352+
let saved_linkage = linkage_view.steal_linkage();
13271353

13281354
// Set the defining package as the link context while loading the
13291355
// struct
13301356
let original_address = linkage_view
1331-
.set_linkage(package.move_package())
1332-
.map_err(|e| {
1333-
PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR)
1334-
.with_message(e.to_string())
1335-
.finish(Location::Undefined)
1336-
})?;
1357+
.set_linkage(&move_package)
1358+
.expect("Linkage context was just stolen. Therefore must be empty");
13371359

13381360
let runtime_id = ModuleId::new(original_address, module.clone());
13391361
let data_store = SuiDataStore::new(linkage_view, new_packages);
13401362
let res = vm.get_runtime().load_type(&runtime_id, name, &data_store);
13411363
linkage_view.reset_linkage();
1364+
linkage_view
1365+
.restore_linkage(saved_linkage)
1366+
.expect("Linkage context was just reset. Therefore must be empty");
13421367
let (idx, struct_type) = res?;
13431368

13441369
// Recursively load type parameters, if necessary
@@ -1707,6 +1732,17 @@ mod checked {
17071732
}
17081733
}
17091734

1735+
fn unwrap_type_tag_load(
1736+
protocol_config: &ProtocolConfig,
1737+
ty: Result<Type, ExecutionError>,
1738+
) -> Result<Type, ExecutionError> {
1739+
if ty.is_err() && !protocol_config.type_tags_in_object_runtime() {
1740+
panic!("Failed to load a type tag from the object runtime -- this shouldn't happen")
1741+
} else {
1742+
ty
1743+
}
1744+
}
1745+
17101746
enum EitherError {
17111747
CommandArgument(CommandArgumentError),
17121748
Execution(ExecutionError),

0 commit comments

Comments
 (0)