Fix Sapling witness desync and parallelize witness cache rebuild
Wallets upgraded across the 1.0.1->1.0.2 network transition could end up with note witnesses stuck at a stale height, causing z_sendmany / z_mergetoaddress to fail to build a valid spend. Root cause was a trio of issues that let a desynced witnessHeight perpetuate instead of self-healing: - DecrementNoteWitnesses left witnessRootValidated and the witness deque in an asymmetric state on the size<=1 path. - VerifyAndSetInitialWitness blindly trusted witnessHeight instead of validating the cached root against the chain, so a bad height survived. - UpdatedNoteData copied witnessHeight even when no witnesses were present. - witnessRootValidated was uninitialized and never serialized, so a garbage true value could short-circuit the self-heal. Fixes: - Default witnessRootValidated to false (in-memory only; never serialized). - VerifyAndSetInitialWitness now validates the cached witness root against the block's hashFinalSaplingRoot and reseeds on mismatch. - Symmetric reset of witness state in DecrementNoteWitnesses. - Guard the witnessHeight copy in UpdatedNoteData behind a non-empty witnesses check. - Defensive majority-root guard in GetSaplingNoteWitnesses. Also rewrites BuildWitnessCache to rebuild the witness cache in parallel (per-block commitment extraction + worker pool), cutting a full repair from ~28 min to ~2 min. Tunable via -witnessbuildthreads and -witnessfastrebuild; output verified byte-identical to the serial path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -311,7 +311,9 @@ public:
|
||||
boost::optional<uint256> nullifier;
|
||||
|
||||
//In Memory Only
|
||||
bool witnessRootValidated;
|
||||
// Never serialized (see SerializationOp): must default false so a garbage value can't
|
||||
// read true and short-circuit the witness self-heal in VerifyAndSetInitialWitness.
|
||||
bool witnessRootValidated = false;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user