Gravity v1.6.1
Release: v1.6.1
Full Changelog: v1.6.0...v1.6.1
Related pinned components:
- gravity-reth: rev
41c0b709(fix: emit oracle nonce carrier for gravity events, gravity-reth#339) - gravity_chain_core_contracts (window 2026-05-14 ... 2026-05-21): mainnet-deploy scripting + staking audit fixes — 12 commits, summarised below
Highlights
- Oracle bridge fixed for repeated in-epoch updates. A long-standing
No JWK entries to convert oracle noncefailure mode that bricked oracle pipelines after the first round in an epoch is fixed in gravity-reth#339, verified by two new e2e cases (bridge_multi_round,bridge_cross_epoch) that reproduce the failure deterministically against the v1.6.0 greth pin. - Mempool silent-blackhole recovery.
TxnCacheis rewritten to per-entry TTL + bucket-sharded snapshot + four-state filter; a tx whose first dispatch landed on a stuck Primary slot is now auto-routed via the Failover slot one TTL (default 5 s) later. Adds a deterministic e2e regression (pfn_chainPhase 3, two back-to-back blackhole halves) that asserts the slot-flip path. - Build-mode foot-gun removed. v1.6.0's optional
gcp-secret-managercargo feature is dropped; the dep is now always built in. Restores a single-step CI release build and prevents the v1.6.0-style "VFN auto-restart-loops because someone forgot a--featuresflag" regression. - Static-OpenSSL gravity_node binary.
cargo build -p gravity_node(e.g.make gravity_node) no longer produces a binary with dynamiclibssl.so.3/libcrypto.so.3deps — vendored OpenSSL is now declared directly on the gravity_node crate. The CI release artifact is unchanged, but ad-hoc-pbuilds and the docker runtime image are now portable across glibc-based base images.
What's Changed
Bug Fixes
- fix(oracle): bump greth to b0ec42c, verified by new e2e cases by @ByteYue in #725
- The new greth rev carries gravity-reth#339, which fixes a
No JWK entries to convert oracle nonceerror that surfaced as soon as the second oracle update inside an epoch. Round 1 succeeded because JWK state was initialised cleanly at epoch start; round 2's oracle nonce push then failed to find JWK entries to convert, andjwk_observer's 10 s retry loop logged the same error until the test timeout. - Two new e2e cases:
bridge_multi_round— 5 oracle update rounds within a single epoch (epoch_interval = 4h). Asserts everyjwk txn epoch …row shares the same epoch.bridge_cross_epoch— bridge events spanning an epoch transition (epoch_interval = 60s). Asserts the twojwk txn epoch …rows fall in strictly increasing epochs.
- Supporting test infra: new
mock_anvil.set_finalized()helper (preload events, then advancefinalizedblock in phases without restarting Anvil);poll_all_native_mintednow does incremental log scans and short-circuits the moment every expectedNativeMintedevent is observed — multi-round wall-clock dropped from ~25 min to ~1 min. - Regression verified against the v1.6.0 greth pin
364b851: same test code reproduces the bug deterministically (≥18 occurrences of the error, all tagged{"epoch":2}); againstb0ec42c(this PR) the error count is 0.
- The new greth rev carries gravity-reth#339, which fixes a
Feature
- mempool: per-entry TTL + bucket-sharded snapshot + silent-blackhole recovery by @nekomoto911 in #722
- Replaces the global-wipe
TxnCacherebuilt in #699 with per-entry TTL + bucket-sharded snapshot + a four-state filter (Dispatch / WaitForPrimary / SuppressInTtl / SuppressSameSlot). A tx whose first dispatch landed on a stuck Primary slot is now auto-routed via the Failover slot one TTL (default 5 s) later — no gaptos changes, no global re-broadcast, no extra tokio tasks. - Adds Phase 3 to the
pfn_chaine2e: restarts pfn1 withGRAVITY_BLACKHOLE_BROADCAST=1(a debug env knob inbin/gravity_node/src/mempool.rs, ~10 LOC) so pfn1 stays a healthysync_statesmember but silently drops mempool broadcasts; drives 30 s of multi-account load via pfn3 and asserts impl-d's slot-flip catches every in-flight tx within ~1 TTL + commit. - Phase 3 is split into two back-to-back halves (Half A blackholes pfn1, Half B blackholes pfn2). pfn3 is never restarted between halves so
priority.rs'sRandomState-seeded Primary stays fixed; exactly one half hasPrimary == blackhole targetand exercises slot-flip, the other half hits direct delivery latency. Cross-half p95 split is a deterministic assertion:min(p95) ≤ 3.0s,max(p95) ≥ 6.0s,gap ≥ 4.0s. First clean run on the harness: Half A p50 = 6.25 s (≈ TTL 5 s + commit ~1 s — slot-flip exactly at the predicted floor), Half B p50 = 1.18 s.
- Replaces the global-wipe
Build & Release Engineering
- chore: drop gcp-secret-manager optional cargo feature, revert #713 by @keanji-x in #714
- Removes the optional
gcp-secret-managerbuild mode inbin/gravity_node. Now pulls thegaptosdep with the feature always enabled (features = ["gcp-secret-manager"]);reqwest+base64become permanent parts of everygravity_nodebuild. - The optional feature was a footgun: v1.6.0 shipped with
default = []and Staging-Mainnet VFNs auto-restart-looped on the panic inaptos-config/.../network_config.rs:281because their identity source isgcp_secret. PR #713 patched the workflow but the underlying design — an optional build flag that every production deploy must remember to enable — is what should go. .github/workflows/release.ymlcollapses the two-stepgravity_node/gravity_clibuild back to a single pre-#713 step. No upstreamgravity-aptoschange.
- Removes the optional
- build: add gravity_cli build target to Makefile by @Stumble in #715
make gravity_clitarget added;gravity_cliincluded inBIN_DIRSforclean. Note:gravity_clirequiresRUSTFLAGS="--cfg tokio_unstable"to build.
- build(release): vendor openssl in gravity_node so -p builds stay self-contained by @keanji-x in #717
cargo build -p gravity_nodewas producing a binary with dynamiclibssl.so.3+libcrypto.so.3deps. Root cause:openssl-sysis pulled transitively viaaptos-vault-client → native-tls; resolver-v2 only sees thevendoredfeature whengravity_cli(which declares it) is part of the same cargo resolve. Scoping with-p gravity_nodeexcludesgravity_cli, soopenssl-sysfalls back to dynamic system linkage. The CI release workflow builds both binaries in one invocation so the official artifact was fine, butmake gravity_nodeand any one-off-p gravity_nodebuild were brittle (Debian 11 vs 12, libssl1.1 vs libssl3, minor-version skew).- Fix: declare
openssl = { version = "0.10", features = ["vendored"] }directly onbin/gravity_node/Cargo.toml, mirroringbin/gravity_cli/Cargo.toml. After the fix,gravity_nodeonly DT_NEEDEDslibc.so.6 / ld-linux-x86-64.so.2 / libstdc++.so.6 / libgcc_s.so.1 / libm.so.6— present in any glibc-based base image. - Follow-on docker cleanup: drops
libssl-dev / libssl3 / libudev{,1} / libzstd{,1}declarations fromdocker/gravity_node/Dockerfile{,.host-binary}and addsperl(needed by vendored OpenSSL'sConfigure). Dropscurlfrom the runtime image (operator-side only). Switches runtime base fromdebian:12-slimtoubuntu:24.04(longer support window, more glibc headroom 2.39 vs 2.36).
CI
- ci(nightly): drop
environment: defaultfrom e2e-docker-nightly by @nekomoto911 in #721- The
fuzzy_clusternightly doesn't reference any environment-scoped secrets / reviewers / URLs. Theenvironment: defaultdeclaration was only producing a redDeploymentrecord on every failed nightly, filling the Deployments tab. Removed; underlying nightly failure (Failed to find PoolCreated event) is tracked separately.
- The
gravity-reth changes since v1.6.0
The greth pin moved from 364b8516 to 41c0b709 — exactly one commit:
#339 fix: emit oracle nonce carrier for gravity eventsby @alexyueDataRecorded-derivedProviderJWKsnow include a synthetic JWK entry carrying the Gravity oracle nonce as 16 raw big-endian bytes. This keeps the existing gaptosObservedJWKsUpdatedadapter path compatible without requiring sdk or gaptos changes. Resolves theNo JWK entries to convert oracle noncefailure mode that bricked round-2+ oracle updates within an epoch.
The SDK PR #725 commit message references b0ec42c as the bumped rev; the rev that actually pinned at the v1.6.1 tag is 41c0b709 (a later rebase / mirror with identical content on the upstream branch).
Contracts (gravity_chain_core_contracts) — window 2026-05-14 ... 2026-05-21
12 commits, mostly geared toward mainnet-launch readiness. Highlights:
Mainnet deployment scripting
#92 chore: port recent foundry-template fixes#93 feat(mainnet): keystore deploy script + multisig-aware verifier#94 feat(bridge): harden GravityPortal + GBridgeSender per audit#95 feat(mainnet): deploy via CreateX + CREATE3 (deterministic addresses)#96 fix(deploy): hoist mkdir so DRY_RUN can write the artifact#97 docs: add deployment logs
Staking / governance audit fixes
#98 fix(staking): disable StakePool.renounceOwnership#100 fix(staking): release pending consensus key on deactivation#103 fix(staking): honor allowValidatorSetChange freeze during activation (#447)
Genesis-tool hardening
#102 fix(genesis-tool): close 4 medium audit findings (#533–#536)#104 feat(genesis-tool): verify Governance owner + isInitialized post-genesis#106 build: strip CBOR metadata footer for deterministic bytecode— required for byte-deterministic genesis across signing parties.