Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ be considered breaking changes.
standalone imported transparent keys (e.g. from a `zcashd` migration).
- No longer crashes in regtest mode when a Sapling or NU5 activation height is
not defined.
- The wallet sync task no longer exits with a "Missing Sapling/Orchard tree
state" error when a shielded pool is active but its note commitment tree is
still empty (e.g. on regtest, where NU5 is active from height 1). An absent
tree state is now correctly treated as an empty tree.
- Zallet now refuses to open wallet databases from incompatible earlier alpha
releases instead of attempting to migrate them.
- `z_sendmany` no longer drop standalone transparent signing keys when the same
Expand Down
45 changes: 17 additions & 28 deletions zallet/src/components/sync/steps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,36 +309,25 @@ pub(super) async fn fetch_chain_state(
.await?
.into_parts();

let final_sapling_tree = if params.is_nu_active(NetworkUpgrade::Sapling, height.0.into()) {
read_frontier_v0(
sapling
.ok_or_else(|| IndexerError::InvalidData {
message: "Missing Sapling tree state".into(),
})?
.as_slice(),
)
.map_err(|e| IndexerError::InvalidData {
message: format!("{e}"),
})?
} else {
// Sapling is not yet active; the Sapling tree is empty.
Frontier::empty()
// An absent tree state (`None`) means the pool's note commitment tree is empty, not an
// error (fetch errors surface via `?` above). Treat "active but empty" like "not yet
// active": an empty frontier.
let final_sapling_tree = match sapling {
Some(sapling) if params.is_nu_active(NetworkUpgrade::Sapling, height.0.into()) => {
read_frontier_v0(sapling.as_slice()).map_err(|e| IndexerError::InvalidData {
message: format!("{e}"),
})?
}
_ => Frontier::empty(),
};

let final_orchard_tree = if params.is_nu_active(NetworkUpgrade::Nu5, height.0.into()) {
read_frontier_v0(
orchard
.ok_or_else(|| IndexerError::InvalidData {
message: "Missing Orchard tree state".into(),
})?
.as_slice(),
)
.map_err(|e| IndexerError::InvalidData {
message: format!("{e}"),
})?
} else {
// NU5 is not yet active; the Orchard tree is empty.
Frontier::empty()
let final_orchard_tree = match orchard {
Some(orchard) if params.is_nu_active(NetworkUpgrade::Nu5, height.0.into()) => {
read_frontier_v0(orchard.as_slice()).map_err(|e| IndexerError::InvalidData {
message: format!("{e}"),
})?
}
_ => Frontier::empty(),
};

Ok(ChainState::new(
Expand Down
Loading