-
Notifications
You must be signed in to change notification settings - Fork 35
Composite Scenarios Execution - Setup parallely, spam parallely (and in stages) #242
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
base: main
Are you sure you want to change the base?
Composite Scenarios Execution - Setup parallely, spam parallely (and in stages) #242
Conversation
|
@arpitkarnatak this is sick, thanks for the PR!
They should all run in parallel with different run IDs. Something I'd like to add in the "compose config" is the ability to define dependencies, so that we may execute them in sequence, but I think the default should be to run them all together at once.
Yeah I agree, this should live in its own crate. |
|
@zeroXbrock Thanks for the feedback. So I'll have to do the following next
I have one little doubt, Currently I'm using the pre-existing |
|
@zeroXbrock So I've done the following
Some things that I've had confusions with.
I want to do the following before merge
But apart from that, it's ready for review, do let me know what needs fixing/clarity |
|
@arpitkarnatak thanks for the PR! I should have time later in the week to review |
|
sorry for such a long delay @arpitkarnatak -- I've been meaning to get to this but we haven't needed this feature for the tests we're currently doing with contender, so this has fallen by the wayside. I'll take another look and hopefully get this merged soon! |
|
Absolutely understandable @zeroXbrock please take your time I was just meaning to get an initial review for the time being to get a sense of whether this is in-line with what you had in mind for this feature, and I could polish it further if it was. Thanks and would be looking forward to the review and comments |
zeroXbrock
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for being so patient @arpitkarnatak. I think we can get this merged soon!
Just had a few comments. Let me know if I can clarify anything!
contender-compose.yml
Outdated
| private_keys: # Optional (these Private keys are from Anvil) | ||
| - 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 | ||
| - 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private keys should only be specified as a cli param -- we don't want people accidentally saving their keys into files that they might share with the world
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I think it would be best that way, will change it accordingly
| tracing = { workspace = true } | ||
| tracing-subscriber = { workspace = true } | ||
| webbrowser = { workspace = true } | ||
| yaml-rust2 = "0.10.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know I specified yaml when I wrote the issue but I wonder if toml would be better -- wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Toml can be nice, since we're using it for the other configurations too. For this case, I would prefer YAML solely because of the readability and syntax familiarity with Docker compose syntax.
crates/cli/src/commands/setup.rs
Outdated
| private_keys: setup_object.private_keys, | ||
| env: setup_object.env, | ||
| min_balance: setup_object.min_balance, | ||
| tx_type: if setup_object.tx_type == *"eip1559" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should use enum matching here instead of string comparison
crates/cli/src/commands/spam.rs
Outdated
| }, | ||
| loops: spam_object.loops, | ||
|
|
||
| // TODO: Need more knowledge, hence hardcoding them for now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should inherit their values from the same CLI args that we use to run spam.
They're just CLI args, but you'll have to check the spam impl to see how the defaults are filled in.
crates/composefile/src/types.rs
Outdated
| pub timeout_secs: u64, | ||
| pub env: Option<Vec<(String, String)>>, | ||
| pub loops: Option<u64>, | ||
| // TODO: These params are hardcoded for now, I'll need some more info in these before implementing them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above comment about CLI args inheritance
| use std::error::Error; | ||
| use yaml_rust2::Yaml; | ||
|
|
||
| pub fn get_tx_type(yaml_object: &LinkedHashMap<Yaml, Yaml>) -> Result<String, Box<dyn Error>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should delete this and use enum matching instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This utility is for handling strings from Compose file. These functions are to extract strings from YAML
In the compose file crate, we have utility to read YAML files, and convert each setup and spam scenario into a JSON, and then from the command we convert that JSON to SetupCommandArgs and SpamCommandArgs (in crates/cli/src/commands/setup and crates/cli/src/commands/spam)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like there's a simpler approach. There's too much boilerplate here (and in the other utils / yaml parsing functions in general), and the tests are essentially just testing the YAML parser.
serde_yaml exists, which would parse all of this automatically, but it's not maintained anymore and probably isn't compatible with the modern version of serde that we already use. I'd prefer to swap out YAML for TOML, so we can use serde.
|
hey @arpitkarnatak just wondering if you're still working on this |
|
@zeroXbrock Yes I am on this, I'll try to get this done over the weekend with the changes you asked |
|
Hello @zeroXbrock I added the following features
The relevant snippets are in the last 4 commits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice work so far @arpitkarnatak -- thanks so much! The system works well, but I left a few suggestions for the code in the comments below.
My biggest concern is that the manual YAML parsing adds too much boilerplate code to maintain efficiently. I think TOML is the way to go -- it'll allow us to use serde (which we already use) and reduce the amount of code needed by a huge amount.
Also, the version of contender your branch is based off is pretty old -- you may want to merge main into your branch soon, but it's up to you whether you do that before or after making the changes I suggested. I imagine it will be easier to do afterwards, since there should be less code to change once the duplication is removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this should be in the project root -- maybe it would fit better under scenarios/? Or we could have a new directory called composite-scenarios/ or something like that.
We should also use valid values, so that users with a simple node (e.g. anvil w/ default config) running on localhost:8545 can run the compose file without error. Any advanced examples we want to show off should go in a document under docs/.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we should also enforce a .compose.toml filename restriction, so users don't accidentally try to run core scenario files as compose files
| @@ -0,0 +1,48 @@ | |||
| setup: | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be cool if we didn't have to manually call setup. Feels like manually specifying rpc_urls for setup could get confusing in a large file (i.e. the user tries to spam on an alternate chain but forgets to run setup on that chain).
Instead, we could check if the scenario TOML file has any setup directives, then run TestScenario::estimate_setup_cost to find the required min_balance, then check the spam directives in the compose file to see which chains need to run which setup and run it automatically at the start.
|
|
||
| futures::future::join_all(setup_tasks).await; | ||
|
|
||
| info!("================================================================================================= Done Composite run for setup ================================================================================================="); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's remove the equal signs from this -- simple logs are fine
| pub struct SpamCommandArgsJsonAdapter { | ||
| pub scenario: String, | ||
| pub rpc_url: String, | ||
| pub builder_url: Option<String>, | ||
| pub txs_per_block: Option<u64>, | ||
| pub txs_per_second: Option<u64>, | ||
| pub duration: u64, | ||
| pub private_keys: Option<Vec<String>>, | ||
| pub min_balance: String, | ||
| pub tx_type: String, | ||
| pub timeout_secs: u64, | ||
| pub env: Option<Vec<(String, String)>>, | ||
| pub loops: Option<u64>, | ||
| pub seed: Option<String>, | ||
|
|
||
| pub call_fcu: bool, | ||
| pub use_op: bool, | ||
| pub auth_rpc_url: Option<String>, | ||
| pub jwt_secret: Option<String>, | ||
| pub disable_reporting: bool, | ||
| pub gas_price_percent_add: Option<u64>, | ||
| } | ||
|
|
||
| // In `contender_cli` we can retrieve the SetupCommandArgs struct from this using SetupCommandArgs::from<SetupCommandArgsJsonAdapter>() | ||
| #[derive(Deserialize, Debug, Clone)] | ||
| pub struct SetupCommandArgsJsonAdapter { | ||
| pub testfile: String, | ||
| pub rpc_url: String, | ||
| pub private_keys: Option<Vec<String>>, | ||
| pub min_balance: String, | ||
| pub tx_type: String, | ||
| pub env: Option<Vec<(String, String)>>, | ||
| pub call_fcu: bool, | ||
| pub use_op: bool, | ||
| pub auth_rpc_url: Option<String>, | ||
| pub jwt_secret: Option<String>, | ||
| pub seed: Option<String>, | ||
| // pub engine_params: EngineParams, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These include lots of duplicate variables from structs that already exist in contender_cli.
Since compose is a cli command, I think it would make more sense to just move this whole crate into a module in crates/cli/src/commands/.
Then, instead of duplicating the variables manually for this struct, just compose these structs using the existing structs and #[serde(flatten)]
| use std::error::Error; | ||
| use yaml_rust2::Yaml; | ||
|
|
||
| pub fn get_tx_type(yaml_object: &LinkedHashMap<Yaml, Yaml>) -> Result<String, Box<dyn Error>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like there's a simpler approach. There's too much boilerplate here (and in the other utils / yaml parsing functions in general), and the tests are essentially just testing the YAML parser.
serde_yaml exists, which would parse all of this automatically, but it's not maintained anymore and probably isn't compatible with the modern version of serde that we already use. I'd prefer to swap out YAML for TOML, so we can use serde.
|
hey @arpitkarnatak are you still working on this? |
|
Hey @zeroXbrock I can't give more time to this in near future at least given my current commitments. Sorry :( |
no worries, thanks for letting me know! |
Motivation
This PR is step 1 for composite scenario execution, as suggested in #145
Solution
Adding a new
composecommand, similar todocker composeA
contender-compose.ymlfile looks likeCurrently this only supports
setupcommand, it parses acontender-compose.ymlfile and deploys multiple contracts from a singlecontender composecommand.The next step would be to include the
spamfrom this file. Before implementing that, I want to know if all these spams are going to be run parallely and fall under a single run ID, or be separate runs one after the other.Also, I feel it would be better to have all the logic for the
composefile to be a separate crate of its own, similar totestfile. Let me know your thoughts, and any feedback on how to improve/move forward with this.PR Checklist