Skip to content
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

Tuple and array arguments supported in resim #1727

Draft
wants to merge 8 commits into
base: develop
Choose a base branch
from

Conversation

lrubasze
Copy link
Contributor

@lrubasze lrubasze commented Feb 29, 2024

Summary

Support for passing Tuple and Array values as function/method arguments in resim.
Tuple arguments shall be surrounded with round brackets ( and ).
Array arguments shall be surrounded with square brackets [ and ].

Examples:

  • Array of Strings
resim call-function <package_address> <blueprint_name> <function_name> '["fizz","buzz"]'
  • Tuple of ResourceAddress, NonFungibleLocalId
resim call-function <package_address> <blueprint_name> <function_name> \
 '(resource_sim1nfzf2h73frult99zd060vfcml5kncq3mxpthusm9lkglvhsr0guahy,#1#)'

Nested Tuples/Arrays are also possible :)

Copy link

github-actions bot commented Feb 29, 2024

Docker tags
docker.io/radixdlt/private-scrypto-builder:8ad836156f

Copy link

github-actions bot commented Feb 29, 2024

Benchmark for 8ad8361

Click to view benchmark
Test Base PR %
costing::bench_prepare_wasm 66.5±0.14ms 65.8±0.15ms -1.05%
costing::decode_sbor 15.0±0.04µs 16.0±0.05µs +6.67%
costing::decode_sbor_bytes 46.4±0.33µs 42.2±0.34µs -9.05%
costing::deserialize_wasm 1256.3±2.96µs 1229.3±2.50µs -2.15%
costing::instantiate_flash_loan 4.0±0.81ms 3.7±0.05ms -7.50%
costing::instantiate_radiswap 5.6±0.05ms 5.8±0.07ms +3.57%
costing::spin_loop 23.5±0.03ms 23.2±0.05ms -1.28%
costing::validate_sbor_payload 30.1±0.05µs 30.4±0.04µs +1.00%
costing::validate_sbor_payload_bytes 259.1±0.70ns 251.4±0.62ns -2.97%
costing::validate_secp256k1 78.9±0.06µs 78.9±0.05µs 0.00%
costing::validate_wasm 37.7±0.05ms 36.6±0.06ms -2.92%
decimal::add/0 8.4±0.00ns 8.4±0.00ns 0.00%
decimal::add/rust-native 9.8±0.00ns 9.8±0.00ns 0.00%
decimal::add/wasmer 111.7±0.10ns 110.8±0.94ns -0.81%
decimal::add/wasmer-call-native 413.8±0.17ns 412.7±0.32ns -0.27%
decimal::add/wasmi 583.7±1.35ns 589.1±0.47ns +0.93%
decimal::add/wasmi-call-native 4.8±0.00µs 4.9±0.01µs +2.08%
decimal::div/0 178.8±0.12ns 180.2±0.38ns +0.78%
decimal::from_string/0 155.8±0.20ns 181.0±0.61ns +16.17%
decimal::mul/0 141.1±0.10ns 143.1±0.13ns +1.42%
decimal::mul/rust-native 139.5±0.35ns 137.8±0.15ns -1.22%
decimal::mul/wasmer 1509.7±0.25ns 1492.5±3.87ns -1.14%
decimal::mul/wasmer-call-native 550.2±0.58ns 549.9±0.49ns -0.05%
decimal::mul/wasmi 42.3±0.25µs 42.0±0.08µs -0.71%
decimal::mul/wasmi-call-native 5.0±0.01µs 5.0±0.01µs 0.00%
decimal::pow/0 652.0±1.38ns 654.7±0.74ns +0.41%
decimal::pow/rust-native 630.4±0.29ns 632.9±0.19ns +0.40%
decimal::pow/wasmer 6.6±0.00µs 6.6±0.00µs 0.00%
decimal::pow/wasmer-call-native 987.2±0.32ns 997.7±0.57ns +1.06%
decimal::pow/wasmi 201.2±1.53µs 201.1±0.60µs -0.05%
decimal::pow/wasmi-call-native 4.9±0.02µs 4.8±0.00µs -2.04%
decimal::root/0 7.9±0.01µs 7.9±0.01µs 0.00%
decimal::sub/0 8.5±0.01ns 8.5±0.01ns 0.00%
decimal::to_string/0 439.5±0.43ns 441.5±0.30ns +0.46%
precise_decimal::add/0 9.5±0.18ns 9.3±0.17ns -2.11%
precise_decimal::add/rust-native 11.4±0.00ns 11.4±0.00ns 0.00%
precise_decimal::add/wasmer 117.6±0.20ns 116.9±0.10ns -0.60%
precise_decimal::add/wasmer-call-native 431.0±0.55ns 429.4±0.31ns -0.37%
precise_decimal::add/wasmi 752.3±2.69ns 744.0±1.63ns -1.10%
precise_decimal::add/wasmi-call-native 5.2±0.01µs 5.2±0.02µs 0.00%
precise_decimal::div/0 304.9±0.20ns 293.4±0.68ns -3.77%
precise_decimal::from_string/0 202.8±0.15ns 208.1±0.35ns +2.61%
precise_decimal::mul/0 325.5±0.35ns 311.3±0.27ns -4.36%
precise_decimal::mul/rust-native 313.1±2.22ns 318.4±2.45ns +1.69%
precise_decimal::mul/wasmer 3.4±0.00µs 3.4±0.00µs 0.00%
precise_decimal::mul/wasmer-call-native 768.8±3.25ns 747.8±0.67ns -2.73%
precise_decimal::mul/wasmi 108.2±0.35µs 108.4±0.53µs +0.18%
precise_decimal::mul/wasmi-call-native 5.7±0.02µs 5.7±0.01µs 0.00%
precise_decimal::pow/0 1759.4±7.35ns 1764.0±4.70ns +0.26%
precise_decimal::pow/rust-native 1449.8±2.75ns 1473.8±6.19ns +1.66%
precise_decimal::pow/wasmer 16.3±0.00µs 16.3±0.00µs 0.00%
precise_decimal::pow/wasmer-call-native 2.0±0.01µs 2.0±0.00µs 0.00%
precise_decimal::pow/wasmi 525.7±0.64µs 521.7±1.36µs -0.76%
precise_decimal::pow/wasmi-call-native 11.6±0.03µs 11.6±0.02µs 0.00%
precise_decimal::root/0 55.4±0.03µs 56.0±0.01µs +1.08%
precise_decimal::sub/0 9.5±0.00ns 9.5±0.00ns 0.00%
precise_decimal::to_string/0 697.5±2.16ns 699.2±1.97ns +0.24%
schema::validate_payload 326.7±0.30µs 343.4±0.52µs +5.11%
transaction::radiswap 5.5±0.02ms 5.5±0.02ms 0.00%
transaction::transfer 1775.5±10.15µs 1775.3±5.21µs -0.01%
transaction_processing::prepare 2.7±0.00ms 2.7±0.00ms 0.00%
transaction_processing::prepare_and_decompile 6.4±0.03ms 6.5±0.01ms +1.56%
transaction_processing::prepare_and_decompile_and_recompile 22.7±0.03ms 23.8±0.06ms +4.85%
transaction_validation::validate_manifest 43.8±0.17µs 43.7±0.51µs -0.23%
transaction_validation::verify_bls_2KB 989.9±20.78µs 1022.2±52.46µs +3.26%
transaction_validation::verify_bls_32B 974.3±16.00µs 1019.7±29.64µs +4.66%
transaction_validation::verify_ecdsa 76.8±0.05µs 76.8±0.20µs 0.00%
transaction_validation::verify_ed25519 54.8±0.10µs 54.9±0.07µs +0.18%

Copy link
Contributor

@dhedey dhedey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really cool! :D

Side thoughts:

  • This is not the standard approach to implementing a parser (normally as per manifest land, you'd implement a lexer and parser) which is why there are quite a lot of edge cases. But the code's a lot more compact. I don't think it's a problem and I don't think it needs changing; but I think it could do with a few of the edge cases being neatened out, and documented a little more.
  • A part of me wonders if we should accept manifest syntax or programmatic json or something (where we have proper lexers already) but I think I prefer your approach tbh :)

Separately, I wonder if we should detect a well known type id of NonFungibleGlobalId, and allow that to be provided as the canonical resource_address:local_id string (as well as the tuple)?


// Splits argument tuple or array elements delimited with "," into vector of elements.
// Elements with brackets (round or square) are taken as is (even if they may include ",")
fn split_argument_tuple_or_array(argument: &str) -> Result<Vec<String>, BuildCallArgumentError> {
Copy link
Contributor

@dhedey dhedey Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the below fix, there are still some constraints around what can be parsed:

  • Strings anywhere inside tuples or arrays can't contain [ or ] or ( or ).
  • Strings directly inside tuples or arrays can't start/end with whitespace.

This isn't necessarily a problem. But we probably want to add the new syntax to the resim documentation somewhere and explain its limitations?

Copy link
Contributor

@dhedey dhedey Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I wonder if we should consider adding some string support with "? Both to the below parser, and to the string parser which would discard start and stopping " -- i.e. we could have an "is in string" flag, and avoid interpreting any other characters until we see a ".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, surrounding strings with " would make things easier, but it would be quite different of other places in resim, where string could be supplied. Not sure if want it...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I was thinking that it could be optional, so abc, "abc" and "abc [ asda" are all acceptable for a string. But it does further complicate the splitter/parser!

let mut chars = argument.chars();

while let Some(c) = chars.next() {
if c.is_whitespace() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This discards all whitespace inside strings contained inside tuples and arrays, I think this is a little too heavy handed, e.g. (hello world,123) would parse as ("helloworld", 123)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think instead we should have the check contingent on round_brackets_level == 0 && square_brackets_level == 0

Copy link
Contributor Author

@lrubasze lrubasze Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This discards all whitespace inside strings contained inside tuples and arrays, I think this is a little too heavy handed, e.g. (hello world,123) would parse as ("helloworld", 123)

Good point 🤦

}
_ => match prev_c {
Some(prev_c) if prev_c == ']' || prev_c == ')' => {
return Err(BuildCallArgumentError::FailedToParse(format!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows (hello)(world) (with no comma) to mean "(hello)(world)" which feels a little wrong, but on reflection, I don't think it's necessarily a problem...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think comma should be mandatory, so would prefer to fix it.

@lrubasze
Copy link
Contributor Author

Separately, I wonder if we should detect a well known type id of NonFungibleGlobalId, and allow that to be provided as the canonical resource_address:local_id string (as well as the tuple)?

This is exactly what I was thinking. In fact I've implemented it in the first commit of this PR, but I replaced it with Tuple and Array approach. But I believe it would be really nice to support it as well.

@iamyulong iamyulong marked this pull request as draft March 28, 2024 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants