`ReceivedNote` now allows Orchard notes to be represented as received
notes. As part of this change, received notes now track whether they
were received using internally- or externally-scoped viewing keys.
This eliminates the need to trial-regenerate notes using the wallet's
IVKs to determine scope at spend time.
Public methods for mutation of these fields have been provided that
perform checking for overflow of the valid monetary range as part
of their operation.
Prior to this change, it's necessary to implement the entirety of the
`WalletRead` trait in order to be able to use the input selection
functionality provided by `zcash_client_backend::data_api::input_selection`.
This change factors out the minimal operations required for transaction
proposal construction to better reflect the principle of least authority
and make the input selection code reusable in more contexts.
In order to minimize the operations of the newly-created `InputSource`
and `ShieldingSource` traits, this change also removes the
`min_confirmations` field from transaction proposals, in favor of
storing explicit target and anchor heights. This has the effect of
limiting the lifetime of transaction proposals to `PRUNING_DEPTH -
min_confirmations` blocks.
In order to use `uint64` for amounts that must be nonnegative in the
`proposal.proto` file, it is useful to update fee and change computation
to use `NonNegativeAmount` where possible.
This fixes the following bug:
Due to complexities related to non-linear scanning, checkpoints are only
added to the wallet's commitment tree in cases where there are notes
discovered within a scanned block. At present, the `shardtree` API only
makes it possible to add multiple checkpoints of the same tree state
when adding checkpoints at the chain tip, and this functionality is not
used by `zcash_client_backend` because we perform checkpoint insertion
in batches that may contain gaps in the case that multiple blocks
contain no Sapling notes. While it would be possible to fix this by
altering the `shardtree` API to permit explicit insertion of multiple
checkpoints of the same tree state at a given note position, this fix
takes a simpler approach.
Instead of ensuring that a checkpoint exists at every block and
computing the required checkpoint depth directly from the minimum number
of confirmations required when attempting a spend, we alter the
`WalletCommitmentTrees` API to allow internal information of the note
commitment tree to be used to determine this checkpoint depth, given the
minimum number of commitments as an argument. This allows us to select a
usable checkpoint from the sparse checkpoint set that resulted from the
sparse insertion of checkpoints described above.
The intent of this API is to provide a single API which returns in a
single call:
* per-account balances, including pending values
* wallet sync progress
Fixes#865Fixes#900
This also removes the zcash_client_sqlite-specific database
initialization procedures in favor of a standardized approach using the
methods available via the data access API.
Prior to the scan-before-sync changes, the wallet was able to assume
that the maximum scanned block height at the time of the spend was
within a few blocks of the chain tip. However, under linear scanning
after the spend-before-sync changes this invariant no longer holds,
resulting in a situation where in linear sync conditions the wallet
could attempt to create transactions with already-past expiry heights.
This change separates the notion of "chain tip" from "max scanned
height", relying upon the `scan_queue` table to maintain the wallet's
view of the consensus chain height and using information from the
`blocks` table only in situations where the latest and/or earliest
scanned height is required.
As part of this change, the `WalletRead` interface is also modified to
disambiguate these concepts.
In general, it is preferable to use globally relevant identifiers where
possible. This PR removes the `WalletRead::TxRef` associated type in
favor of using `TxId` directly for the transaction identifier, and
restricts the use of the `NoteRef` type to those scenarios where the
result of one query is intended to be used directly as the input to
another query.
Closes#834
This implements a priority queue backed by the wallet database for scan
range ordering. The scan queue is updated on each call to `put_blocks`
or to `update_chain_tip`.
Instead of calling `put_block` for each block scanned,
`scan_cached_blocks` will now defer the block writes until the scan of a
batch is complete and will perform the block writes and note commitment
tree updates all within a single transaction.
This should ordinarily be fine in terms of memory consumption, because
the block data being saved is pruned to only that spend an output
information that is related to transactions in the wallet, which will
normally be sparse enough that the block range size that is appropriate
for a given platform to run within a batch scanner adequately bounds the
memory consumption of this pruned representation.