This change modifies note encryption and decryption functions
to treat a shielded output as a single value instead of handling
the parts of an output as independent arguments.
This commit introduces a `Domain` trait which defines the types
and operations that are shared between Sapling and Orchard note
encryption and decryption processes.
Previously we were retrieving nullifiers for notes that were not
marked spent, but not checking against whether the spending
transaction had been included in a block.
`create_spend_to_address` was originally written only for sending to
Sapling addresses. It was later amended to support sending to
transparent addresses, but the assumption about there being a Sapling
output was not removed. This was not an issue for most transactions
because there would be change, but in the case of a z->t transaction
with no change, `create_spend_to_address` would reliably panic.
This commit fixes the bug by setting the output index for transparent
recipients to 0. The `output_index` field of `SentTransaction` is also
documented to correctly reflect its dependency on the type of
`recipient_address`.
Memo fields have two ways to encode an empty memo:
- 0xF6 followed by all-zeroes, encoding "there is no memo".
- All-zeroes, encoding the empty UTF-8 string.
In almost all cases you want the former, but users thinking about byte
slices may expect MemoBytes::default() to result in the latter. To
ensure clarity, we now require calling either MemoBytes::default() or
MemoBytes::from_bytes(&[]) to be explicit.
No such confusion exists for the Memo enum, because the two types are
visibly separated as different enum cases, and Memo::Empty makes sense
as the default.
The MemoBytes struct is a minimal wrapper around the memo bytes, and only
imposes the existence of null-padding for shorter memos. The only error
case is attempting to construct a memo that is too long. MemoBytes is
guaranteed to be round-trip encodable (modulo null padding).
The Memo enum implements the additional memo rules defined in ZIP 302,
interpreting the contents of a memo (for example, parsing it as text).