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

Add generate-types crate #63

Merged
merged 12 commits into from
Apr 4, 2024
Merged

Add generate-types crate #63

merged 12 commits into from
Apr 4, 2024

Conversation

JesseAbram
Copy link
Member

Adds a generate type crate that can help generate config and aux types

Copy link

vercel bot commented Mar 25, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
programs ❌ Failed (Inspect) Mar 26, 2024 3:09pm

@JesseAbram JesseAbram marked this pull request as ready for review March 26, 2024 15:43
@HCastano HCastano changed the title add generate types crate Add generate-types crate Mar 27, 2024
Copy link
Contributor

@HCastano HCastano left a comment

Choose a reason for hiding this comment

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

Okay so I see the intention in this PR, but I think we can improve this. My high level
suggestions here:

Let's get rid of the generate-types crate. Instead if we want to show people in this
repo how to get the type definitions we can: add an example Rust code snippted to the
README, add a doc-test to the examples, or a normal test in the examples.

Let's add the actual generation to the test-cli in the Core repo (schemar annotations
are fine here). There we can add CLI options for outputing the JSON schema formatted
data, or hex-bytes depending on what the user prefers.

This should give us a more robust and usable solution that can be used across all
programs, not just one specific example program.

Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to commit generated artifacts. Anybody that needs them can just run the code and get this themselves

Copy link
Member Author

Choose a reason for hiding this comment

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

ya but this is an example so people can see

Comment on lines 6 to 13
fs::write(
"./device_key_proxy_config_type.txt",
format!(
"{:?}",
serde_json::to_vec(&schema_config_device_key_proxy)
.expect("error converting user config for device key proxy")
),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't be dumping bytes to a file.

Instead we should leave the JSON Schema object in tact, and then consumers can decide how to use that data themselves. One of those options can be transforming in to bytes (e.g using something like xxd, or another Rust program).

Copy link
Member Author

Choose a reason for hiding this comment

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

the bytes are the format we want to actually post on chain so people can copy paste them if they need or feed them into a script

Comment on lines 6 to 14
fs::write(
"./device_key_proxy_config_type.txt",
format!(
"{:?}",
serde_json::to_vec(&schema_config_device_key_proxy)
.expect("error converting user config for device key proxy")
),
)
.expect("Failed to write to device key proxy config");
Copy link
Contributor

Choose a reason for hiding this comment

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

To my comment above, I would do something like this instead

Suggested change
fs::write(
"./device_key_proxy_config_type.txt",
format!(
"{:?}",
serde_json::to_vec(&schema_config_device_key_proxy)
.expect("error converting user config for device key proxy")
),
)
.expect("Failed to write to device key proxy config");
println!(
"{}",
serde_json::to_string_pretty(&schema_config_device_key_proxy)
.expect("error converting user config for device key proxy")
);

@JesseAbram
Copy link
Member Author

Okay so I see the intention in this PR, but I think we can improve this. My high level suggestions here:

Let's get rid of the generate-types crate. Instead if we want to show people in this repo how to get the type definitions we can: add an example Rust code snippted to the README, add a doc-test to the examples, or a normal test in the examples.

Let's add the actual generation to the test-cli in the Core repo (schemar annotations are fine here). There we can add CLI options for outputing the JSON schema formatted data, or hex-bytes depending on what the user prefers.

This should give us a more robust and usable solution that can be used across all programs, not just one specific example program.

but the test cli does only feeds in the compiled wasm (which requires the serialized types at chain upload time) you can't get the needed types from the bytecode. As well I agree this is not perfect, the whole flow kinda sucks. We should have a package you can pull down to write a program and autogenerate the template code, that should also have a generate types functions, that I think is doable but takes a lot of steps. IMO this is a good incremental step before that, which tests out the thesis and moves us along

Copy link
Contributor

@HCastano HCastano left a comment

Choose a reason for hiding this comment

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

but the test cli does only feeds in the compiled wasm (which requires the serialized
types at chain upload time) you can't get the needed types from the bytecode.

Good point. I guess this is something we can look into improving down the line.

As well I agree this is not perfect, the whole flow kinda sucks. We should have a
package you can pull down to write a program and autogenerate the template code, that
should also have a generate types functions, that I think is doable but takes a lot of
steps. IMO this is a good incremental step before that, which tests out the thesis and
moves us along

I don't think we should be shipping a crate for this very specific example. We can test
the thesis in a better way.

We're better off showing people how to do this themseleves for any program using a
doctests and/or an example in the README.

We can still include some portion of the byte-string to show people what is expected
on-chain, but I still wouldn't include the whole set of bytes (which can change at any
time anyways if fields change).

I've included a rough suggestion on how to do this. I can also make a PR into this PR if
you want me to flesh this out further.

@ameba23
Copy link
Contributor

ameba23 commented Mar 27, 2024

I haven't got around to looking at this in detail but it looks good.

One thing we could do to encourage people to use this is add schemars to the Cargo.toml of the cargo-generate template: https://github.com/entropyxyz/programs/tree/master/templates/basic-template

Possibly we could also include the function there from generate-types/src/main.rs so that people can build the schemas right out of the box with their own program. But im not sure if we could have a main fn there without it meddling with building the program itself.

It would be cool if there was some way to make the generic-types crate more generic - as in have a way of specifying what program you want it to build from without manually changing the code. But i can't think of a way to do that.

@JesseAbram
Copy link
Member Author

I haven't got around to looking at this in detail but it looks good.

One thing we could do to encourage people to use this is add schemars to the Cargo.toml of the cargo-generate template: https://github.com/entropyxyz/programs/tree/master/templates/basic-template

Possibly we could also include the function there from generate-types/src/main.rs so that people can build the schemas right out of the box with their own program. But im not sure if we could have a main fn there without it meddling with building the program itself.

It would be cool if there was some way to make the generic-types crate more generic - as in have a way of specifying what program you want it to build from without manually changing the code. But i can't think of a way to do that.

totally agreed, I know this is only a half step, maybe a macro to do it automatically or something, but either way dev ex here is way lacking, in fact this repo should not be used at all to make programs, there should be a cargo init and it have a template with this, not exactly sure, for me this is a half measure until we figure out a full devex plan

@JesseAbram JesseAbram requested a review from HCastano April 1, 2024 18:20

[dependencies]
entropy-programs-core={ git="https://github.com/entropyxyz/programs.git", tag="v0.8.0" }
[workspace]
Copy link
Contributor

@ameba23 ameba23 Apr 2, 2024

Choose a reason for hiding this comment

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

I would maybe keep the program itself in the top-level of the workspace - eg:

[workspace]
members = [".", "generate-types"]

[package]
name = "{{project-name}}"
version = "0.1.0"

etc.

This would also mean there would be just one readme - not one for the workspace and one for the program itself.

Copy link
Member Author

Choose a reason for hiding this comment

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

ehhhh idk, this can grow and Im just going off my recollections of eth dev, I liked you know tests and contracts being in separate repos, Im ok getting out voted here I just idk feels icky

Copy link
Contributor

Choose a reason for hiding this comment

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

@JesseAbram I'm with Peg here, I would prefer the program at the top level

Copy link
Member Author

Choose a reason for hiding this comment

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

ok bet I still disagree but will do

#[cfg_attr(feature = "std", derive(schemars::JsonSchema))]
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct AuxData {
}
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@ameba23 ameba23 left a comment

Choose a reason for hiding this comment

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

Looks great - assuming generating schemas for a template works - i haven't tried it.

As i said in other comment, i would keep the program itself top-level, and have just one readme, which can include the instructions for generating types. I guess we can put more details about what you should actually do with these schemas when you want to publish a program in a separate PR once its possible to do that from the SDK or some other programs build tool. I guess eventually we'll have something which compiles the program, generates the schemas and bundles it all into a set_program extrinsic.

@JesseAbram
Copy link
Member Author

Looks great - assuming generating schemas for a template works - i haven't tried it.

I have lol, super unfun to test

As i said in other comment, i would keep the program itself top-level, and have just one readme, which can include the instructions for generating types. I guess we can put more details about what you should actually do with these schemas when you want to publish a program in a separate PR once its possible to do that from the SDK or some other programs build tool. I guess eventually we'll have something which compiles the program, generates the schemas and bundles it all into a set_program extrinsic.

Pretty much what I was thinking, the generate can be its whole own tool that can take someone from cargo generate to deploy

Copy link
Contributor

@HCastano HCastano left a comment

Choose a reason for hiding this comment

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

Main change I'd want here is the workspace this.

I like this approach better than the last one, specifically that it ties the type generation to the program a bit closer.

The workflow could still be improved, but I'm okay kicking that down the road a bit further.

license = "Unlicense"
edition = "2021"

# This is required to compile programs to a wasm module
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to update the comment to specify that the Wasm required crate-type is cdylib and rlib is used for library-like uses

@@ -11,7 +11,7 @@ edition = "2021"

# This is required to compile programs to a wasm module
[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib", "rlib"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Same thing here


[dependencies]
entropy-programs-core={ git="https://github.com/entropyxyz/programs.git", tag="v0.8.0" }
[workspace]
Copy link
Contributor

Choose a reason for hiding this comment

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

@JesseAbram I'm with Peg here, I would prefer the program at the top level

fn main() {
let schema_config = schema_for!(UserConfig);
fs::write(
"./config_type.txt",
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be in the .gitignore


let schema_aux_data = schema_for!(AuxData);
fs::write(
"./aux_data_type.txt",
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

Copy link
Contributor

Choose a reason for hiding this comment

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

I would look into attaching a name to the generated files as well, like {{ project_name }}_serialized_configuration_data

crate-type = ["cdylib", "rlib"]

[dependencies]
entropy-programs-core={ git="https://github.com/entropyxyz/programs.git", tag="v0.8.0" }
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably release this to crates.io at some point 😅

templates/basic-template/generate-types/Cargo.toml Outdated Show resolved Hide resolved
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
@JesseAbram JesseAbram merged commit db7ecd3 into master Apr 4, 2024
2 checks passed
@HCastano HCastano deleted the generate-types branch April 5, 2024 15:37
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.

3 participants