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

feat: use of WorldContractReader from abigen! #1010

Merged
merged 18 commits into from
Dec 20, 2023

Conversation

glihm
Copy link
Collaborator

@glihm glihm commented Oct 11, 2023

This PR aims at exploring how abigen! macro in PR on starknet-rs can be used to reduce amount of code related to contract calls / invokes.

Few points here:

  1. abigen! is still experimental, but thanks to this PR I was able to fix several important things. Thank you dojo! :)
  2. Multi-call is not yet supported by abigen, so some functions were not modified. However, if we can add options to the macro, an option like external_generate_call=true can trigger an additional code generation for externals like my_external_call which returns the Call instead of actually executing the transaction. This will allow the combinations of several Calls in only one execute, leveraging abigen rust string typing. Example where it can be useful in torii: register_models.
  3. I renamed the methods that had the same name as contract method with from_str as there are some additional parameter checking based on input string. Does this sound good to you too?
  4. I do like how you were working with Contract and ContractReader, I've ported the same implementation in the abigen which in my opinion is a very good approach. This allows the current code to directly add some impl for the structs generated by abigen which have the same name as the one before.
  5. With JSON files, I have some problem with the paths, were clippy is expecting a relative path to the Cargo.toml of torii-client, but cargo build -p torii-client is expecting a relative path to Cargo.toml of the workspace. Keep investigating, but any help on this would be very welcomed!
  6. To generate the abi, I have to add this to the Scarb.toml:
[[target.starknet-contract]]
sierra = true

Is it ok to push this change, or we do not want this into the scarb manifest?

I'll keep this PR in draft for now to gather some feedback on this work. Any comment would be greatly appreciated to keep exploring this path and enhancing robustness and capabilities of abigen.

@glihm glihm changed the title feat: use of world from abigen! feat: use of WorldContractReader from abigen! Oct 11, 2023
Copy link
Contributor

@tarrencev tarrencev left a comment

Choose a reason for hiding this comment

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

Looks good! Can we remove the from_str methods if we pass a FieldElement instead?

let model = world.model(&name, BlockId::Tag(BlockTag::Latest)).await?;
let schema = model.schema(BlockId::Tag(BlockTag::Latest)).await?;
let layout = model.layout(BlockId::Tag(BlockTag::Latest)).await?;
world.set_call_block_id(BlockId::Tag(BlockTag::Latest));
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm this is an interesting pattern. Why did you decide to go this path vs passing for each call?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Adding an extra-parameter to function in a sense makes it less natural to call a function of our contract as we have to know that the abigen will add this extra param.

But at the same time, having the set_call_block_id pattern is a "limitation"/"constraint" when the instance is shared, as we need a mut reference to adjust the block id, and this may cause some races without adding mutex for instance.

So... I would say that it was an experiment, and after making more test I am not sure what can be the best approach. Or maybe abigen may give this option to the user?

@glihm
Copy link
Collaborator Author

glihm commented Oct 17, 2023

Looks good! Can we remove the from_str methods if we pass a FieldElement instead?

If there is no problem at externalizing the inputs verification, we can definitely remove the from_str methods to keep using only the generated code.

Taking this example:

pub async fn grant_writer_from_str(
    &self,
    model: &str,
    contract: &ContractAddress,
) -> Result<
    InvokeTransactionResult,
    WorldContractError<A::SignError, <A::Provider as Provider>::Error>,
> {
    let model = cairo_short_string_to_felt(model)
        .map_err(WorldContractError::CairoShortStringToFeltError)?;

    self.grant_writer(&model, contract).await.map_err(WorldContractError::AccountError)
}

The model verification should then be done out of this function by the caller of the generated grant_writer function.

@tarrencev tarrencev force-pushed the main branch 2 times, most recently from 0f4d258 to 19d76ce Compare October 20, 2023 21:09
@tarrencev
Copy link
Contributor

Looks good! Can we remove the from_str methods if we pass a FieldElement instead?

If there is no problem at externalizing the inputs verification, we can definitely remove the from_str methods to keep using only the generated code.

Taking this example:

pub async fn grant_writer_from_str(
    &self,
    model: &str,
    contract: &ContractAddress,
) -> Result<
    InvokeTransactionResult,
    WorldContractError<A::SignError, <A::Provider as Provider>::Error>,
> {
    let model = cairo_short_string_to_felt(model)
        .map_err(WorldContractError::CairoShortStringToFeltError)?;

    self.grant_writer(&model, contract).await.map_err(WorldContractError::AccountError)
}

The model verification should then be done out of this function by the caller of the generated grant_writer function.

I think this is fine, until cairo gets a string type which can handle validation internally

@tarrencev tarrencev force-pushed the main branch 9 times, most recently from dd36cf5 to 4979471 Compare December 1, 2023 08:56
@tarrencev tarrencev force-pushed the main branch 8 times, most recently from 6a784ce to a08f2cb Compare December 10, 2023 03:06
@glihm glihm force-pushed the feat/world-abigen branch from 45c5558 to 71a1830 Compare December 15, 2023 23:34
@glihm glihm marked this pull request as ready for review December 16, 2023 05:25
@glihm
Copy link
Collaborator Author

glihm commented Dec 16, 2023

@tarrencev if you have time I would appreciate a new review on this one. 🙏

(Contains the commit from #1297 as I used it for debug, I can rebase depending on which is merged first)

@glihm
Copy link
Collaborator Author

glihm commented Dec 16, 2023

I'm thinking of generating the two .json file for world and executor during the CI. This can help to prevent someone changing the cairo files, without actually updating the artifacts.

This will also help us ensuring that the rust programs correctly use the cairo methods.

What is the best for that, adding a step in the CI and use sozo to build the spawn-and-move example? I didn't see any build step, does the devcontainer already contain compiled artifacts?

@glihm glihm requested a review from tarrencev December 16, 2023 05:33
@tarrencev
Copy link
Contributor

I'm thinking of generating the two .json file for world and executor during the CI. This can help to prevent someone changing the cairo files, without actually updating the artifacts.

This will also help us ensuring that the rust programs correctly use the cairo methods.

What is the best for that, adding a step in the CI and use sozo to build the spawn-and-move example? I didn't see any build step, does the devcontainer already contain compiled artifacts?

This is currently done here: https://github.com/dojoengine/dojo/blob/main/crates/dojo-test-utils/build.rs

@glihm glihm force-pushed the feat/world-abigen branch from cdc91b8 to 6e7ceac Compare December 20, 2023 03:38
@codecov-commenter
Copy link

codecov-commenter commented Dec 20, 2023

Codecov Report

Attention: 26 lines in your changes are missing coverage. Please review.

Comparison is base (bc42b8e) 59.24% compared to head (3bfcda9) 60.43%.
Report is 6 commits behind head on main.

❗ Current head 3bfcda9 differs from pull request most recent head 62446b7. Consider uploading reports for the commit 62446b7 to get more accurate results

Files Patch % Lines
crates/sozo/src/ops/register.rs 0.00% 7 Missing ⚠️
crates/dojo-world/src/contracts/cairo_utils.rs 73.68% 5 Missing ⚠️
crates/dojo-world/src/contracts/model.rs 78.57% 3 Missing ⚠️
crates/sozo/src/ops/model.rs 0.00% 3 Missing ⚠️
crates/torii/client/src/client/mod.rs 0.00% 3 Missing ⚠️
crates/sozo/src/ops/auth.rs 0.00% 2 Missing ⚠️
crates/sozo/src/ops/migration/mod.rs 85.71% 2 Missing ⚠️
crates/dojo-world/src/contracts/world.rs 92.85% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1010      +/-   ##
==========================================
+ Coverage   59.24%   60.43%   +1.18%     
==========================================
  Files         225      226       +1     
  Lines       18900    18777     -123     
==========================================
+ Hits        11198    11347     +149     
+ Misses       7702     7430     -272     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@glihm
Copy link
Collaborator Author

glihm commented Dec 20, 2023

Due to the dependencies between dojo-world and dojo-lang which are used into dojo-test-utils to actually build the artifacts, the PR for now embed the ABI in the .git.

Inside the dojo-world/src/contracts/abi there is a README to ensure any dev can generate them in case the ABI changes. This anyway will be catch up by the compilation if the bindings are not correct.

@kariy @tarrencev let me know if you have a chance to review and if some stuff here must be re-considered. 🙏

Copy link
Contributor

@tarrencev tarrencev left a comment

Choose a reason for hiding this comment

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

really nice improvement

crates/torii/types-test/Scarb.lock Outdated Show resolved Hide resolved
crates/dojo-world/src/contracts/world.rs Outdated Show resolved Hide resolved
crates/dojo-world/src/contracts/cairo_utils.rs Outdated Show resolved Hide resolved
@glihm glihm requested a review from kariy December 20, 2023 15:59
@glihm glihm merged commit 792194c into dojoengine:main Dec 20, 2023
9 checks passed
@glihm glihm deleted the feat/world-abigen branch December 20, 2023 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants