Commit Graph

16167 Commits

Author SHA1 Message Date
therealyingtong 8a7283ca83 Introduce CWallet::HaveOrchardSpendingKeyForAddress. 2022-04-06 20:34:38 +08:00
str4d 9e80e4aff6
Merge pull request #5819 from ebfull/fix-rescans
Fix logic for deciding whether to perform Orchard updates during rescan
2022-04-05 14:53:17 +01:00
Kris Nuttycombe 53a302cf3f
Merge pull request #5789 from nuttycom/bug/wallet_init_post_nu5
Fix a bug in initialization of the Orchard wallet after NU5 activation.
2022-04-04 20:06:34 -06:00
Kris Nuttycombe 98c848fd20
Merge pull request #5809 from str4d/5805-fix-thread-notify-wallets-init
wallet: Initialise ThreadNotifyWallets with wallets best block
2022-04-04 20:04:53 -06:00
Sean Bowe 979d0b5ee3
Fix logic for deciding whether to perform Orchard updates during rescan
In `ScanForWalletTransactions` we skip forward from `pindexStart` to a block
near our wallet birthday. But we use this as the basis for deciding the value
of `performOrchardWalletUpdates` later, which is wrong because our wallet
birthday might be beyond the NU5 activation height. The result is that we
won't actually perform the required scanning (mainly witnessing and so forth)
needed to spend notes in our wallet.
2022-04-04 16:06:11 -06:00
Kris Nuttycombe 8e4dd1e964 Only check nWitnessCacheSize on rewind if we've ever witnessed a Sprout or Sapling note.
This allows "rollback" for empty Sapling wallets injected into nonempty
chain state that is then rolled back.
2022-04-04 15:31:19 -06:00
ebfull fbddebc63f
Merge pull request #5804 from str4d/consensus-check-coinbase-shielded-spends
Apply HaveShieldedRequirements to coinbase transactions
2022-04-04 14:28:52 -06:00
Kris Nuttycombe afb503503d Omit check of Orchard commitment root after rewind past first checkpoint.
If we no longer have any checkpoints in the Orchard wallet, we must
skip the check against the prior note commitment tree root because
we know that the Orchard wallet's state may be for a chain that is
being reorg'ed away. This is safe because we know that we will have
removed all information from the wallet that we need to perform spends
from that state, and we also know that when we start rolling forward
along the new chain that we will overwrite the initial state of the
Orchard note commitment tree.
2022-04-04 13:05:46 -06:00
Kris Nuttycombe 5b7370c55e Update test to verify rewind behavior. 2022-04-04 13:05:42 -06:00
Kris Nuttycombe 344aef435d Improve error output from OrchardWallet::get_spend_info 2022-04-04 13:05:42 -06:00
Kris Nuttycombe 6fbcba641d Fix a bug in initialization of the Orchard wallet after NU5 activation.
When initializing a new Orchard wallet after NU5 activation, it is
not valid to start from the empty note commitment tree; instead,
the note commitment tree needs to be initialized from the state of
the global Orchard Merkle frontier.

In addition, this change necessitates a change to how rewinds work,
such that in a rollback scenario with a newly initialized wallet
that does not have sufficient checkpoints to fully satisfy a requested
rewind, the rewind is allowed to proceed so long as it does not
invalidate any persisted witness data.
2022-04-04 13:05:42 -06:00
Kris Nuttycombe 4afc6a37c9 Refactor ChainTip to take a struct of Merkle trees instead of a pair.
This makes addition of the Orchard Merkle frontier easier in the future.
2022-04-04 12:04:34 -06:00
Kris Nuttycombe d9de6b64fc Adds a test demonstrating an Orchard wallet initialization bug.
If a new Orchard wallet is created after the first Orchard spend
post NU5 activation, it causes an assertion failure because the root
of the wallet's empty note commitment tree does not match the global
note commitment tree root.
2022-04-04 12:04:32 -06:00
Jack Grigg 098a70ed89 wallet: Rename `CWallet::GetBestBlock` to `GetPersistedBestBlock`
This more accurately reflects its meaning, as it corresponds to the most
recently persisted best chain (i.e. the chain tip that the wallet will
return to on restart), rather than the chain tip to which the in-memory
wallet state has been synced.
2022-04-04 17:43:17 +00:00
Jack Grigg bb072f06c9 AcceptToMemoryPool: Re-add missing code comment
The comment on `view.SetBackend(dummy)` was removed when we backported
upstream locking PRs in zcash/zcash#5017. The upstream commit in
question removed a locking scope but did not remove the reference to
that scope in the comment. Our backport removed the outdated comment,
but should have modified it instead, because otherwise the existence of
`view.SetBackend(dummy)` is very confusing (as it disconnects the cache
from `pcoinsTip`, on the assumption that everything we need from it has
been cached via calls to `CCoinsViewCache::HaveCoins` and
`CCoinsViewCache::HaveShieldedRequirements`).
2022-04-04 16:57:55 +00:00
Jack Grigg c99e7752e4 mempool: Remove duplicated anchor and nullifier assertions
Now that we call `Consensus::CheckTxShieldedInputs` on all transactions
in `CTxMemPool::check`, we don't need to separately check the nullifiers
and anchors directly. That change also fixed a bug where we weren't
previously making the same assertions about Orchard Actions.
2022-04-04 16:57:55 +00:00
Jack Grigg f1cda64602 Apply `HaveShieldedRequirements` to coinbase transactions
Both transparent and shielded inputs have contextual checks that need to
be enforced in the consensus rules. For shielded inputs, these are that
the anchors in transactions correspond to real commitment tree states
(to ensure that the spent notes existed), and that their nullifiers are
not being double-spent.

When Sprout was first added to the codebase, we added input checks in
the same places that transparent inputs were checked; namely anywhere
`CCoinsViewCache::HaveInputs` is called. These all happened to be gated
on `!tx.IsCoinBase()`, which was fine because we did not allow Sprout
JoinSplits in coinbase transactions (enforced with a non-contextual
check).

When we added Sapling we also allowed coinbase outputs to Sapling
addresses (shielded coinbase). We updated `HaveShieldedRequirements` to
check Sapling anchors and nullifiers, but didn't change the consensus
code to call it on coinbase. This was fine because Sapling Spends and
Outputs are separate, and we did not allow Sapling Spends in coinbase
transactions (meaning that there were no anchors or nullifiers to
enforce the input rules on).

Orchard falls into an interesting middle-ground:
- We allowed coinbase outputs to Orchard addresses, to enable Sapling
  shielded coinbase users to migrate to Orchard.
- Orchard uses Actions, which are a hybrid of Sprout JoinSplits and
  Sapling Spends/Outputs. That is, an Orchard Action comprises a single
  spend and a single output.

To maintain the "no shielded spends in coinbase" rule, we added an
`enableSpends` flag to the Orchard circuit. We force it to be set to
`false` for coinbase, ensuring that all Orchard spends in a coinbase use
dummy (zero-valued) notes. However, this is insufficient: the coinbase
transaction will still contain an Orchard anchor and nullifiers, and
these need to be correctly constrained.

In particular, not constraining the Orchard nullifiers in a coinbase
transaction enables a Faerie Gold attack. We explicitly require that
Orchard nullifiers are unique, so that there is a unique input to the
nullifier derivation. Without the coinbase check, the following attack
is possible:
- An adversary creates an Orchard Action sending some amount of ZEC to a
  victim address, with a dummy spent note. The entire transaction can be
  fully-shielded by placing the real spent note in a separate Action.
- The adversary uses the exact same dummy note in a coinbase
  transaction, creating the exact same output note (same victim address
  and amount).
- The victim now has two notes with the same ZEC amount, but can only
  spend one of them because they have the same nullifier.

This commit fixes the consensus bug by calling `HaveShieldedRequirements`
outside of `!tx.IsCoinBase()` gates. To simplify its usage, there is now
a `Consensus::CheckTxShieldedInputs` function that handles the logging
and validation state updates. We also move shielded input checks from
`ContextualCheckInputs` to `ContextualCheckShieldedInputs`; these now
mirror each other in that they check contextual rules on transparent and
shielded inputs respectively, followed by checking signatures.
2022-04-04 16:57:55 +00:00
ebfull a4cc6ad3d0
Merge pull request #5788 from daira/orchard-nullifier-check
Orchard nullifier and anchor consistency checks
2022-04-04 08:20:17 -06:00
Steven c8e0503c69
Merge pull request #5797 from nuttycom/feature/z_listunspent_account
Add account ID to z_listunspent results.
2022-04-04 07:17:53 -07:00
Jack Grigg 3a1261efda wallet: Initialise ThreadNotifyWallets with wallet's best block
The previous code assumed that the last chain tip notified to the wallet
was equal to the node's chain tip at startup. However, this assumption
fails if the node shuts down uncleanly, or if a wallet file is moved
from one node to another.

We now try to start notifying from the wallet's best block, and if the
node doesn't have that block we fall back to the node's chain tip like
before.

Closes zcash/zcash#5805.
2022-04-02 00:38:26 +00:00
Daira Hopwood 6c23b162ba
Merge pull request #5808 from str4d/5806-treat-mnemonichdchain-corruption-as-fatal
wallet: Treat `mnemonichdchain` records as key material
2022-04-02 01:02:08 +01:00
Jack Grigg 17d576fef4 wallet: Treat `mnemonichdchain` records as key material
This is a temporary change to ensure that if this record is unreadable,
we immediately shut down the node and don't make any further changes
that could impair our ability to recover from this state later.

Part of zcash/zcash#5806.
2022-04-01 22:16:40 +00:00
Daira Hopwood 0130426dea AcceptToMemoryPool: Remove initial nullifier checks for Sprout and Sapling
(within the mempool only), that are redundant with checks in
HaveShieldedRequirements. The latter take into account nullifiers in the
chain (using CCoinsViewMemPool::GetNullifier) and include Orchard.

There is no meaningful DoS-protection motivation for the checks being
removed here, nor do they simplify reasoning about the code (if anything
the redundancy makes it more confusing).

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
2022-04-01 23:16:11 +01:00
Daira Hopwood 8e15446c17
Merge pull request #5802 from nuttycom/bug/z_listaddress_internal
Do not display internal addresses in z_listaddresses.
2022-04-01 22:47:09 +01:00
Kris Nuttycombe 5e4eb72a9b Do not display internal addresses in z_listaddresses.
Fixes #5800
2022-04-01 12:53:59 -06:00
Kris Nuttycombe 0a0ac9989e Add a test demonstrating that z_listaddresses reveals internal addrs. 2022-04-01 12:46:55 -06:00
Daira Hopwood f9a703ed51 This check done for Sprout and Sapling (which is separate from consensus nullifier checks)
was not being done for Orchard.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
2022-04-01 19:42:30 +01:00
Kris Nuttycombe 0a5dbc10d4 Add account ID to z_listunspent results.
Fixes #5795
2022-04-01 10:02:13 -06:00
Kris Nuttycombe f7b11f6da1
Merge pull request #5775 from nuttycom/feature/orchard_list_unspent
Add Orchard support to z_listunspent.
2022-04-01 07:39:25 -06:00
str4d 445e853a60
Merge pull request #5790 from nuttycom/nu5-consensus_merge-master
Merge `master` to the nu5-consensus branch.
2022-04-01 12:08:31 +01:00
Jack Grigg e5756cc198 qa: Add test for Orchard support in `z_listunspent` 2022-04-01 02:44:56 +00:00
Kris Nuttycombe 866278f79a Merge remote-tracking branch 'upstream/master' into nu5-consensus_merge-master 2022-03-31 20:29:28 -06:00
Kris Nuttycombe 4afec83947
Merge pull request #5782 from nuttycom/cleanup/incrementalmerkletree_positions
Update to the latest incrementalmerkletree.
2022-03-31 12:57:00 -06:00
str4d bd2bc8834f
Merge pull request #5779 from str4d/persist-orchard-note-positions
wallet: Persist Orchard note positions with the witness tree
2022-03-31 19:33:08 +01:00
Kris Nuttycombe a852eb223b Update incrementalmerkletree version to fix GC bug & use updated API.
This also modifies the serialized form of the wallet's incremental
merkle tree. This will require a complete reindex for testnet wallets.
2022-03-31 10:52:48 -06:00
Kris Nuttycombe 824824d6d2 Add Orchard support to z_listunspent.
Also, ensure that Sapling internal addresses are not displayed
in z_listunspent outputs.

Fixes #5683
2022-03-31 10:41:35 -06:00
str4d fbd2912885 Apply suggestions from code review
Co-authored-by: Daira Hopwood <daira@jacaranda.org>
Co-authored-by: Kris Nuttycombe <kris.nuttycombe@gmail.com>
2022-03-31 16:07:05 +00:00
Jack Grigg b121fd94d9 wallet: Persist Orchard tx height alongside note positions
Previously we were reconstructing the height on wallet load by looking
up the `blockHash` field of `CMerkleTx` to find the transaction's height
in the main chain. However, this field is updated whenever `AddToWallet`
is called, while the transaction's height and note positions need to be
kept in sync with `SetBestChain`, which is only called once every 10
minutes. In the case that a reorg occurs between `SetBestChain` and the
node shutting down, the resulting height on wallet load would be
inconsistent. As with note positions, any inconsistency should be
resolved by the post-load wallet rescan, which rewinds the Orchard
witness tree and unsets any position information.

Part of zcash/zcash#5784.
2022-03-31 15:45:56 +00:00
Jack Grigg 2d6cb93125 wallet: Add version information to Orchard commitment tree data
We add both C++ client version information (enabling version-specific
changes if necessary, matching the rest of the C++ wallet), and record
version information (enabling local serialization format changes).

Part of zcash/zcash#5784.
2022-03-31 15:08:09 +00:00
Jack Grigg d651f22e86 wallet: Persist Orchard note positions with the witness tree
We rewrite the entire witness tree each time we update the wallet's best
chain state, and we need the note positions to always be consistent with
the tree state (otherwise mined notes become unspendable after the node
restarts).
2022-03-30 23:23:27 +00:00
Jack Grigg ac3229201f wallet: Move Orchard note position data into a separate map 2022-03-30 23:23:27 +00:00
Jack Grigg 0255964559 qa: Add RPC test testing Orchard note position persistence
The test fails during the final `z_sendmany`, because it is selecting a
note that was detected before restarting the node. Because we force the
wallet to call `SetBestChain` on every block, the wallet doesn't need to
rescan on restart, and thus doesn't repopulate the `position` field of
the in-memory note.

This issue went unnoticed in existing tests that exercise node restarts,
because the RPC tests are fast enough that they never pass the 10-minute
timeout for writing the wallet state. This commit adds a regtest-only
config option that disables the lazy writing.
2022-03-30 23:23:27 +00:00
Kris Nuttycombe a394770ab8
Merge pull request #5772 from therealyingtong/scope-api
Update FFI to use scoped APIs for viewing keys and addresses
2022-03-30 13:04:08 -06:00
Kris Nuttycombe 53cc7ecceb Apply suggestions from code review
Co-authored-by: str4d <thestr4d@gmail.com>
2022-03-30 10:10:28 -06:00
therealyingtong bc33ba5a9f Update FFI to use scoped APIs for viewing keys and addresses 2022-03-30 08:30:27 -06:00
Kris Nuttycombe 72b27fb906 Add independent wallet persistence tests.
Co-authored by: @therealyingtong
2022-03-30 08:27:41 -06:00
Daira Hopwood 560db173bd
Merge pull request #5769 from daira/fix-gtest-define
Fix an incorrect preprocessor symbol
2022-03-29 22:15:52 +01:00
Daira Hopwood a92e249e4b Fix an incorrect preprocessor symbol.
Also repair the lint-includes-guards.sh script that was checking for the incorrect symbol.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
2022-03-29 20:18:16 +01:00
sasha 9befdb2c45
Merge pull request #5767 from daira/postpone-deps
Postpone native_clang and libcxx 14.0.0; admin merge as requested by @nuttycom
2022-03-29 11:12:02 -07:00
Kris Nuttycombe 72e7d2b83f
Merge pull request #5765 from nuttycom/doc/rpc_release_notes
Update release notes to include all RPC changes since 4.6.0
2022-03-29 11:25:55 -06:00