Zebra raised its local rollback window to 1000 blocks in #10650 (MAX_BLOCK_REORG_HEIGHT, zebra-state v13.0.0). The zcashd fork behind the sidecar's zcashd compat mode is still on upstream's 99 (MAX_REORG_LENGTH = COINBASE_MATURITY - 1, src/main.h), so a reorg 100-1000 blocks deep shuts the sidecar node down while Zebra keeps going. Filing here because that fork has issues disabled.
Verified against valargroup/zcashd: every branch still has MAX_REORG_LENGTH = COINBASE_MATURITY - 1 and MAX_CHECKPOINTS = 100.
These have to land together — raising only the node threshold converts a clean shutdown into an assertion crash:
-
src/main.h: MAX_REORG_LENGTH to 1000, decoupled from COINBASE_MATURITY (consensus-critical, must not change).
-
src/wallet/wallet.h: WITNESS_CACHE_SIZE = MAX_REORG_LENGTH + 1 follows automatically to 1001. It has to track the reorg limit because CWallet::DecrementNoteWitnesses asserts nWitnessCacheSize > 0 once a note's witness deque runs dry.
-
src/rust/src/wallet.rs: MAX_CHECKPOINTS 100 -> 1001. Wallet::rewind returns RewindError::InsufficientCheckpoints past that and the C++ caller wraps the FFI call in assert().
-
src/rust/src/incremental_merkle_tree.rs: read_tree feeds the serialized max_checkpoints straight back into BridgeTree::from_parts, so existing wallet.dat files would stay at 100 forever. Pass MAX_CHECKPOINTS in instead, still consuming the serialized bytes so the format is unchanged.
-
src/main.h: MIN_BLOCKS_TO_KEEP 288 -> MAX_REORG_LENGTH + 1, or a pruned node cannot physically reorg 1000 blocks. Pin DEFAULT_CHECKBLOCKS at 288 so startup verification does not get 3.5x slower.
-
qa/rpc-tests/reorg_limit.py and qa/rpc-tests/sapling_rewind_check.py hardcode the old depths and the "roll back N blocks" messages.
Cost: witness-cache memory and wallet.dat grow roughly 10x for wallets holding shielded notes, since one witness per block per tracked note is retained. The growth is gradual — nWitnessCacheSize increases by 1 per connected block, so an upgraded wallet takes ~900 blocks to reach the new ceiling.
Zebra raised its local rollback window to 1000 blocks in #10650 (
MAX_BLOCK_REORG_HEIGHT, zebra-state v13.0.0). The zcashd fork behind the sidecar's zcashd compat mode is still on upstream's 99 (MAX_REORG_LENGTH = COINBASE_MATURITY - 1,src/main.h), so a reorg 100-1000 blocks deep shuts the sidecar node down while Zebra keeps going. Filing here because that fork has issues disabled.Verified against
valargroup/zcashd: every branch still hasMAX_REORG_LENGTH = COINBASE_MATURITY - 1andMAX_CHECKPOINTS = 100.These have to land together — raising only the node threshold converts a clean shutdown into an assertion crash:
src/main.h:MAX_REORG_LENGTHto 1000, decoupled fromCOINBASE_MATURITY(consensus-critical, must not change).src/wallet/wallet.h:WITNESS_CACHE_SIZE = MAX_REORG_LENGTH + 1follows automatically to 1001. It has to track the reorg limit becauseCWallet::DecrementNoteWitnessesassertsnWitnessCacheSize > 0once a note's witness deque runs dry.src/rust/src/wallet.rs:MAX_CHECKPOINTS100 -> 1001.Wallet::rewindreturnsRewindError::InsufficientCheckpointspast that and the C++ caller wraps the FFI call inassert().src/rust/src/incremental_merkle_tree.rs:read_treefeeds the serializedmax_checkpointsstraight back intoBridgeTree::from_parts, so existingwallet.datfiles would stay at 100 forever. PassMAX_CHECKPOINTSin instead, still consuming the serialized bytes so the format is unchanged.src/main.h:MIN_BLOCKS_TO_KEEP288 ->MAX_REORG_LENGTH + 1, or a pruned node cannot physically reorg 1000 blocks. PinDEFAULT_CHECKBLOCKSat 288 so startup verification does not get 3.5x slower.qa/rpc-tests/reorg_limit.pyandqa/rpc-tests/sapling_rewind_check.pyhardcode the old depths and the "roll back N blocks" messages.Cost: witness-cache memory and
wallet.datgrow roughly 10x for wallets holding shielded notes, since one witness per block per tracked note is retained. The growth is gradual —nWitnessCacheSizeincreases by 1 per connected block, so an upgraded wallet takes ~900 blocks to reach the new ceiling.