The components are accessed by a lock on application state. When some command
calls block_on to enter an async context, it obtained a write lock on the
entire application state. This meant that if the application state were
accessed later in an async context, a deadlock would occur. Instead the
TokioComponent holds an Option<Runtime> now, so that before calling block_on,
the caller can .take() the runtime and release the lock. Since we only ever
enter an async context once, it's not a problem that the component is then
missing its runtime, as once we are inside of a task we can access the runtime.
ShieldedData objects must have at least one spend or output; using Either
ensures that at least one must be present. This is similar to the
JoinSplitData case, but slightly more complicated: rather than enforcing that
one list has at least one element (which can be done as `(first, rest)`), here
we need to use Either. This has the downside that it is possible to construct
multiple equivalent internal representations (choosing whether a spend or
output goes in the `first` slot), but this easily fixed with a custom PartialEq
implementation.
This replaces the read_list function and makes the code significantly cleaner.
The only downside is that it loses exact preallocation, but this is probably not a big deal.
In the previous transaction modeling I defined the structs so that the number
of old and new commitments for a JoinSplit were variable, when in fact the
Sprout design fixes both to be 2. So now they are hardcoded as 2 in the source
code as well. This commit also fixes some missing `pub` fields on the
`JoinSplit` struct.
* Added a few more top-level fields for the Transaction struct
* Add a placeholder Script type.
This could alternately use bytes::Bytes to save some allocations
but I don't think this is important to get perfectly now. In the future, we
will want to have all of the script handling code in the zebra-script crate,
but we will need to have a container type for an encoded script in zebra-chain,
because otherwise zebra-chain would depend on zebra-script and not the other
way around.
* Rename Transaction{Input,Output} -> Transparent{Input,Output}.
These are only *transparent* inputs and outputs, so by putting Transparent in
the name (instead of Transaction) it's more clear that a transaction's inputs
or outputs can also be shielded.
* Add a LockTime enum.
* First attempt at a Transaction enum.
This attempts to map the versioning and field presence rules into an ADT, so
that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling
transaction) are unrepresentable.
* Update zebra-chain/src/transaction.rs
Co-Authored-By: Daira Hopwood <daira@jacaranda.org>
* Add fixme note on type refinement.
* Rename Transaction variants according to version.
* Split transaction.rs into submodules.
* Start filling in spend, output descriptions.
* Progress on JoinSplit data structures.
This has a lot of duplication and should really use generics to abstract over
Sprout-on-BCTV14 or Sprout-on-Groth16.
* Add data types for Bctv14 and Groth16 proofs.
This also adds a trait to abstract over them.
* Make JoinSplit descriptions generic over the proof system.
* Update zebra-chain/src/transaction/joinsplit.rs