-
Notifications
You must be signed in to change notification settings - Fork 11.5k
[3/n][object runtime type tags] Add type tags to object runtime update adapter to handle them #22092
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3/n][object runtime type tags] Add type tags to object runtime update adapter to handle them #22092
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
//# init --addresses Test=0x0 | ||
|
||
//# publish | ||
module Test::M1 { | ||
public struct X has key { | ||
id: UID, | ||
} | ||
|
||
fun init(ctx: &mut TxContext) { | ||
sui::transfer::transfer(X { id: object::new(ctx) }, ctx.sender()); | ||
} | ||
} | ||
|
||
//# view-object 1,1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs | ||
--- | ||
processed 3 tasks | ||
|
||
task 1, lines 6-15: | ||
//# publish | ||
created: object(1,0), object(1,1) | ||
mutated: object(0,0) | ||
gas summary: computation_cost: 1000000, storage_cost: 6216800, storage_rebate: 0, non_refundable_storage_fee: 0 | ||
|
||
task 2, line 17: | ||
//# view-object 1,1 | ||
Owner: Account Address ( _ ) | ||
Version: 2 | ||
Contents: Test::M1::X { | ||
id: sui::object::UID { | ||
id: sui::object::ID { | ||
bytes: fake(1,1), | ||
}, | ||
}, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
//# init --addresses Test=0x0 | ||
|
||
//# publish | ||
module Test::M1 { | ||
public struct Event has copy, drop, store { | ||
x: u64, | ||
} | ||
|
||
fun init(_ctx: &mut TxContext) { | ||
sui::event::emit(Event { x: 1 }); | ||
} | ||
} | ||
|
||
//# view-object 1,0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--- | ||
source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs | ||
--- | ||
processed 3 tasks | ||
|
||
task 1, lines 6-15: | ||
//# publish | ||
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] } | ||
created: object(1,0) | ||
mutated: object(0,0) | ||
gas summary: computation_cost: 1000000, storage_cost: 4689200, storage_rebate: 0, non_refundable_storage_fee: 0 | ||
|
||
task 2, line 17: | ||
//# view-object 1,0 | ||
1,0::M1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,10 @@ mod checked { | |
}, | ||
gas_charger::GasCharger, | ||
gas_meter::SuiGasMeter, | ||
programmable_transactions::{data_store::SuiDataStore, linkage_view::LinkageView}, | ||
programmable_transactions::{ | ||
data_store::{PackageStore, SuiDataStore}, | ||
linkage_view::LinkageView, | ||
}, | ||
type_resolver::TypeTagResolver, | ||
}; | ||
use move_binary_format::{ | ||
|
@@ -59,7 +62,7 @@ mod checked { | |
metrics::LimitsMetrics, | ||
move_package::MovePackage, | ||
object::{Authenticator, Data, MoveObject, Object, ObjectInner, Owner}, | ||
storage::{BackingPackageStore, DenyListResult, PackageObject}, | ||
storage::DenyListResult, | ||
transaction::{Argument, CallArg, ObjectArg}, | ||
}; | ||
use tracing::instrument; | ||
|
@@ -285,10 +288,10 @@ mod checked { | |
.unwrap_or(*package_id)); | ||
} | ||
|
||
let package = package_for_linkage(&self.linkage_view, package_id) | ||
let move_package = get_package(&self.linkage_view, package_id) | ||
.map_err(|e| self.convert_vm_error(e))?; | ||
|
||
self.linkage_view.set_linkage(package.move_package()) | ||
self.linkage_view.set_linkage(&move_package) | ||
} | ||
|
||
/// Load a type using the context's current session. | ||
|
@@ -341,7 +344,12 @@ mod checked { | |
} | ||
let new_events = events | ||
.into_iter() | ||
.map(|(ty, tag, value)| { | ||
.map(|(tag, value)| { | ||
let ty = unwrap_type_tag_load( | ||
self.protocol_config, | ||
self.load_type_from_struct(&tag) | ||
.map_err(|e| self.convert_vm_error(e)), | ||
)?; | ||
let layout = self | ||
.vm | ||
.get_runtime() | ||
|
@@ -704,7 +712,7 @@ mod checked { | |
let Self { | ||
protocol_config, | ||
vm, | ||
linkage_view, | ||
mut linkage_view, | ||
mut native_extensions, | ||
tx_context, | ||
gas_charger, | ||
|
@@ -839,12 +847,6 @@ mod checked { | |
loaded_runtime_objects.extend(loaded_child_objects); | ||
|
||
let mut written_objects = BTreeMap::new(); | ||
for package in new_packages { | ||
let package_obj = Object::new_from_package(package, tx_digest); | ||
let id = package_obj.id(); | ||
created_object_ids.insert(id); | ||
written_objects.insert(id, package_obj); | ||
} | ||
for (id, additional_write) in additional_writes { | ||
let AdditionalWrite { | ||
recipient, | ||
|
@@ -872,7 +874,24 @@ mod checked { | |
} | ||
} | ||
|
||
for (id, (recipient, ty, value)) in writes { | ||
for (id, (recipient, tag, value)) in writes { | ||
let ty = unwrap_type_tag_load( | ||
protocol_config, | ||
load_type_from_struct( | ||
vm, | ||
&mut linkage_view, | ||
&new_packages, | ||
&StructTag::from(tag.clone()), | ||
) | ||
.map_err(|e| { | ||
convert_vm_error( | ||
e, | ||
vm, | ||
&linkage_view, | ||
protocol_config.resolve_abort_locations_to_package_id(), | ||
) | ||
}), | ||
)?; | ||
let abilities = vm.get_runtime().get_type_abilities(&ty).map_err(|e| { | ||
convert_vm_error( | ||
e, | ||
|
@@ -910,6 +929,13 @@ mod checked { | |
written_objects.insert(id, object); | ||
} | ||
|
||
for package in new_packages { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This got moved down as we need to use |
||
let package_obj = Object::new_from_package(package, tx_digest); | ||
let id = package_obj.id(); | ||
created_object_ids.insert(id); | ||
written_objects.insert(id, package_obj); | ||
} | ||
|
||
// Before finishing, ensure that any shared object taken by value by the transaction is either: | ||
// 1. Mutated (and still has a shared ownership); or | ||
// 2. Deleted. | ||
|
@@ -1023,7 +1049,6 @@ mod checked { | |
|
||
/// Special case errors for type arguments to Move functions | ||
pub fn convert_type_argument_error(&self, idx: usize, error: VMError) -> ExecutionError { | ||
use move_core_types::vm_status::StatusCode; | ||
use sui_types::execution_status::TypeArgumentError; | ||
match error.major_status() { | ||
StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH => { | ||
|
@@ -1284,22 +1309,17 @@ mod checked { | |
|
||
/// Fetch the package at `package_id` with a view to using it as a link context. Produces an error | ||
/// if the object at that ID does not exist, or is not a package. | ||
fn package_for_linkage( | ||
linkage_view: &LinkageView, | ||
fn get_package( | ||
package_store: &dyn PackageStore, | ||
package_id: ObjectID, | ||
) -> VMResult<PackageObject> { | ||
use move_binary_format::errors::PartialVMError; | ||
use move_core_types::vm_status::StatusCode; | ||
|
||
match linkage_view.get_package_object(&package_id) { | ||
) -> VMResult<Rc<MovePackage>> { | ||
match package_store.get_package(&package_id) { | ||
Ok(Some(package)) => Ok(package), | ||
Ok(None) => Err(PartialVMError::new(StatusCode::LINKER_ERROR) | ||
.with_message(format!("Cannot find link context {package_id} in store")) | ||
.finish(Location::Undefined)), | ||
Err(err) => Err(PartialVMError::new(StatusCode::LINKER_ERROR) | ||
.with_message(format!( | ||
"Error loading link context {package_id} from store: {err}" | ||
)) | ||
.with_message(format!("Error loading {package_id} from store: {err}")) | ||
.finish(Location::Undefined)), | ||
} | ||
} | ||
|
@@ -1323,22 +1343,27 @@ mod checked { | |
|
||
// Load the package that the struct is defined in, in storage | ||
let defining_id = ObjectID::from_address(*address); | ||
let package = package_for_linkage(linkage_view, defining_id)?; | ||
|
||
let data_store = SuiDataStore::new(linkage_view, new_packages); | ||
let move_package = get_package(&data_store, defining_id)?; | ||
|
||
// Save the link context as we need to set it while loading the struct and we don't want to | ||
// clobber it. | ||
let saved_linkage = linkage_view.steal_linkage(); | ||
|
||
// Set the defining package as the link context while loading the | ||
// struct | ||
let original_address = linkage_view | ||
.set_linkage(package.move_package()) | ||
.map_err(|e| { | ||
PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) | ||
.with_message(e.to_string()) | ||
.finish(Location::Undefined) | ||
})?; | ||
.set_linkage(&move_package) | ||
.expect("Linkage context was just stolen. Therefore must be empty"); | ||
|
||
let runtime_id = ModuleId::new(original_address, module.clone()); | ||
let data_store = SuiDataStore::new(linkage_view, new_packages); | ||
let res = vm.get_runtime().load_type(&runtime_id, name, &data_store); | ||
linkage_view.reset_linkage(); | ||
linkage_view | ||
.restore_linkage(saved_linkage) | ||
.expect("Linkage context was just reset. Therefore must be empty"); | ||
let (idx, struct_type) = res?; | ||
|
||
// Recursively load type parameters, if necessary | ||
|
@@ -1707,6 +1732,17 @@ mod checked { | |
} | ||
} | ||
|
||
fn unwrap_type_tag_load( | ||
protocol_config: &ProtocolConfig, | ||
ty: Result<Type, ExecutionError>, | ||
) -> Result<Type, ExecutionError> { | ||
if ty.is_err() && !protocol_config.type_tags_in_object_runtime() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should never happen, but just to be paranoid, panic in case it does and we're before this feature is enabled |
||
panic!("Failed to load a type tag from the object runtime -- this shouldn't happen") | ||
} else { | ||
ty | ||
} | ||
} | ||
|
||
enum EitherError { | ||
CommandArgument(CommandArgumentError), | ||
Execution(ExecutionError), | ||
|
Uh oh!
There was an error while loading. Please reload this page.