Replace Backend.{createToAddress, shieldToAddress} with proposal-based methods#1344
Conversation
| companion object { | ||
| fun parse(encoded: ByteArray): ProposalUnsafe { | ||
| val inner = Proposal.parseFrom(encoded) | ||
| return ProposalUnsafe(inner) |
There was a problem hiding this comment.
Despite this being called ProposalUnsafe, I expect we'll do most validation in this class because we have access to the parsed protobuf (which can't be used outside backend-lib without requiring sdk-lib to depend on the protobuf library, and I figure it's better to keep it being a backend-internal detail). The wrapping Proposal in sdk-lib is wrapping the exposed types here in safe API types like Zatoshi.
There was a problem hiding this comment.
Yes, that is the way we do it with the other models as well.
nuttycom
left a comment
There was a problem hiding this comment.
utACK with nonblocking nits. Some of these, on further reflection, are just design issues that should probably be cleaned up separately; the one that I'd like clarification on is the UnsafeProposal vs Proposal situation and the meaning of the parse method on Proposal; please document those types/methods more completely.
| import cash.z.wallet.sdk.ffi.ProposalOuterClass.FeeRule | ||
| import cash.z.wallet.sdk.ffi.ProposalOuterClass.Proposal | ||
|
|
||
| class ProposalUnsafe( |
There was a problem hiding this comment.
Does this need to be documented, or is it not exposed to the SDK user?
There was a problem hiding this comment.
I don't intend for it to be exposed to the SDK user, but IDK if I succeeded within Kotlin.
There was a problem hiding this comment.
It's not ideal, as the class is still reachable from clients, but this is how we used to with, e.g., jni models too. We're helping ourselves with the internal in the package.
| .map(|account| { | ||
| let account_id = AccountId::from(account); | ||
| let account_id = | ||
| AccountId::try_from(account).map_err(|_| format_err!("Invalid account ID"))?; |
There was a problem hiding this comment.
Since accounts has been cast from a jint, it cannot be more than 2^31-1, so this error should never occur. This could also be an expect.
| fn account_id_from_jint(account: jint) -> Result<AccountId, failure::Error> { | ||
| u32::try_from(account) | ||
| .map_err(|_| ()) | ||
| .and_then(|id| AccountId::try_from(id).map_err(|_| ())) |
There was a problem hiding this comment.
This try_from should never be able to fail, because the u32::try_from will have ensured that the resulting u32 falls into the valid range of account IDs. I think that using map and expect here would actually be appropriate, because if the inner try_from fails that should indicate that something is crashingly wrong.
| output_params: JString<'_>, | ||
| network_id: jint, | ||
| use_zip317_fees: jboolean, | ||
| ) -> jbyteArray { |
There was a problem hiding this comment.
nit: It might be nice to have a type alias for jbyteArray that indicates that this is a serialized proposal protobuf. The fact that the return type didn't change was a little disorienting.
nuttycom
left a comment
There was a problem hiding this comment.
Now that [zcash/librustzcash#1060] has merged, please update proposal.proto before this merges.
e503d16 to
c00b0de
Compare
c00b0de to
0a7cf96
Compare
|
Force-pushed to address review comments. |
nuttycom
left a comment
There was a problem hiding this comment.
proposal.proto is still the older version, not what's on current ][zcash/librustzcash@main]
0a7cf96 to
b3cfad5
Compare
|
Force-pushed to update |
|
There appear to be a bunch of linting errors being reported. |
HonzaR
left a comment
There was a problem hiding this comment.
Thanks for these changes. I just pushed a few minor commits.
IIUC our intention here is to have a two-step transaction submitting? I.e. 1. get transaction proposal, 2. submit transition.
To achieve this, we need to update the Synchronizer's API to provide the new propose API methods, which would call related missing propose methods in the txManager and tweak the existing sendToAddress and shieldToAddress Is that correct?
| companion object { | ||
| fun parse(encoded: ByteArray): ProposalUnsafe { | ||
| val inner = Proposal.parseFrom(encoded) | ||
| return ProposalUnsafe(inner) |
There was a problem hiding this comment.
Yes, that is the way we do it with the other models as well.
| import cash.z.wallet.sdk.ffi.ProposalOuterClass.FeeRule | ||
| import cash.z.wallet.sdk.ffi.ProposalOuterClass.Proposal | ||
|
|
||
| class ProposalUnsafe( |
There was a problem hiding this comment.
It's not ideal, as the class is still reachable from clients, but this is how we used to with, e.g., jni models too. We're helping ourselves with the internal in the package.
It's not strictly necessary, but it would make the most sense to do this. If we don't make this change then we end up calling the propose API twice, once to get the fee and then again during transaction creation, and the second time the fee could technically change. If we expose a Eventually we will want to enable the SDK user to request that proofs start being created in the background at the time the |
b6656fe to
8f5b3c2
Compare
|
Rebased on #1357 and now targeting the 2.1.0 feature branch. I will rebase again once that merges. |
8f5b3c2 to
14da738
Compare
|
Rebased on |
14da738 to
457984e
Compare
…sed methods Closes #1338.
- This copies the pattern from lightwallet-client-lib module where we set the package for the generated classes - It adds internal to the path, to be explicit about not exposing it out of the backend module
457984e to
f3a56d1
Compare
|
Force-pushed to fix lints. |
HonzaR
left a comment
There was a problem hiding this comment.
Additionally, I tested it with Zashi via included builds, and it works as expected.
Migrates to the latest in-progress revision of the Zcash Rust crates, so this is not suitable for inclusion in an SDK release yet.
Closes #1338.
Author
Reviewer
Footnotes
Code often looks different when reviewing the diff in a browser, making it easier to spot potential bugs. ↩
While we aim for automated testing of the SDK, some aspects require manual testing. If you had to manually test
something during development of this pull request, write those steps down. ↩
While we are not looking for perfect coverage, the tool can point out potential cases that have been missed. Code coverage can be generated with:
./gradlew checkfor Kotlin modules and./gradlew connectedCheck -PIS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=truefor Android modules. ↩Having your code up to date and squashed will make it easier for others to review. Use best judgement when squashing commits, as some changes (such as refactoring) might be easier to review as a separate commit. ↩
In addition to a first pass using the code review guidelines, do a second pass using your best judgement and experience which may identify additional questions or comments. Research shows that code review is most effective when done in multiple passes, where reviewers look for different things through each pass. ↩
While the CI server runs the demo app to look for build failures or crashes, humans running the demo app are
more likely to notice unexpected log messages, UI inconsistencies, or bad output data. Perform this step last, after verifying the code changes are safe to run locally. ↩