-
Notifications
You must be signed in to change notification settings - Fork 67
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 support for typed constructor calls in tests (register
) and deployed code (deploy
)
#1348
Comments
I think a way we could do this is to add an associative type to the The SDK generates an implementation for the The associated type would be required to be For a contract that accepts no args, the associated type would simply be For a contract that accepts args, the associated type would be specified as a tuple of the types the contract requires. The register functions would then reference the associated type as the required type for the args, and then internally convert them to the Vec. We could do the same thing with the deploy function. However, in both these cases we need someway to provide an -out-, if say we're loading a contract and it isn't known what types it accepts, because maybe it doesn't have a spec. We still have to support that case, but I'm not sure if we can support both the typed and untyped approaches. I'll have a play with this idea and see what's possible. |
The 'untyped' approach must remain at least for the I'm not sure if that's what you're already proposing, but could we generate |
I started down the approach of using associated types (1⃣) in #1369, and it does look like the experience of using it would be sweeeeet. However I've run into a problem that defining the types on the associated types is done in Considering other ideas: 2⃣ –
I think we should do it for non-test builds too, so the deploy and register experiences are the same. In your example, the function returns 3⃣ – The register call would look like this:
And the deploy call would look like this:
Conveniently the signature of the register and deploy functions don't change and can be easily used for dynamic dispatch. Inconveniently you have to discover the |
Deploy and register are quite different though. Register is test-only, needs to support compiled-in contracts and doesn't have to support dynamic dispatch. Deploy needs to support dynamic dispatch, is wasm-only and is more sensitive to the amount of code generated. It would be great if we could converge these, but I don't think it's a hard requirement.
Yeah, I think for tests it's actually more intuitive. Maybe the name should be different though, like On a side note, I've just realized that our clients have |
Since it's existed for years, I don't think we need to do anything immediately. If it shows up as a pain point, we can introduce a |
Register does need to support dynamic dispatch for .wasm files loaded. |
This approach ☝ would suffer from the same challenge that #1369 did: generating the |
I've opened a change that I'm experimenting on idea 3⃣ with. It ended up looking a little different: let contract_id = env.register(
Contract,
ContractArgs::__constructor(v1, v2, v3),
); env.deployer()
.with_current_contract(salt)
.deploy_v2(
wasm_hash,
ContractArgs::__constructor(v1, v2, v3),
); The biggest downside of 3⃣ is discoverability 😕. |
### What Add ContractArgs for building function args. ### Usage ```diff -let contract_id = env.register(Contract, (100_u32, 1000_i64)); +let contract_id = env.register(Contract, ContractArgs::__constructor(&100_u32, &1000_i64)); ``` ### Diff of generated code for constructor test vector ```diff @@ -7,6 +7,8 @@ extern crate core; extern crate compiler_builtins as _; use soroban_sdk::{contract, contractimpl, contracttype, Env}; pub struct Contract; +///ContractArgs is a type for building arg lists for functions defined in "Contract". +pub struct ContractArgs; ///ContractClient is a client for calling the contract defined in "Contract". pub struct ContractClient<'a> { pub env: soroban_sdk::Env, @@ -210,6 +212,17 @@ impl<'a> ContractClient<'a> { res } } +impl ContractArgs { + pub fn __constructor<'i>( + init_key: &'i u32, + init_value: &'i i64, + ) -> (&'i u32, &'i i64) { + (init_key, init_value) + } + pub fn get_data<'i>(key: &'i DataKey) -> (&'i DataKey,) { + (key,) + } +} #[doc(hidden)] pub mod ____constructor { use super::*; ``` ### Why To provide a way to make specifying args as concrete. Dependent on: - stellar/rs-soroban-env#1479 Close #1348 ### Note This is still very much an experiment.
What
Add support for typed constructor calls in tests (
register
) and deployed code (deploy
)Why
See:
register
andregister_at
fns to replaceregister_contract
,register_contract_with_constructor
,register_contract_wasm
,register_contract_wasm_with_constructor
#1343 (comment)The text was updated successfully, but these errors were encountered: