Skip to content

feat: Ironwood #18

Open
ValarDragon wants to merge 103 commits into
ironwood-mainfrom
add-ironwood-v6-value-pool
Open

feat: Ironwood #18
ValarDragon wants to merge 103 commits into
ironwood-mainfrom
add-ironwood-v6-value-pool

Conversation

@ValarDragon

@ValarDragon ValarDragon commented Jun 7, 2026

Copy link
Copy Markdown

Summary

Adds Ironwood as a NU7 value pool and updates the experimental V6 transaction format to carry transparent, Sapling, Orchard, and Ironwood components.

  • Adds Ironwood to value balance arithmetic, serialization, deserialization, and RPC value pool reporting.
  • Changes V6 transactions to carry transparent inputs and outputs, optional Sapling data, optional Orchard data, and optional Ironwood data.
  • Rejects net new value entering Orchard after NU7.
  • Removes ZIP 233 fields and related template and test plumbing from the NU7 V6 path.
  • Bumps the state database format from 27 to 28 for the value pool byte encoding change.
  • Preserves decoding compatibility for previous 32 byte and 40 byte value pool encodings.
  • Updates the librustzcash patch rev to the current Ironwood integration head.

Validation

  • cargo check -p zebra-chain -p zebra-consensus --locked

@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic czarcas7ic force-pushed the add-ironwood-v6-value-pool branch from 4231155 to 2ce6f53 Compare June 8, 2026 15:06
@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic czarcas7ic force-pushed the add-ironwood-v6-value-pool branch from 9da5ea0 to 52070be Compare June 9, 2026 00:17
@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic

This comment was marked as resolved.

@chatgpt-codex-connector

This comment was marked as resolved.

@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@czarcas7ic

This comment was marked as resolved.

@chatgpt-codex-connector

This comment was marked as resolved.

@czarcas7ic czarcas7ic force-pushed the add-ironwood-v6-value-pool branch 10 times, most recently from 4bee636 to 922bef4 Compare June 18, 2026 21:30
serialize_optional_orchard_shielded_data_with_flags(
orchard_shielded_data,
&mut writer,
orchard::shielded_data::FlagFormat::Nu6_3,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine because the cross-address bit has already been constrained to be 0 in this case.

block,
sapling_root,
orchard_root,
&Default::default(),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Later explore a sentinel value here

Comment thread zebra-chain/src/transaction.rs Outdated
Comment thread zebra-consensus/src/primitives/halo2.rs Outdated
Comment on lines +295 to +296
pub static VERIFIER_V6_ORCHARD_AND_IRONWOOD_NU6_3_ONWARD: Lazy<VerifierService> =
Lazy::new(|| batch_verifier(&VERIFYING_KEY_V6_ORCHARD_AND_IRONWOOD_NU6_3_ONWARD));

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, it is just NU6_3 ONWARD

Comment thread zebra-consensus/src/primitives/halo2.rs Outdated
Comment on lines 325 to 328
// NU6.2 ships the fixed circuit, and every upgrade after it inherits that fixed circuit,
// so all of them verify under the fixed key.
Nu6_2 | Nu6_3 | Nu7 => &VERIFIER_POST_NU6_2,
Nu6_2 | Nu6_3 | Nu7 => &VERIFIER_V5_ORCHARD_NU6_2_ONWARD,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not right, NU6_3 needs to map to the NU6_3 circuit even in V5 transactions.

* feat(network): enable solo-mining on disable_pow networks

A node on a custom proof-of-work-disabled network (e.g. a mainnet
shadow-fork used to test an upgrade against real state) could not mine
with the `generate` RPC, because two checks still assumed a peer-synced
PoW chain:

- the state-layer contextual difficulty-adjustment check rejected a
  locally-mined block whose declared nBits cannot match the value
  derived from the (grafted) chain history; and
- `SyncStatus::is_close_to_tip` returned false without peers, so the
  mempool never activated and `generate`/`getblocktemplate` refused.

Both already had a regtest-only escape (regtest sets disable_pow). Gate
them on `network.disable_pow()` instead, so any PoW-disabled network
behaves like regtest for mining. disable_pow is never true on Mainnet
(hardwired false) or the public Testnet, so real-network behaviour is
unchanged, and the semantic PoW range check (nBits <= PoWLimit) still
runs. Adds a unit test that a disable_pow network is always close-to-tip.

* address review: reject unrepresentable difficulty + single-node disable_pow

C1 (check.rs): under disable_pow, don't fully skip the difficulty-adjustment
check -- still reject a difficulty that isn't representable as work
(to_work() == None). Otherwise a block submitted with a crafted extreme-hard
nBits passes validation and later panics computing cumulative chain work
(to_work().expect in non_finalized_state/chain.rs), letting a peer/RPC caller
crash a disable_pow node.

C2 (config.rs): disable_pow networks now skip remote peer loading like regtest,
so they are genuinely single-node. That is what makes treating them as
always-close-to-tip (for the mempool / generate) correct, instead of reporting
at-tip while a peerful node is still behind.
@ValarDragon ValarDragon reopened this Jun 25, 2026
@v12-auditor

v12-auditor Bot commented Jun 25, 2026

Copy link
Copy Markdown

Warning

Insufficient credits for auto-review. Keep at least $5.00 of available balance to start a run. Please add credits to continue.

ValarDragon and others added 19 commits June 25, 2026 18:18
# Conflicts:
#	zebra-chain/src/orchard/shielded_data.rs
#	zebra-chain/src/transaction/serialize.rs
#	zebra-chain/src/transaction/unmined.rs
#	zebra-consensus/src/error.rs
#	zebra-consensus/src/primitives/halo2.rs
#	zebra-consensus/src/transaction/check.rs
#	zebra-state/src/service/finalized_state/zebra_db/chain.rs
… add-ironwood-v6-value-pool

# Conflicts:
#	zebra-chain/src/orchard/shielded_data.rs
#	zebra-chain/src/orchard/tests/prop.rs
#	zebra-chain/src/transaction/tests/vectors.rs
#	zebra-consensus/src/error.rs
#	zebra-consensus/src/primitives/halo2.rs
#	zebra-consensus/src/primitives/halo2/tests.rs
#	zebra-consensus/src/transaction/check.rs
#	zebra-state/src/service/finalized_state/zebra_db/chain.rs
…rcuit (#260)

`v5_verifier_for` routed every upgrade from NU6.2 onward — `Nu6_2`,
`Nu6_3`, `Nu7`, and `ZFuture` — to the NU6.2 fixed-circuit Orchard key.
That is wrong from NU6.3: the Orchard Action circuit changes again at
NU6.3 to add the `disableCrossAddress` constraint that enforces the
Orchard-pool cross-address restriction, and the fixed key cannot
constrain that public input.

Per ZIP 229 the restriction is enforced for every Orchard-pool Action
mined from NU6.3 onward "regardless of transaction version ... so that
it cannot be bypassed by using a version 5 transaction", and v4/v5/v6
transactions all stay valid at NU6.3. The pinned `orchard` crate agrees:
`BundleProtocol::OrchardPostNu6_3` ("the Orchard pool at NU6.3+") builds
the `PostNu6_3` circuit. So an honest v5 Orchard bundle at NU6.3 proves
under `PostNu6_3` and would be rejected by the fixed key (different
verifying key) — a consensus split — while a fixed-key proof could not
enforce the cross-address restriction at all.

Fix the routing: NU6.3 onward (`Nu6_3`, `Nu7`, `ZFuture`) now uses the
NU6.3 key, so a v5 Orchard bundle at NU6.3 shares the key with v6
Orchard and Ironwood; `Nu6_2` alone keeps the fixed key. Rename the
keys/verifiers from transaction-version names to circuit-era names
(`VERIFIER_NU6_2`, `VERIFIER_NU6_3_ONWARD`, ...) because the circuit is
a function of (pool, era), not transaction version; deprecated
`POST_NU6_2` aliases are retargeted to the fixed key.
# Conflicts:
#	zebra-chain/src/primitives/zcash_primitives.rs
#	zebra-chain/src/transaction/serialize.rs
#	zebra-chain/src/transaction/sighash.rs
#	zebra-chain/src/transaction/tests/vectors.rs
#	zebra-consensus/CHANGELOG.md
#	zebra-consensus/src/transaction/check.rs
# Conflicts:
#	zebra-consensus/src/transaction/tests.rs
)

orchard -> a0c1b83032ab7d75492c12f5ca28745c4e77eb1b (zcash/orchard feat/ironwood head)
librustzcash -> 4a2ff926db6312969afb7865f4e697bb41e98cf0 (Ironwood integration head)

Adapts to two moved orchard APIs, both in zebra-chain's note-encryption
primitive:
- BundleProtocol -> bundle::BundlePoolRestrictions (1:1 variant rename,
  behavior-preserving)
- version-specific note-encryption domains: use IronwoodDomain (V3) for
  the Ironwood bundle instead of OrchardDomain (V2)

Regenerates cargo-vet exemptions for the new pins.
…atch

Bumps the orchard patch to the feat/ironwood head (30c4ea27) and the librustzcash patch revs to the ironwood-integration commit that depends on it, so the lock resolves to a single orchard version.
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	supply-chain/config.toml
#	zebra-chain/src/block/arbitrary.rs
#	zebra-chain/src/primitives/zcash_history.rs
#	zebra-chain/src/primitives/zcash_note_encryption.rs
#	zebra-state/src/service/finalized_state.rs
#	zebra-state/src/service/finalized_state/zebra_db/rollback.rs
#	zebra-state/src/service/non_finalized_state/chain.rs
#	zebra-state/src/service/non_finalized_state/tests/vectors.rs
… add-ironwood-v6-value-pool

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	zebra-chain/src/primitives/zcash_note_encryption.rs
# Conflicts:
#	zebra-consensus/src/primitives/halo2.rs
#	zebra-consensus/src/primitives/halo2/tests.rs
#	zebra-consensus/src/transaction.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants