-
Notifications
You must be signed in to change notification settings - Fork 126
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
Fixing tx-builder-config-builder to take references and not values #269
Fixing tx-builder-config-builder to take references and not values #269
Conversation
Missed this when we've been merging the config PR itself, but if used with values and not references in JS - the passed values are very much getting consumed as well, which causes way too many hidden problems. |
self | ||
} | ||
|
||
pub fn key_deposit(mut self, key_deposit: BigNum) -> Self { | ||
self.key_deposit = Some(key_deposit); | ||
pub fn pool_deposit(mut self, pool_deposit: &BigNum) -> Self { |
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'm fairly certain this (BigNum
passed by-value) is present in other areas. I know it implements Copy
in rust but I'm not sure if that is enough to not cause issues when it goes through the wasm-bindgen boundary.
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.
For me it caused problem when being passed by value - that value then gets very counter-intuitively erased when used from JS. I will double-check then where it's being used by-value, might also need to be fixed if this is something that is used from JS as well.
Did you see the comments I left in #261 regarding the config builder? |
I think wasm-bindgen would handle code breaking because of passing by value. Since that would break how javascript works. For example if you have a function in rust that takes by value let my_s = "hello world";
process_string(my_s);
console.log(my_s); It should still print hello world? There is example here that shows that it works: https://rustwasm.github.io/docs/wasm-bindgen/reference/types/exported-rust-types.html#exported-struct-whatever-rust-types |
The problem (at least from what I remember) is when you have non-primitive types that don't have some special into wasm ABI or whatever trait defined where I think it moves it out, since in JS they're just a handle/ptr into wasm linear memory, not an actual JS primitive So |
The problem happens when we have non-native types, as correctly mentioned by Rob, strings are a very special case because in your example you have a JS type string which is being converted into the Rust type when passed in and the Rust type will probably get consumed in this case, but the original JS type will continue working. Meanwhile we have a lot of case when a Rust type value is being stored in js and then reused, e.g.
If |
Thank you for the explanation. I think in this case taking self by value can be bad here also. For example if the user creates a config buider in one place and tries to update it conditionally he has to do: let cfg_builder = CfgBuilder::new();
if (cond) {
cfg_builder = cfg_builder.pool_deposit(my_deposit); // this is what the user has to do
cfg_builder.pool_deposit(my_deposit); // this destroys the cfg_builder and makes a bug
} I am trying to look into this |
@rooooooooob , I saw them now, yes. Left a comment there: #261 (comment) |
Oh, this is a really good point! I will test it out in JS now, If this is really the case - we defo have to change then |
I checked and looks like this is the case, so we have to change the api to avoid this |
Yes, double checked, the third line in this example crashes:
@ozgrakkurt , can you plz create a separate branch an a PR that fixed this? |
I think the cleanest solution to this might be:
this way user can construct this like a js object and pass it to Another good thing about this option is we can leave the builder methods as they are so they can be used in Rust. But js users can pass JsValue. I'm not sure if this is the best way. Alternatively we can make builder methods take reference of self and return nothing. const x = this.WalletV4.TransactionBuilderConfigBuilder.new();
x.max_tx_size(42);
x.max_value_size(42); And can't do this: const x = this.WalletV4.TransactionBuilderConfigBuilder.new()
.max_tx_size(42)
.max_value_size(42)
.build(); @rooooooooob @vsubhuman what are your opinions on this? |
This might be a problem to rely on JSON parsing on the JS-WASM boundary, since we are passing problematic values like
Would it be too big of a problem to clone self on every return? Because then it would be fine with the expectations, e.g.:
This would be 100% compatible with usual builder conventions |
Yes, now that looks like the best solution to me as well, thanks. I can do that in this branch if it's ok, or I can create a seperate one. |
Let's create a separate one, meanwhile I'll get this one merged 👌 |
No description provided.