bitcoinz icon indicating copy to clipboard operation
bitcoinz copied to clipboard

Assertion `*rt == witnesses[i]->root()' failed (recheck of the sapling notes witness height)

Open Sil3ntVip3r opened this issue 11 months ago • 1 comments

It seams the wallet gets this error randomly when using Z addresses. The error below is the error from the node. Reference attached image for more info.

This could be the solution (recheck of the sapling notes witness height): https://github.com/zcash/zcash/blob/c791f0a770c832c8f8dd20c62091781a276858e9/src/wallet/wallet.cpp#L3923

Feb 27 15:20:50 bitcoinzd[2062777]: bitcoinzd: wallet/wallet.cpp:1971: void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint>, std::vector<boost::optional<libzcash::IncrementalWitness<32, libzcash::PedersenHash> > >&, uint256&): Assertion `*rt == witnesses[i]->root()' failed

image

Sil3ntVip3r avatar Mar 02 '24 23:03 Sil3ntVip3r

There is currently no solution to this problem. Only a workaroud, restart the node with rescan option : bitcoinzd -rescan.

This is annoying, especially if a lot of transactions were carried out with this wallet.

MarcelusCH avatar Apr 30 '24 16:04 MarcelusCH

To get root cause of this issue a patched node is needed:

diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 1b9e6124f..68a0db8bd 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1981,11 +1981,17 @@ void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes,
     LOCK(cs_wallet);
     witnesses.resize(notes.size());
     boost::optional<uint256> rt;
+    boost::optional<int> witnessHeight;
     int i = 0;
     for (SaplingOutPoint note : notes) {
         if (mapWallet.count(note.hash) &&
                 mapWallet[note.hash].mapSaplingNoteData.count(note) &&
                 mapWallet[note.hash].mapSaplingNoteData[note].witnesses.size() > 0) {
+            if (!witnessHeight) {
+                witnessHeight = mapWallet[note.hash].mapSaplingNoteData[note].witnessHeight;
+            } else {
+                assert(*witnessHeight == mapWallet[note.hash].mapSaplingNoteData[note].witnessHeight);
+            }
             witnesses[i] = mapWallet[note.hash].mapSaplingNoteData[note].witnesses.front();
             if (!rt) {
                 rt = witnesses[i]->root();

This code must be added and compiled only on the node where the issue is happening and removed after got all information needed to solve it.

MarkLTZ avatar Jul 15 '24 15:07 MarkLTZ

#99 should fix this issue, but it require on affected wallets a firstrun using options -zapwallettxes=2 -rescan.

MarkLTZ avatar Jul 29 '24 17:07 MarkLTZ