-
Notifications
You must be signed in to change notification settings - Fork 4
Milestone 4 summary
During the milestone 4 we added the necessary features for interacting with transactions. This work heavily depends on previous milestones, in which we implemented the key derivation features.
During the next sections we will go through the original RFP requirements regarding transactions and also cover most of the development nuances. We can assume that are all the parts are ready for evaluation, unless this document says the opposite.
We are currently able to generate transactions for Transparent
, Sapling
and Orchard
. We decided to concentrate our efforts in exposing the general transaction builder, as it looked the higher level interface for users. During this journey, some decisions were made:
-
The general transaction builder has support for adding
Transparent
andSapling
information to the transaction, but not forOrchard
. Looks like the Orchard support is a work in progress at the time of this write. In the meanwhile, we opted for creating a separated Orchard transaction builder, which uses the Orchard bundle builder under the hood. Whenever the general builder implements the Orchard support, we think this project should strive for exposing it, unifying everything under the same transaction builder. -
Structs with type parameters like lifetimes as in the general transaction builder are not friendly with the UniFFI way of managing lifetimes (and trespassing the FFI barrier in general). Thats one of the reasons because we needed to create an indirection, which first collects the needed information from the user and then, in a final step (the
build()
method), instantiates the original builder, does all the operations in the same function scope and returns the result. The code of the builder can be found here. -
We applied the same strategy for the previously commented Orchard transaction builder as in the above point, but due to different reasons. UniFFI does not support methods that accept a
&mut
references due to its concurrency safe conventions. This forces API implementations to add thread-safe interior mutability patterns, like usingMutex
orRwLock
. Apart from that, the Orchard bundle owned builder exhaust the builder after calling thebuild()
method, by doing a move ofself
. That seems incompatible with UniFFi , as it expects&self
in thebuild()
method. -
Some structs like TransactionsData implements the state pattern by using generic type parameters. In cases like this, we are only exposing the
Authorized
implementation of them, as its the only, final state in which the transactions are returned from builders when invoking thebuild()
method. -
At the time of this write, only python tests are present for transactions. Read more about in the "testing discussion" section below.
All the implemented builders (see above section) , signs the transactions when the build()
method is called. They only return signed transactions.
The first level fields methods of the transaction have been exposed, except the fee_paid()
one. This is because such method requires a closure as parameter, which is not FFI friendly. The code is commented by the way, waiting for an acceptable solution if needed.
The different transaction bundles (Transparent
, Sapling
, Orchard
) which conforms a transaction are also exposed up to a certain grade of detail. It would be relatively easy to add more definition in the future if needed.
For the Orchard
bundle, this crypto methods were also exposed, but we still need to test them. That is going to be addressed in Milestone 5 by this issue.
Transactions implements from_bytes()
and to_bytes()
methods, that should help on fulfilling this requirement and contribute to interoperability.
Initially, team investigations determined there is no such support in librustzcash
library so its currently not implemented. However, we are open to implement this functionality if the community point us to the relevant code.
There is an active discussion in the team regarding having tests for all the relevant languages. Here are the general pros and cons we are analyzing:
- Pros
- They serve as live documentation for the different languages/communities.
- The UniFFI library is still under heavy development. Having tests for all languages apparently give us more confidence that a specific language binding generation its not broken.
- Cons
- It seems we are testing the UniFFI library not only our wrapper code. We think this is not the goal.
- Increased testing time, so slow feedback loop while developing.
We are currently going for implementing all the tests for all languages, specially for the transactions part, as we consider the community will appreciate it.
We also opened this issue for addressing the high CI times in tests.