-
Notifications
You must be signed in to change notification settings - Fork 35
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
Expose APIs for working with transaction proposals #1382
Conversation
9afed2a
to
d4b0306
Compare
35cc57b
to
93e9954
Compare
93e9954
to
4d4d749
Compare
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.
utACK with questions that we should probably create follow-up issues to address.
usk: spendingKey | ||
) | ||
|
||
return txId | ||
logger.debug("transaction id: \(txId)") | ||
return [try await repository.find(rawID: txId)] |
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 repository.find
throw if it cannot find the txid? I would think that ideally that would return an optional result, so that "not found" is distinguished from "error" (though in this particular case you'd want to throw an error anyway, so it's nonblocking for now.)
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 shouldn't encounter this case (successful wallet DB lookup that returns no result) because if we reach here, the transaction was successfully created by the Rust backend (and didn't itself result in an exception). Any exception thrown here would instead be due to database access failures, which are indeed exceptions.
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift
Outdated
Show resolved
Hide resolved
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.
utACK modulo comments.
4d4d749
to
cf6d4a1
Compare
Force-pushed to address review comments. |
cf6d4a1
to
7508fce
Compare
} | ||
} | ||
|
||
public extension Proposal { |
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 would advise not to expose this publicly.
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.
If you have a suggestion for how to avoid exposing this publicly, I'm all ears. The constraint here is Zashi iOS using TCA, which needs to be able to construct mock data to be returned from its mock implementation of the Synchronizer
protocol for use in e.g. preview of UIs (so we can't just return something that would be an error case).
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.
NOTE: I don't know which things you've tried and which ones you haven't, but there are a few things I can think from the top of my head. I promise I'll look this deeper shortly. I might be still lacking context and this could be somewhat inaccurate or insufficient.
A. "Uncle bob's Clean code" approach
Treat the whole SDK as an external dependency under the principle of Bob Martin's clean code architecture. Look at the problem as you were Unstoppable or EDGE and you don't control the dependency. Wrap around it and have a shim that you Do control and use that instead.
B. Pointfree.co / TCA approach.
Make proposal on the SDK Protocol. The SDK returns an implementation of it. Then use a protocol witness or a mock implementation on Zashi to provide the mocked version that you need.
A and B
Make a protocol on Zashi for what the app expects of a proposal. This propocol contains a throwing toProposal()
function.
Make an Adapter of the SDK's Proposal type that conforms to Zashi's.
Make a Mock implementation for testing on Zashi that throws whenever toProposal()
is invoked. If by mistake this ever happens and a mocked proposal is sent in production you can see the error and flag it as critical in Crash reporting platform.
Or better, the testing code is never available in outside of the testing target.
- Returns `null` when there are no funds to shield or the shielding threshold is not met. - Throws an exception if there are funds to shield in more than one transparent receiver within the account. - Has an optional parameter for specifying which transparent receiver to shield funds from. This commit only alters the API to support the above; the functional changes require modifying the FFI and Rust backend, which will happen in a separate commit.
Closes #1186.
67d564f
to
f617f17
Compare
Force-pushed to clean up the commits. |
Includes: - Multi-step transaction proposals. - Changes to support `Synchronizer.proposeShielding` API changes.
I tested all 5 APIs while working on adoption of this PR (e9177a2) in Zashi. I can confirm
|
Before we merge this, I'm going to add a helper method to |
2eeee5f
to
23fd069
Compare
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.
cursory utACK, modulo @pacu's comments
var iterator = transactions.makeIterator() | ||
var submitFailed = false | ||
|
||
return AsyncThrowingStream() { |
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 don't understand exactly how AsyncThrowingStream
works - is it something whereby each time you poll it it invokes this block?
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 async stream and there's a very specific way how to work with it. The stream emits values until it finishes (nil value is emitted). And a client awaits it until the nil is emitted (or an error in case of AsyncThrowingStream - throwing means this stream can emit an error, another stream is AsyncStream which ends only when nil is emitted).
So technically speaking, typically it's not known how many values are emitted, it usually even doesn't matter because the use of stream is implemented as
for try await value in stream { }
This for
will end at some point in the future, the stream can emit 1, 5 or 5M values. The processing lives in an async context so it's not blocking.
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.
re-utACK 72acbc6
72acbc6
to
129ac43
Compare
Force-pushed to remove the 2.0.11 changelog bump, as @LukasKorba will make a few other release updates before the actual release commit. |
Closes #1343.
This code review checklist is intended to serve as a starting point for the author and reviewer, although it may not be appropriate for all types of changes (e.g. fixing a spelling typo in documentation). For more in-depth discussion of how we think about code review, please see Code Review Guidelines.
Author
Reviewer