Merge pull request #6387 from str4d/6004-orchard-reindex
Reset Orchard wallet state in `CWallet::ClearNoteWitnessCache`
This commit is contained in:
commit
26dbee2c5f
|
@ -79,6 +79,7 @@ BASE_SCRIPTS= [
|
|||
'wallet_orchard_change.py',
|
||||
'wallet_orchard_init.py',
|
||||
'wallet_orchard_persistence.py',
|
||||
'wallet_orchard_reindex.py',
|
||||
'wallet_nullifiers.py',
|
||||
'wallet_sapling.py',
|
||||
'wallet_sendmany_any_taddr.py',
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2023 The Zcash developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.mininode import COIN
|
||||
from test_framework.util import (
|
||||
NU5_BRANCH_ID,
|
||||
assert_equal,
|
||||
get_coinbase_address,
|
||||
nuparams,
|
||||
start_node,
|
||||
start_nodes,
|
||||
stop_nodes,
|
||||
wait_and_assert_operationid_status,
|
||||
wait_bitcoinds,
|
||||
)
|
||||
|
||||
from decimal import Decimal
|
||||
import time
|
||||
|
||||
BASE_ARGS = [
|
||||
nuparams(NU5_BRANCH_ID, 210),
|
||||
'-regtestwalletsetbestchaineveryblock',
|
||||
]
|
||||
|
||||
# Test wallet behaviour when reindexing with Orchard state.
|
||||
class WalletOrchardReindexTest(BitcoinTestFramework):
|
||||
def setup_nodes(self):
|
||||
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[BASE_ARGS] * self.num_nodes)
|
||||
|
||||
def run_test(self):
|
||||
# Check height is before NU5.
|
||||
assert_equal(self.nodes[0].getblockcount(), 200)
|
||||
|
||||
# Mine blocks to activate NU5.
|
||||
self.sync_all()
|
||||
self.nodes[2].generate(10)
|
||||
self.sync_all()
|
||||
|
||||
# Get a new Orchard-only unified address
|
||||
acct = self.nodes[0].z_getnewaccount()['account']
|
||||
addrRes = self.nodes[0].z_getaddressforaccount(acct, ['orchard'])
|
||||
assert_equal(acct, addrRes['account'])
|
||||
assert_equal(addrRes['receiver_types'], ['orchard'])
|
||||
ua = addrRes['address']
|
||||
|
||||
# Create a transaction with an Orchard output to advance the Orchard
|
||||
# commitment tree.
|
||||
recipients = [{'address': ua, 'amount': Decimal('10')}]
|
||||
myopid = self.nodes[0].z_sendmany(
|
||||
get_coinbase_address(self.nodes[0]),
|
||||
recipients, 1, 0, 'AllowRevealedSenders')
|
||||
wait_and_assert_operationid_status(self.nodes[0], myopid)
|
||||
|
||||
# Mine the transaction.
|
||||
self.sync_all()
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# Confirm that we see the Orchard note in the wallet.
|
||||
assert_equal(
|
||||
{'pools': {'orchard': {'valueZat': Decimal('10') * COIN}}, 'minimum_confirmations': 1},
|
||||
self.nodes[0].z_getbalanceforaccount(acct))
|
||||
|
||||
# Mine blocks to ensure that the wallet's tip is far enough beyond NU5
|
||||
# activation that it won't rescan blocks before then on startup.
|
||||
self.sync_all()
|
||||
self.nodes[2].generate(9)
|
||||
self.sync_all()
|
||||
|
||||
# Restart the node with -reindex.
|
||||
blockcount = self.nodes[0].getblockcount()
|
||||
stop_nodes(self.nodes)
|
||||
wait_bitcoinds()
|
||||
self.num_nodes = 1
|
||||
self.nodes = [start_node(0, self.options.tmpdir, BASE_ARGS + ['-reindex'])]
|
||||
|
||||
# Confirm that the reindexed node does not crash.
|
||||
# Before https://github.com/zcash/zcash/issues/6004 was fixed, the node
|
||||
# would crash here inside `IncrementNoteWitnesses`, unless the node was
|
||||
# restarted during the `ActivateBestChain` phase of reindexing (which we
|
||||
# don't do in this test).
|
||||
while self.nodes[0].getblockcount() < blockcount:
|
||||
time.sleep(0.1)
|
||||
assert_equal(self.nodes[0].getblockcount(), blockcount)
|
||||
|
||||
# Confirm that we still see the Orchard note in the wallet.
|
||||
assert_equal(
|
||||
{'pools': {'orchard': {'valueZat': Decimal('10') * COIN}}, 'minimum_confirmations': 1},
|
||||
self.nodes[0].z_getbalanceforaccount(acct))
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletOrchardReindexTest().main()
|
|
@ -39,7 +39,7 @@ void orchard_wallet_free(OrchardWalletPtr* wallet);
|
|||
* in place with the expectation that they will be overwritten and/or updated in
|
||||
* the rescan process.
|
||||
*/
|
||||
bool orchard_wallet_reset(OrchardWalletPtr* wallet);
|
||||
void orchard_wallet_reset(OrchardWalletPtr* wallet);
|
||||
|
||||
/**
|
||||
* Checkpoint the note commitment tree. This returns `false` and leaves the note
|
||||
|
|
|
@ -215,8 +215,8 @@ public:
|
|||
* in place with the expectation that they will be overwritten and/or updated in the
|
||||
* rescan process.
|
||||
*/
|
||||
bool Reset() {
|
||||
return orchard_wallet_reset(inner.get());
|
||||
void Reset() {
|
||||
orchard_wallet_reset(inner.get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2550,6 +2550,11 @@ void CWallet::ClearNoteWitnessCache()
|
|||
}
|
||||
}
|
||||
nWitnessCacheSize = 0;
|
||||
|
||||
// This resets spentness information in addition to the Orchard note witness
|
||||
// caches, which is fine because it will be recovered during the reindex or
|
||||
// rescan that called `ClearNoteWitnessCache()`.
|
||||
orchardWallet.Reset();
|
||||
}
|
||||
|
||||
template<typename NoteDataMap>
|
||||
|
|
Loading…
Reference in New Issue