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 web3::contract::deploy::execute_no_unlock
#252
Conversation
This function is a variant of `web3::contract::deploy::execute` that does not require the account for which it is used to be unlocked.
179a9f0
to
7cb9e68
Compare
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
Introduced in tomusdrw/rust-web3#252.
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.
The overall idea is ok, but there are few improvements to be made.
src/contract/deploy.rs
Outdated
let raw_tx = web3 | ||
.personal() | ||
.sign_transaction(tx, password) | ||
.wait() |
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.
That is making a synchronous call, it's not acceptable in async context.
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.
Then how should I fetch the value that web3.personal().sign_transaction()
returns?
I can chain this computation with and_then(move |signed_tx| {send_raw_transaction_with_confirmation ... }
, but that's only moving the Future
down the line, and the closure can't return one.
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.
Almost forgot: the impl<T: Transport> Future
for SendTransactionWithConfirmation<T>
has type Item = TransactionReceipt
, meaning even if the above is done, we will still be getting a TransactionReceipt
where we should be getting a SendTransactionWithConfirmation<T>
to be used to create a PendingContract
.
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.
Most likely we need to change PendingContract
to be able to work with aribtrary Future
that resolves to TransactionReceipt
:
PendingContract<
T: Transport,
F: Future<Item=TransactionReceipt, Error=...> = SendTransactionWithConfirmation<T>,
> {
}
and then use the and_then
combinator as you've mentioned.
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 was reluctant to change PendingContract
without the go-ahead of someone more knowledgeable about the code base than me. If it sounds reasonable, then I will do so, and re-request a review.
Thank you for your attention 👍
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 understand that the type signatures you wrote here are merely suggestive, but what does F: Future<Item=TransactionReceipt, Error=...> = SendTransactionWithConfirmation<T>
mean?
I have not come across this syntax before.
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.
It's a generic parameter, but with a default value. So that PendingContract<T>
would still be backward compatible, as the F
type would default to SendTransactionWithConfirmation
if omitted.
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 split the two functions back again since the previous refactoring would not work with this change to PendingContract
.
However, now I'm getting an error on this line I am not sure I understand:
F
mismatched types
expected type parameter, found struct `futures::AndThen`
note: expected type `Ft`
found type `futures::AndThen<helpers::CallFuture<types::transaction::RawTransaction, <T as Transport>::Out>, confirm::SendTransactionWithConfirmation<T>, [closure@src\contract\deploy.rs:165:79: 172:10 eth:_, self:_]>`rustc(E0308)
deploy.rs(177, 13): expected type parameter, found struct `futures::AndThen`
I was under the impression and_then
returned a struct, AndThen
, that implemented Future
so I am not sure why PendingContract
would have issues with it.
Do you mind lending me a hand with this? I apologise for my unreasonable request.
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.
The thing is that you let the caller specify Ft
, since it's a generic parameter, but you try to return AndThen
later on.
So the error is just saying that the caller expected a custom Ft
type, but you tried to force AndThen
on them. Try using impl Future
in the returned type of PendingContract
. If not we can just put Box
there.
src/contract/deploy.rs
Outdated
/// `sign_raw_transaction_with_confirmation` instead of | ||
/// `sign_transaction_with_confirmation`, which requires the account from | ||
/// which the transaction is sent to be unlocked. | ||
pub fn execute_no_unlock<P, V>( |
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.
Can we call it sign_and_execute
?
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.
Sure!
src/contract/deploy.rs
Outdated
.personal() | ||
.sign_transaction(tx, password) | ||
.wait() | ||
.expect("Transaction signing failed"); |
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 definitely should not panic if we can't sign the transaction - it should just be a regular Err
that can be later handled by the caller.
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.
You are right.
from: Address, | ||
password: &str, | ||
web3: crate::Web3<T>, | ||
) -> Result<PendingContract<T, Ft>, ethabi::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.
) -> Result<PendingContract<T, Ft>, ethabi::Error> | |
) -> Result<PendingContract<T, impl Future<...>>, ethabi::Error> |
Drop Ft
and try this.
4de83e3
to
6f2f992
Compare
@tomusdrw thank you for all the help. I don't quite like the way |
Have a look at: rockbmb#1 |
9184442
to
2204f5d
Compare
I only now realized I still need to update the |
@rockbmb good to go now? |
@tomusdrw not quite. I'm getting an odd compiler error at I would like to be sure it is not because of anything I did here. |
Maybe add an example/test to this PR so that we can debug it together? |
@tomusdrw I'll add one right next to the test for |
src/contract/deploy.rs
Outdated
/// `sign_raw_transaction_with_confirmation` instead of | ||
/// `sign_transaction_with_confirmation`, which requires the account from | ||
/// which the transaction is sent to be unlocked. | ||
pub fn sign_and_execute<P, V, Ft>( |
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.
The Ft
parameter is unused. This is problematic for calling code because the compiler cannot infer the instantiation of Ft
. This leads to the calling code always requiring an explicit type annotation.
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 just remove it then. I guess I left it by mistake.
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'll try this out.
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.
Does it solve the issues you were having?
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.
It did. I get other errors now, but as far as this PR goes, it has what we need.
Do you still want me to add a test before we merge?
@rockbmb Feel free to add a test in a follow-up PR. |
This PR introduces a variant of
web3::contract::deploy::execute
that does not require the account for which it is used to be unlocked.