In zcash/zcash/pull/5544 we added an FFI method specific to the Orchard
part of the transaction builder, to enable passing the Orchard bundle on
the Rust side directly instead of using a partial serialization. We
passed the remainder of the transaction to the Rust side by serializing,
as we similarly do in `SignatureHash`. We then decomposed the parsed
transaction on the Rust side to insert the Orchard bundle. However, we
then used the `TxDigests` that was derived from the parsed transaction,
not the reconstructed one, which meant we produced an invalid sighash
when building Orchard-containing transactions.
The addition of `OrchardRawAddress` to `RecipientAddress` drives most of
the changes in this commit, which enable `z_sendmany` to send funds to
addresses in the Orchard pool once NU5 activates.
We add the Orchard change address mapping on account creation, as we
only ever generate a single change address internally. External Orchard
receivers are added to the map when `z_getaddressforaccount` is called.
This commit also fixes two bugs in the handling of Orchard internal IVKs.
When adding a full viewing key to the Orchard (Rust) wallet, we need to
derive both the internal and external IVKs (and map them to the external
FVK so we effectively never expose the internal FVK). We were only
deriving the external IVK, meaning that trying to add the Orchard change
address to the wallet should have failed. However, in a separate bug the
C++ internal IVK derivation method was calling the Rust external IVK
derivation function, meaning that we were effectively using the external
Orchard address at index 0 _as_ the change Orchard address.
This tests the following operations:
* add a spending key to the wallet
* add notes from the Orchard bundle component of a transaction to the
wallet
* detect notes in the wallet that correspond to the spending key
* verify that notes that are not ours are not mistakenly labeled
as ours
This also alters `TransactionBuilder::SendChangeTo` to take a
`libzcash::ChangeAddress` value and thus avoids the invalid
t-addr case of CTxDestination.
We use the `zcash_address` crate to parse Unified Addresses (which we
currently do nothing with). That crate returns an `UnsupportedAddress`
error for unhandled address kinds, which we were previously logging.
However, we _do_ support the other address kinds; we just parse them in
the C++ code.
Closeszcash/zcash#5321.
This type is backed by the `zcash_address` implementaion of
unified full viewing keys. It is intended for serialization
and parsing of UFVKs, and provides conversion functions that
allow for construction to and from ZcashdUnifiedFullViewingKey
values.
Adds SaplingDiversifiableFullViewingKey as a superclass of
SaplingExtendedFullViewingKey, and reduces the Sapling component
of UnifiedFullViewingKey to the new intermediate type. This
permits deserialization from the data that will be present
in the serialized form of the Sapling component of a UFVK.
Remove IncrementalSinsemillaTree; this will be replaced by
a more full-featured OrchardWallet type which embeds the
incremental merkle tree used in wallet operations.
Having this be a submodule of `orchard_ffi` while following Rust 2018
module structure made it impossible to use the `include!` macro on
`orchard_ffi.rs`, which is exactly what the `zcash_script` crate does.
See this comment for details:
https://github.com/rust-lang/rust/issues/50132#issuecomment-969450868
To resolve this, we restructure the FFI library crate to only have FFI
methods in "leaf" module files.
In order to support generation of unified addresses, it needs
to be possible for the code generating a unified address to search
the space of Sapling diversifiers to obtain a valid diversifier.
Historically, invalid diviersifiers were simply skipped, so we retain
this behavior when obtaining a Sapling address from the legacy HD seed.
We are already checking the other bundle-specific consensus rules:
- Encodings are checked during transaction parsing.
- Signatures are batch-validated.
Closeszcash/zcash#5195.
- Currently, only RedPallas signatures are batch-validated. We can extend
this validator to cover Halo 2 proofs in the future.
- Signatures in a batch are not retried individually if the batch fails:
- For per-transaction batching (when adding to the mempool), we don't
care which signature within the transaction failed.
- For per-block batching, we currently don't care which transaction
failed. We might do so in future, at which point this behaviour can
be easily changed.
The C++ parser only requires the various Sapling components to be 32-byte
arrays. The Rust parser enforces stricter type checks at parse time, and
we now unconditionally parse with the Rust parser for deriving txids.
The majority of the parser is in C++, but Orchard bundles are parsed
exclusively by Rust.
The ZIP 244 test vectors are brought in here so we can start by testing
round-trip serialization.
In addition to the specified consensus rules, we unconditionally enable
ZIP 216 in the following situations:
- Wallet code
- Transaction building
- Nullifiers for wallet notes
- Tests
- Benchmarks
Closeszcash/zcash#5201.
Given that label values may be dynamic, any metrics callsite with labels
can't be stored statically. Instead, we contruct a fresh metrics Key each
time we hit a metric with labels (if a metrics recorder is installed).
Leverages the VA_OPT macro library, which is a polyfill for __VA_OPT__
on non-C++20 platforms, to enable TracingSpan to support optional fields.
Source: https://github.com/willwray/VA_OPT
License: Boost Software License, Version 1.0
The layer creation itself looks a bit more complex, but this is due to
how altering the presence of timestamps changes the type signature of the
formatter. The main improvements are that we now only initialise the
registry in a single location, and the log filter reload handle has a
single type signature (whereas previously its type signature depended on
the configuration).
Requires a minimum of tracing-subscriber 0.2.12, which added this feature.
Part of zcash/zcash#4668.
Some consumers were relying on the libsodium behaviour that the output
length was not checked against the configured hash output length.
blake2b_simd::Hash::as_bytes returns a correctly-sized slice, which we
were then failing to copy into the consumer's buffer. Instead of
requiring the consumer to provide a full-length buffer and then truncate
the output themselves (likely causing a double-copy, as we don't have
nice slices in C++), we instead allow the consumer to consume up to the
maximum output.
crypto_sign_verify_detached is still used within the consensus rules
until Canopy activation. ed25519-zebra generates signatures that are
valid under both pre- and post-Canopy rules (for our honest usage),
so we can use it to generate transaction signatures now. Then once
Canopy activates, we can remove the remaining usages of crypto_sign.
Add support for logging fields in spans and events
Field values must be pointers to C strings, which in practice means that they
cannot be formatted inline (as the pointer must remain valid across the FFI).
This might be improved by future iterations of the macros.
`LogPrint()` is also moved to the DEBUG level, leaving `LogPrintf()` at INFO.
This will make it possible to de-duplicate some components of the
tracing configuration. The layers themselves cannot be fully
de-duplicated due to type system constraints (a Layer wraps a
Subscriber, and is itself a Subscriber typed on the one it wraps).
Windows uses u16 for OS strings, requiring an owned OsString when
converting to Rust. This needs to be stored in its own variable, so we
can take an immutable reference to it in Path::new.
Due to tracing's extensive use of the Rust type system, we have to Box
the handle in order to pass it back across the FFI. We define a
ReloadHandle trait which exposes the necessary Handle APIs.
The tracing crate is initialized with an optional log path, and will
either start a background thread for non-blocking log writing, or write
directly to standard output with ANSI encoding.
C preprocessor macros are used to emulate the Rust macros natively
provided by the tracing crate. They handle the creation of static
tracing callsites, and ensure that the correct file and line number
information is used for each logging site.
We only relied on success being 0 and our code was otherwise agnostic to the
actual return code in the event of failed signature verification, but this
change keeps the API consistent.
std::vector<T> is guaranteed to store T contiguously. However, there is
no guarantee that sizeof(std::array<unsigned char, N>) == N, which
prevents us from interpreting std::vector<std::array<unsigned char, N>>
as &[[u8; N]] on the Rust side of the FFI.
Instead, we define HistoryEntry as a struct wrapping a C array, which
(as checked by static_assert) contains no padding.
This enables IDE integration to work (which requires the Cargo.toml to
be in the repo root).
"make clean" no longer runs "cargo clean", because IDE integrations hold
locks on files within the Rust build directory, and an error inside
"cargo clean" error would prevent "make clean" from completing (and
removing other files).
The Cargo.lock is updated to account for the Zcash Rust crates no longer
being in the same workspace. Dependencies that were not transitive
dependencies of librustzcash are also removed, but no versions change.