Skip to content

Commit

Permalink
Resolve parameters of type vector<vector<Object<T>>> (#2811)
Browse files Browse the repository at this point in the history
* parse the type nested and resolve argument

* refactor error handling

* adjust the caller

* use the several methods to read data from common struct

* remove unused imports

* add integrations test for argument resolver
  • Loading branch information
steelgeek091 authored Oct 24, 2024
1 parent bed7a8f commit cf661ec
Show file tree
Hide file tree
Showing 7 changed files with 492 additions and 123 deletions.
42 changes: 42 additions & 0 deletions crates/testsuite/features/argument_resolver.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Feature: Rooch CLI argument resolver integration tests

@serial
Scenario: argument_resolver_test
Given a server for vector_object_test
Then cmd: "account list --json"

Then cmd: "move publish -p ../../examples/argument_resolver --named-addresses argument_resolver=default --json"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

Then cmd: "move run --function default::argument_resolver::create_mock_object_to_sender --args u64:123"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"
Then sleep: "3"
Then cmd: "object -o default -t {{$.account[-1].default.hex_address}}::argument_resolver::MockObject"
Then cmd: "move run --function default::argument_resolver::object --args object:{{$.object[-1].data[0].id}} --args u64:123"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

Then cmd: "move run --function default::argument_resolver::create_mock_object_to_sender --args u64:123"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"
Then sleep: "3"
Then cmd: "object -o default -t {{$.account[-1].default.hex_address}}::argument_resolver::MockObject"
Then cmd: "move run --function default::argument_resolver::object_ref --args object:{{$.object[-1].data[0].id}} --args u64:123"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

Then cmd: "move run --function default::argument_resolver::create_mock_object_to_sender --args u64:123"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"
Then sleep: "3"
Then cmd: "object -o default -t {{$.account[-1].default.hex_address}}::argument_resolver::MockObject"
Then cmd: "move run --function default::argument_resolver::object_mut_ref --args object:{{$.object[-1].data[0].id}} --args u64:123"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

Then cmd: "move view --function default::argument_resolver::vector_string_argument --args vector<string>:hello123"
Then assert: "{{$.move[-1].return_values[0].decoded_value}} == 'hello123'"

Then cmd: "move view --function default::argument_resolver::vector_object_id_argument --args vector<object_id>:0x0a3e8d86b65c8d51ffa92ed278ac96f895a4b7c8bdb60a8b6cd8a5393cb27760"
Then assert: "{{$.move[-1].return_values[0].decoded_value}} == 0x0a3e8d86b65c8d51ffa92ed278ac96f895a4b7c8bdb60a8b6cd8a5393cb27760"

Then cmd: "move view --function default::argument_resolver::string_argument --args string:hello123"
Then assert: "{{$.move[-1].return_values[0].decoded_value}} == 'hello123'"

Then cmd: "move view --function default::argument_resolver::object_id_argument --args object_id:0x0a3e8d86b65c8d51ffa92ed278ac96f895a4b7c8bdb60a8b6cd8a5393cb27760"
Then assert: "{{$.move[-1].return_values[0].decoded_value}} == '0x0a3e8d86b65c8d51ffa92ed278ac96f895a4b7c8bdb60a8b6cd8a5393cb27760'"
17 changes: 17 additions & 0 deletions examples/argument_resolver/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "argument_resolver"
version = "0.0.1"

[dependencies]
MoveStdlib = { local = "../../frameworks/move-stdlib" }
MoveosStdlib = { local = "../../frameworks/moveos-stdlib" }
RoochFramework = { local = "../../frameworks/rooch-framework" }

[addresses]
argument_resolver = "_"
std = "0x1"
moveos_std = "0x2"
rooch_framework = "0x3"

[dev-addresses]
argument_resolver = "0x42"
46 changes: 46 additions & 0 deletions examples/argument_resolver/sources/main.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module argument_resolver::argument_resolver {
use moveos_std::object;
use moveos_std::object::{Object, ObjectID};
use std::vector;
use std::signer;
use std::debug;
use std::string::String;

struct MockObject has key,store,drop,copy {value: u64}

entry public fun create_mock_object_to_sender(account: &signer, arg: u64) {
let user_object = object::new(MockObject{value: arg});
let object_id = object::id(&user_object);
debug::print(&object_id);
object::transfer(user_object, signer::address_of(account));
}

entry public fun object(_account:&signer, object: Object<MockObject>, arg: u64) {
assert!(object::borrow(&object).value == arg, 1);
object::remove(object);
}

entry public fun object_ref(_account: &signer, object_ref: &Object<MockObject>, arg: u64) {
assert!(object::borrow(object_ref).value == arg, 1);
}

entry public fun object_mut_ref(_account: &signer, mut_object_ref: &mut Object<MockObject>, arg: u64) {
assert!(object::borrow_mut(mut_object_ref).value == arg, 1);
}

public fun vector_string_argument(_account: &signer, string_vector_argument: vector<String>): String {
vector::pop_back(&mut string_vector_argument)
}

public fun vector_object_id_argument(_account: &signer, object_id_vector_argument: vector<ObjectID>): ObjectID {
vector::pop_back(&mut object_id_vector_argument)
}

public fun string_argument(_account: &signer, string_argument: String): String {
string_argument
}

public fun object_id_argument(_account: &signer, object_id_argument: ObjectID): ObjectID {
object_id_argument
}
}
40 changes: 39 additions & 1 deletion examples/vector_object/sources/main.move
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module vector_object::vector_object {
use moveos_std::object;
use moveos_std::object::Object;
use moveos_std::object::{Object, ObjectID};
use std::vector;
use std::signer;
use std::debug;
use std::string::String;

struct MockObject has key,store,drop,copy {value: u64}

Expand Down Expand Up @@ -45,4 +46,41 @@ module vector_object::vector_object {

vector::destroy_empty(mock_object_list);
}

entry public fun transfer_vector_object_nested(account: &signer, mock_object_list: vector<vector<Object<MockObject>>>) {
debug::print(&mock_object_list);

while(vector::length(&mock_object_list) > 0) {
let inner_list = vector::pop_back(&mut mock_object_list);
while(vector::length(&inner_list) > 0) {
let mock_object_arg = vector::pop_back(&mut inner_list);
object::transfer(mock_object_arg, signer::address_of(account));
};
vector::destroy_empty(inner_list);
};

vector::destroy_empty(mock_object_list);
}

entry public fun vector_nested(_account: &signer, nested_vector: vector<vector<u64>>) {
while(vector::length(&nested_vector) > 0) {
let inner_list = vector::pop_back(&mut nested_vector);
while(vector::length(&inner_list) > 0) {
let arg = vector::pop_back(&mut inner_list);
debug::print(&arg);
}
}
}

entry public fun vector_string_argument(_account: &signer, string_argument: vector<String>) {
debug::print(&string_argument);
}

entry public fun vector_object_id_argument(_account: &signer, string_argument: vector<ObjectID>) {
debug::print(&string_argument);
}

entry public fun string_argument(_account: &signer, string_argument: String) {
debug::print(&string_argument);
}
}
35 changes: 35 additions & 0 deletions moveos/moveos-object-runtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use move_core_types::{
account_address::AccountAddress, gas_algebra::NumBytes, language_storage::ModuleId,
value::MoveTypeLayout, vm_status::StatusCode,
};
use move_vm_types::loaded_data::runtime_types::Type;
use move_vm_types::values::{StructRef, Value};
use moveos_types::{
move_std::string::MoveString,
Expand Down Expand Up @@ -369,6 +370,40 @@ impl<'r> ObjectRuntime<'r> {
self.get_loaded_module(module_id).map(|m| m.is_some())
}

pub fn load_object_argument(
&mut self,
object_id: &ObjectID,
type_: &Type,
layout_loader: &dyn TypeLayoutLoader,
) -> VMResult<()> {
let (rt_obj, _) = self
.load_object(layout_loader, object_id)
.map_err(|e| e.finish(Location::Module(object::MODULE_ID.clone())))?;
match type_ {
Type::Reference(_) | Type::MutableReference(_) => {
let pointer_value = rt_obj
.borrow_object(None)
.map_err(|e| e.finish(Location::Module(object::MODULE_ID.clone())))?;
//We cache the object pointer value in the object_pointer_in_args
//Ensure the reference count and the object can not be borrowed in Move
self.object_pointer_in_args
.insert(object_id.clone(), RuntimeObjectArg::Ref(pointer_value));
}
Type::StructInstantiation(_, _) => {
let pointer_value = rt_obj
.take_object(None)
.map_err(|e| e.finish(Location::Module(object::MODULE_ID.clone())))?;
//We cache the object pointer value in the object_pointer_in_args
//Ensure the reference count and the object can not be borrowed in Move
self.object_pointer_in_args
.insert(object_id.clone(), RuntimeObjectArg::Value(pointer_value));
}
_ => {}
}

Ok(())
}

pub fn load_arguments(
&mut self,
layout_loader: &dyn TypeLayoutLoader,
Expand Down
17 changes: 8 additions & 9 deletions moveos/moveos/src/vm/moveos_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ where
let location = Location::Script;
moveos_verifier::verifier::verify_entry_function(&loaded_function, &self.session)
.map_err(|e| e.finish(location.clone()))?;
let _resolved_args =
self.resolve_argument(&loaded_function, call.args.clone(), location)?;
let _serialized_args =
self.resolve_argument(&loaded_function, call.args.clone(), location, false)?;

let compiled_script_opt = CompiledScript::deserialize(call.code.as_slice());
let compiled_script = match compiled_script_opt {
Expand All @@ -245,7 +245,7 @@ where
moveos_verifier::verifier::verify_entry_function(&loaded_function, &self.session)
.map_err(|e| e.finish(location.clone()))?;
let _resolved_args =
self.resolve_argument(&loaded_function, call.args.clone(), location)?;
self.resolve_argument(&loaded_function, call.args.clone(), location, false)?;
Ok(VerifiedMoveAction::Function {
call,
bypass_visibility: false,
Expand Down Expand Up @@ -310,8 +310,8 @@ where
.session
.load_script(call.code.as_slice(), call.ty_args.clone())?;
let location: Location = Location::Script;
let resolved_args = self.resolve_argument(&loaded_function, call.args, location)?;
let serialized_args = self.load_arguments(resolved_args)?;
let serialized_args =
self.resolve_argument(&loaded_function, call.args, location, true)?;
self.session
.execute_script(
call.code,
Expand All @@ -336,8 +336,8 @@ where
call.ty_args.as_slice(),
)?;
let location = Location::Module(call.function_id.module_id.clone());
let resolved_args = self.resolve_argument(&loaded_function, call.args, location)?;
let serialized_args = self.load_arguments(resolved_args)?;
let serialized_args =
self.resolve_argument(&loaded_function, call.args, location, true)?;
if bypass_visibility {
// bypass visibility call is system call, such as execute L1 block transaction
self.session
Expand Down Expand Up @@ -508,8 +508,7 @@ where
call.ty_args.as_slice(),
)?;
let location = Location::Module(call.function_id.module_id.clone());
let resolved_args = self.resolve_argument(&loaded_function, call.args, location)?;
let serialized_args = self.load_arguments(resolved_args)?;
let serialized_args = self.resolve_argument(&loaded_function, call.args, location, true)?;
let return_values = self.session.execute_function_bypass_visibility(
&call.function_id.module_id,
&call.function_id.function_name,
Expand Down
Loading

0 comments on commit cf661ec

Please sign in to comment.