Releases: penumbrafi/penumbra
Release list
pd 2.0.11
pd 2.0.11 is pd 2.0.10 with a fixed pd migrate prune. Same consensus code,
APP_VERSION still 11, same restart genesis: a drop-in for a running 2.0.9 or
2.0.10 node, with no migration, no upgrade height and no coordination.
git diff v2.0.10..v2.0.11 -- crates/core is empty. Do not re-run
migrate-restart from pre-restart state to join the chain — the commit_in_place
fix below changes what it produces; join from a post-restart snapshot.
2.0.10's pd migrate prune must not be run on post-restart state. It
produced a database with the correct root hash that pd start could not use.
What changed
- Pruning detects any key where the merkle leaf and the value store disagree —
the restart migration left three of them onpenumbra-1— and preserves the
value a node reads, leaving the tree and the root hash untouched. Every such
key is logged. - Every column family the pruner does not rebuild is fingerprinted in both
databases, and the pruned store reopened at the same version and root hash,
before any directory is renamed. A mismatch aborts, swapping nothing. cnidarium0.83.2 (tagv0.83.2) carries the other half:commit_in_place
now refreshes the snapshot cache, which is what left the divergence behind.
Pruning
Stop both cometbft and pd, then run as the pd user with a raised limit:
sudo -u penumbra bash -c 'ulimit -n 1048576 && pd migrate --home <pd_home> prune'.
Budget 1–4 hours and ~5 GB RAM for a full store; start pd first, then cometbft.
<pd_home>/rocksdb_old keeps the unpruned copy — delete it after a day of
following the chain. One validator at a time; archive, RPC, indexer and
snapshot-provider nodes do not prune, and never with an older version.
Full procedure: docs/pruning.md.
Assets
pd, pcli, pclientd, pindexer, pmonitor and elcuity for linux x86_64
and aarch64; reproduce with cargo build --release --locked.
Maintained by the Penumbra community — https://github.com/penumbrafi/penumbra.
Built by GitHub Actions from v2.0.11. Verify a download against SHA256SUMS:
sha256sum -c --ignore-missing SHA256SUMSFull source diff: v2.0.9...v2.0.11
pd 2.0.10
Superseded by v2.0.11; do not use this version's pd migrate prune on post-restart state.
pd 2.0.10 is pd 2.0.9 plus one new command, pd migrate prune. Same consensus
code, APP_VERSION still 11, same migrate-restart and same restart genesis.
Drop-in: 2.0.9 and 2.0.10 nodes run side by side, and adopting it needs no
migration, no upgrade height and no coordination. The only diff outside
crates/bin/pd is a comment — check with
git diff v2.0.9..v2.0.10 -- crates/core.
pd migrate prune
Offline pruning of the state store: collapses the historical versions of the
Jellyfish Merkle Tree to the latest one, verifying every key against the
unchanged root hash with range proofs as it rebuilds. On mainnet this takes the
pd database from roughly 350 GB to roughly 30 GB.
It is not an upgrade migration: no network halt, no prune height, and nodes
may prune at different versions. The root hash is unchanged, so pruned and
unpruned nodes are indistinguishable to consensus. The only cost is your own
node being offline while it runs — an hour on a quiet NVMe host, several on a
busy one.
systemctl stop cometbft penumbra
sudo -u penumbra bash -c 'ulimit -n 1048576 && pd migrate --home <pd_home> prune'
systemctl start penumbra && systemctl start cometbft- Stop both
pdand CometBFT. CometBFT crash-loops without its ABCI peer. - One validator at a time, never more than a third of voting power offline
at once, and not within 24 hours of the restart. - Archive, RPC and indexer nodes do not prune. A pruned node cannot answer
queries about state before its prune point, which breaks relayers and
explorers. The network needs unpruned nodes to exist.
The unpruned database is kept at <pd_home>/rocksdb_old; delete it once the
node has followed the chain for a day. Full procedure, failure modes and the
open-file-limit trap: docs/pruning.md.
Assets
Linux x86_64 and aarch64, built by GitHub Actions from this tag; reproduce with
cargo build --release --locked. Verify downloads against SHA256SUMS.
cnidarium is pinned to penumbrafi/cnidarium 0.83.1 (e37da88) for the
verified pruning API; no existing storage or proof code path is modified.
Maintained by the Penumbra community —
https://github.com/penumbrafi/penumbra.
Built by GitHub Actions from v2.0.10. Verify a download against SHA256SUMS:
sha256sum -c --ignore-missing SHA256SUMSFull source diff: v2.0.9...v2.0.10
penumbra-1 recovery — pd 2.0.9
penumbra-1 coordinated restart — pd 2.0.9 (migrate-restart)
penumbra-1 halted at height 12598600. This continues the same
chain-id — all balances and delegations preserved — by disabling the
two departed validators (iqlusion, polkachu) and keeping the other 14.
Verify, do not trust. The cross-check is that your own
pd migrate-restart reproduces the exact genesis hash below — not this
binary. Reproduce the binary: cargo build --release --locked -p pd on
this tag. Built on ubuntu-22.04 (glibc 2.35). Every code change versus
stock v2.0.6: v2.0.6...v2.0.9
Restart height is 12598602. Every validator that was online at the
halt already signed height 12598601 on the halted chain, and CometBFT
will not sign those rounds again, so a restart at 12598601 can never
produce a block (reproduced on a copy of the real halt state). The
migration executes an empty application block 12598601 itself and
starts CometBFT at 12598602; your signing state is raised to 12598602
by the migration. There is no CometBFT block 12598601. Earlier builds
(v2.0.8, the 2.0.6 branch builds) must not be used.
- genesis sha256:
c099ccb02a2136d5071fb22b1511eeec1588ad09676e0a0532d072f28b433ed4 - app_hash / post_root:
1db72ab20c0babdb8696f361d5b08d790abd8032ac64d762b138ddc80f0f99f7
What each validator does
The script restart/penumbra-restart.sh walks all of this as confirmed
steps (detects your homes, refuses on mismatch). Manual equivalent:
# 0. Get pd 2.0.9 (this release's binary, or build from source above).
# STOP your old pd AND cometbft. Do NOT start any old-chain node again.
# 1. Snapshot / full copy of node0 (rollback point). Do not touch
# priv_validator_key.json or priv_validator_state.json.
cp -a node0 node0.pre-restart
# 2. Migrate (ulimit -n high; ~30s):
ulimit -n 1048576
pd migrate-restart --home node0/pd --comet-home node0/cometbft \
--remove 3969C0511C6ABE474757FEAB7C1B4004796D7E72 \
--remove 9B2D4391131198750FF28EE73EC953ECFCFD06EF \
--disable
# 3. VERIFY the produced genesis — MUST equal the sha above, or stop:
sha256sum node0/cometbft/config/genesis.json
# 4. Check signing state: must read "height": "12598602", round 0, step 0
cat node0/cometbft/data/priv_validator_state.json
# 5. config.toml: persistent_peers = KEEP validators only, pex = false (first blocks).
# 6. Start pd (this binary), then cometbft, in the go-window.Only hard rule: stop your old node before starting the migrated one
(running both = double-sign = tombstone). If you're late, just do
steps 0–6 whenever and your node will sync to the tip and resume signing —
you don't need to hit the go-window exactly. RPC/full nodes run steps 0–3
to follow the chain.
The first block is 12598602 once more than two thirds of the kept set is
online; round timeouts before that are expected. See restart/README.md.