Skip to content

Commit

Permalink
fix(CLI): optional args & type args issue (#21)
Browse files Browse the repository at this point in the history
* fix(CLI): optional args & type args issue

* fmt
  • Loading branch information
Poytr1 authored Nov 21, 2022
1 parent 5d758e5 commit 6e27b69
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 104 deletions.
23 changes: 12 additions & 11 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ It doesn't require the view functions as entry functions, and now supports all t

This project includes a CLI tool, also we've built a web app on top of it. You can choose to use the CLI tool or directly start the web stack locally via docker.

## Visit demo website at http://composer.sentio.xyz/
We host a demo website for preview use, have a try :sparkles: !

## Start the Web APP locally
```shell
sudo docker run --env BIN_PATH="/app/view-function" -d -p 8080:4000 poytr1/sentio-composer-app:latest
Expand All @@ -27,16 +30,16 @@ You can choose to build the CLI tool on your own or download the binary directly
## CLI Usage
### Run the CLI
`view-function -h`
```shell
```
Usage: view-function [OPTIONS] --func <FUNCTION>
Options:
-F, --func <FUNCTION>
Function name to call, e.g. 0x1::foo::bar.
-T, --type_args <TYPE_ARGS>
Type parameters, seperated by ',' e.g. 0x1::aptos_coin::AptosCoin. [default: ]
Type parameters, seperated by ',' e.g. 0x1::aptos_coin::AptosCoin.
-A, --args <ARGS>
Parameters, seperated by ',' e.g. foo, bar. [default: ]
Parameters, seperated by ',' e.g. foo, bar.
-L, --ledger_version <LEDGER_VERSION>
Ledger version, if not apply or 0, use the latest ledger version. [default: 0]
-N, --network <NETWORK>
Expand All @@ -49,23 +52,21 @@ Options:
Print help information
-V, --version
Print version information

```
### Example
```shell
# command
view-function \
--func 0xeaa6ac31312d55907f6c9d7a66432d92d4da3aeef7ceb4e6242a8414ac67fa82::vault::account_collateral_and_debt \
--func 0x1::coin::balance \
--type_args 0x1::aptos_coin::AptosCoin \
--args 0xf485fdf431d489c7bd0b83efa2413a6701fe4985d3e64a299a1a2e9fb46bcb82 \
--ledger_version 0 \
--network testnet
--args 0x21ddba785f3ae9c6f03664ab07e9ad83595a0fa5ca556cec2b9d9e7100db0f07 \
--ledger_version 35842267 \
--network mainnet
# output
{
"log_path": ".log/aptos_tool_bin.log",
"log_path": "",
"return_values": [
"800000000u64",
"1103000000u64"
"3120544100u64"
]
}
```
Expand Down
154 changes: 82 additions & 72 deletions src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,80 +125,90 @@ pub fn construct_struct_type_tag_from_str(raw: &str) -> TypeTag {
}));
}

pub fn serialize_input_params(input_params: Vec<&str>, param_types: Vec<MoveType>) -> Vec<Vec<u8>> {
assert_eq!(input_params.len(), param_types.len());
pub fn serialize_input_params(
raw_args: Option<&String>,
param_types: Vec<MoveType>,
) -> Vec<Vec<u8>> {
let mut args: Vec<Vec<u8>> = Vec::new();
let mut param_types_iter = param_types.into_iter();
input_params.into_iter().for_each(|p| {
if p.trim().len() > 0 {
let current_param_type = param_types_iter.next().unwrap();
match current_param_type {
MoveType::Bool => {
args.push(
MoveValue::Bool(matches!(p.trim(), "true" | "t" | "1"))
.simple_serialize()
.unwrap(),
);
}
MoveType::U8 => {
let num = p.trim().parse::<u8>();
args.push(MoveValue::U8(num.unwrap()).simple_serialize().unwrap());
}
MoveType::U64 => {
let num = p.trim().parse::<u64>();
args.push(MoveValue::U64(num.unwrap()).simple_serialize().unwrap());
}
MoveType::U128 => {
let num = p.trim().parse::<u128>();
args.push(MoveValue::U128(num.unwrap()).simple_serialize().unwrap());
}
MoveType::Address => {
// Suppose it's an account parameter
args.push(
MoveValue::Address(AccountAddress::from_hex_literal(p.trim()).unwrap())
.simple_serialize()
.unwrap(),
);
}
MoveType::Signer => {
// Suppose it's an account parameter
args.push(
MoveValue::Signer(AccountAddress::from_hex_literal(p.trim()).unwrap())
.simple_serialize()
.unwrap(),
);
}
MoveType::Vector { items } => match items.as_ref() {
MoveType::Bool => {}
MoveType::U8 => args.push(
MoveValue::vector_u8(String::from(p.trim()).into_bytes())
.simple_serialize()
.unwrap(),
),
MoveType::U64 => {}
MoveType::U128 => {}
MoveType::Address => {}
MoveType::Signer => {}
MoveType::Vector { .. } => {}
MoveType::Struct(_) => {}
MoveType::GenericTypeParam { .. } => {}
MoveType::Reference { .. } => {}
MoveType::Unparsable(_) => {}
},
MoveType::Struct(_tag) => {
panic!("Struct type is not supported yet")
}
MoveType::GenericTypeParam { .. } => {
panic!("Struct type is not supported yet")
}
MoveType::Reference { .. } => {
panic!("Struct type is not supported yet")
}
MoveType::Unparsable(_) => {
panic!("Unparsable paramter")
if let Some(args_val) = raw_args {
let input_params: Vec<&str> = args_val.split(",").collect();
assert_eq!(
input_params.len(),
param_types.len(),
"The length of provided input params is not equal to expected one."
);
let mut param_types_iter = param_types.into_iter();
input_params.into_iter().for_each(|p| {
if p.trim().len() > 0 {
let current_param_type = param_types_iter.next().unwrap();
match current_param_type {
MoveType::Bool => {
args.push(
MoveValue::Bool(matches!(p.trim(), "true" | "t" | "1"))
.simple_serialize()
.unwrap(),
);
}
MoveType::U8 => {
let num = p.trim().parse::<u8>();
args.push(MoveValue::U8(num.unwrap()).simple_serialize().unwrap());
}
MoveType::U64 => {
let num = p.trim().parse::<u64>();
args.push(MoveValue::U64(num.unwrap()).simple_serialize().unwrap());
}
MoveType::U128 => {
let num = p.trim().parse::<u128>();
args.push(MoveValue::U128(num.unwrap()).simple_serialize().unwrap());
}
MoveType::Address => {
// Suppose it's an account parameter
args.push(
MoveValue::Address(AccountAddress::from_hex_literal(p.trim()).unwrap())
.simple_serialize()
.unwrap(),
);
}
MoveType::Signer => {
// Suppose it's an account parameter
args.push(
MoveValue::Signer(AccountAddress::from_hex_literal(p.trim()).unwrap())
.simple_serialize()
.unwrap(),
);
}
MoveType::Vector { items } => match items.as_ref() {
MoveType::Bool => {}
MoveType::U8 => args.push(
MoveValue::vector_u8(String::from(p.trim()).into_bytes())
.simple_serialize()
.unwrap(),
),
MoveType::U64 => {}
MoveType::U128 => {}
MoveType::Address => {}
MoveType::Signer => {}
MoveType::Vector { .. } => {}
MoveType::Struct(_) => {}
MoveType::GenericTypeParam { .. } => {}
MoveType::Reference { .. } => {}
MoveType::Unparsable(_) => {}
},
MoveType::Struct(_tag) => {
panic!("Struct type is not supported yet")
}
MoveType::GenericTypeParam { .. } => {
panic!("Struct type is not supported yet")
}
MoveType::Reference { .. } => {
panic!("Struct type is not supported yet")
}
MoveType::Unparsable(_) => {
panic!("Unparsable paramter")
}
}
}
}
});
});
}
return args;
}
64 changes: 43 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,12 @@ fn main() {
arg!(
-T --type_args <TYPE_ARGS> "Type parameters, seperated by ',' e.g. 0x1::aptos_coin::AptosCoin."
)
.default_value("")
.required(false),
)
.arg(
arg!(
-A --args <ARGS> "Parameters, seperated by ',' e.g. foo, bar."
)
.default_value("")
.required(false),
)
.arg(
Expand Down Expand Up @@ -91,8 +89,8 @@ fn main() {
.get_matches();

let func = matches.get_one::<String>("func").unwrap().clone();
let type_args = matches.get_one::<String>("type_args").unwrap().clone();
let args = matches.get_one::<String>("args").unwrap().clone();
let type_args = matches.get_one::<String>("type_args");
let args = matches.get_one::<String>("args");
let ledger_version: u64 = matches.get_one::<u64>("ledger_version").unwrap().clone();
let network: String = matches.get_one::<String>("network").unwrap().clone();
let config_file: String = matches.get_one::<String>("config").unwrap().clone();
Expand All @@ -102,8 +100,12 @@ fn main() {
let log_path = set_up_log(&config, log_level.clone());

debug!("Value for func: {}", func);
debug!("Value for type arguments: {}", type_args);
debug!("Value for arguments: {}", args);
if let Some(val) = type_args {
debug!("Value for type arguments: {}", val);
}
if let Some(val) = args {
debug!("Value for arguments: {}", val);
}
debug!("Value for ledger version: {}", ledger_version);
debug!("Value for network: {}", network);
debug!("Value for config file: {}", config_file);
Expand Down Expand Up @@ -159,8 +161,8 @@ fn set_up_log(config: &ToolConfig, log_level: String) -> String {

fn exec_func(
func: String,
type_args: String,
args: String,
type_args_input: Option<&String>,
args_input: Option<&String>,
ledger_version: u64,
network: String,
config: &ToolConfig,
Expand Down Expand Up @@ -197,21 +199,22 @@ fn exec_func(
panic!("No matched function found!");
};

let splitted_args: Vec<&str> = args.split(",").collect();
let ser_args: Vec<Vec<u8>> = serialize_input_params(splitted_args, param_types);
let ser_args: Vec<Vec<u8>> = serialize_input_params(args_input, param_types);

// For now, we only support struct type arg
let splitted_type_args = type_args.split(",");
let mut type_args: Vec<TypeTag> = vec![];
splitted_type_args.into_iter().for_each(|tp| {
if tp.trim().len() > 0 {
if tp.contains("::") {
type_args.push(construct_struct_type_tag_from_str(tp));
} else {
panic!("only support struct type parameters now!");
if let Some(tp_args_val) = type_args_input {
let splitted_type_args = tp_args_val.split(",");
splitted_type_args.into_iter().for_each(|tp| {
if tp.trim().len() > 0 {
if tp.contains("::") {
type_args.push(construct_struct_type_tag_from_str(tp));
} else {
panic!("only support struct type parameters now!");
}
}
}
});
});
}

let storage = InMemoryLazyStorage::new(ledger_version, network, client.clone(), cache_folder);
let res = exec_func_internal(storage, module, func_id, type_args, ser_args);
Expand Down Expand Up @@ -346,8 +349,8 @@ mod tests {
};
exec_func(
String::from("0xeaa6ac31312d55907f6c9d7a66432d92d4da3aeef7ceb4e6242a8414ac67fa82::vault::account_collateral_and_debt"),
String::from("0x1::aptos_coin::AptosCoin"),
String::from("0xf485fdf431d489c7bd0b83efa2413a6701fe4985d3e64a299a1a2e9fb46bcb82"),
Some(&String::from("0x1::aptos_coin::AptosCoin")),
Some(&String::from("0xf485fdf431d489c7bd0b83efa2413a6701fe4985d3e64a299a1a2e9fb46bcb82")),
0,
String::from("testnet"),
&CONFIG,
Expand All @@ -356,4 +359,23 @@ mod tests {
debug!("{}", execution_result.return_values[0]);
debug!("{}", execution_result.return_values[1]);
}

#[test]
fn test_get_current_block_height() {
let mut execution_result = ExecutionResult {
log_path: String::new(),
return_values: vec![],
};
exec_func(
String::from("0x1::block::get_current_block_height"),
None,
None,
0,
String::from("mainnet"),
&CONFIG,
&mut execution_result,
);
assert_eq!(execution_result.return_values.len(), 1);
debug!("{}", execution_result.return_values[0]);
}
}

0 comments on commit 6e27b69

Please sign in to comment.