diff --git a/flake.lock b/flake.lock
index 5a9df8191..9dd4af3af 100644
--- a/flake.lock
+++ b/flake.lock
@@ -18,6 +18,30 @@
"type": "github"
}
},
+ "multimarkdown6": {
+ "inputs": {
+ "flake-utils": [
+ "flake-utils"
+ ],
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1772132433,
+ "narHash": "sha256-ScYZ7ME1N1zI34iwdGIdshChqsdrOgS09aLbkIZ7Xjo=",
+ "owner": "zcash",
+ "repo": "MultiMarkdown-6",
+ "rev": "543434c9df78b6be9e8125ff19a5e6934dc8ba82",
+ "type": "github"
+ },
+ "original": {
+ "owner": "zcash",
+ "repo": "MultiMarkdown-6",
+ "rev": "543434c9df78b6be9e8125ff19a5e6934dc8ba82",
+ "type": "github"
+ }
+ },
"nixpkgs": {
"locked": {
"lastModified": 1768564909,
@@ -37,6 +61,7 @@
"root": {
"inputs": {
"flake-utils": "flake-utils",
+ "multimarkdown6": "multimarkdown6",
"nixpkgs": "nixpkgs"
}
},
diff --git a/flake.nix b/flake.nix
index b69455b2b..14035b348 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,44 +4,98 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
+ multimarkdown6 = {
+ url = "github:zcash/MultiMarkdown-6/543434c9df78b6be9e8125ff19a5e6934dc8ba82";
+ inputs.nixpkgs.follows = "nixpkgs";
+ inputs.flake-utils.follows = "flake-utils";
+ };
};
- outputs = { self, nixpkgs, flake-utils }:
- flake-utils.lib.eachDefaultSystem (system:
+ outputs =
+ {
+ self,
+ nixpkgs,
+ flake-utils,
+ multimarkdown6,
+ }:
+ flake-utils.lib.eachDefaultSystem (
+ system:
let
pkgs = nixpkgs.legacyPackages.${system};
+ mmd = multimarkdown6.packages.${system}.default;
+
+ # Pin docutils and rst2html5 to the versions specified in zip-guide.rst.
+ docutils = pkgs.python3Packages.docutils.overridePythonAttrs (old: rec {
+ version = "0.21.2";
+ src = pkgs.fetchPypi {
+ pname = "docutils";
+ inherit version;
+ hash = "sha256-OmsYcy7fGC2qPNEndbuzOM9WkUaPke7rEJ3v9uv6mG8=";
+ };
+ });
+
+ # This is a separate PyPI package from docutils' built-in rst2html5;
+ # it provides its own HTML5 writer with different math handling.
+ rst2html5 = pkgs.python3Packages.buildPythonPackage rec {
+ pname = "rst2html5";
+ version = "2.0.1";
+ pyproject = true;
+
+ src = pkgs.fetchPypi {
+ inherit pname version;
+ hash = "sha256-MJmYyF+rAo8vywGizNyIbbCvxDmCYueVoC6pxNDzKuk=";
+ };
+
+ build-system = [ pkgs.python3Packages.poetry-core ];
+
+ dependencies = [
+ docutils
+ pkgs.python3Packages.genshi
+ pkgs.python3Packages.pygments
+ ];
+
+ # rst2html5_.py is a top-level module referenced by the entry point
+ # but poetry-core's include directive doesn't always install it.
+ postInstall = ''
+ cp rst2html5_.py $out/${pkgs.python3.sitePackages}/
+ '';
+
+ # Tests require additional fixtures not included in the PyPI tarball
+ doCheck = false;
+ };
in
{
devShells.default = pkgs.mkShell {
- buildInputs = with pkgs; [
+ buildInputs = [
# Core dependencies for render.sh
- python3Packages.docutils # provides rst2html5
- pandoc # pandoc markdown renderer
- multimarkdown # multimarkdown renderer
- perl # perl for text processing
+ rst2html5 # rst2html5 2.0.1 (PyPI)
+ pkgs.python3Packages.pygments # syntax highlighting for code blocks
+ pkgs.pandoc # pandoc markdown renderer
+ mmd # multimarkdown renderer (zcash fork)
+ pkgs.perl # perl for text processing
# Build system dependencies
- gnumake # make command for building
- git # required by Makefile for safe.directory
+ pkgs.gnumake # make command for building
+ pkgs.git # required by Makefile for safe.directory
# LaTeX dependencies for protocol PDF generation
- (texlive.combine {
- inherit (texlive) scheme-full;
+ (pkgs.texlive.combine {
+ inherit (pkgs.texlive) scheme-full;
})
# Python dependencies for links_and_dests.py
- python3
- python3Packages.beautifulsoup4
- python3Packages.html5lib
- python3Packages.certifi
+ pkgs.python3
+ pkgs.python3Packages.beautifulsoup4
+ pkgs.python3Packages.html5lib
+ pkgs.python3Packages.certifi
# Standard utilities (usually available, but ensuring they're present)
- coreutils # sed, grep, cat, basename, wc, diff, cp, rm, mkdir, touch
- bash # shell interpreter
- gnused # GNU sed
- gnugrep # GNU grep
- diffutils # diff command
- findutils # utilities for finding files
+ pkgs.coreutils
+ pkgs.bash
+ pkgs.gnused
+ pkgs.gnugrep
+ pkgs.diffutils
+ pkgs.findutils
];
shellHook = ''
@@ -63,4 +117,4 @@
};
}
);
-}
\ No newline at end of file
+}
diff --git a/render.sh b/render.sh
index 2fee6649b..045e9e7b5 100755
--- a/render.sh
+++ b/render.sh
@@ -32,11 +32,11 @@ fi
title="$(basename -s ${filetype} ${inputfile} | sed -E 's|zip-0{0,3}|ZIP |; s|draft-|Draft |')$(grep -E '^(\.\.)?\s*Title: ' ${inputfile} |sed -E 's|.*Title||')"
echo " ${title}"
-Math1=''
-Math2=''
-Math3=''
+Math1=''
+Math2=''
+Math3=''
-Mermaid=''
+Mermaid=''
ViewAndStyle=''
diff --git a/static/assets/images/zip-0234-balance.png b/static/assets/images/zip-0234-balance.png
index 9f0e8e5a7..131600add 100644
Binary files a/static/assets/images/zip-0234-balance.png and b/static/assets/images/zip-0234-balance.png differ
diff --git a/static/assets/images/zip-0234-block_subsidy.png b/static/assets/images/zip-0234-block_subsidy.png
index 435d8fcd4..cfc26c66a 100644
Binary files a/static/assets/images/zip-0234-block_subsidy.png and b/static/assets/images/zip-0234-block_subsidy.png differ
diff --git a/zips/draft-arya-dairaemma-disable-addition-of-transparent-chain-value.md b/zips/draft-arya-dairaemma-disable-addition-of-transparent-chain-value.md
index 9492274d5..1028b81e7 100644
--- a/zips/draft-arya-dairaemma-disable-addition-of-transparent-chain-value.md
+++ b/zips/draft-arya-dairaemma-disable-addition-of-transparent-chain-value.md
@@ -2,7 +2,7 @@
ZIP: XXX
Title: Disabling Addition of New Value to the Transparent Chain Value Pool
Owners: Arya
- Daira-Emma Hopwood
+ Daira-Emma Hopwood
Status: Draft
Category: Consensus
Created: 2025-08-13
diff --git a/zips/draft-ecc-authenticated-reply-addrs.md b/zips/draft-ecc-authenticated-reply-addrs.md
index 6a9a5acb5..46c5db6bf 100644
--- a/zips/draft-ecc-authenticated-reply-addrs.md
+++ b/zips/draft-ecc-authenticated-reply-addrs.md
@@ -1,8 +1,8 @@
ZIP: ???
Title: Authenticated Reply Addresses
- Owners: Jack Grigg
- Kris Nuttycombe
- Daira Emma Hopwood
+ Owners: Jack Grigg
+ Kris Nuttycombe
+ Daira-Emma Hopwood
Status: Draft
Category: Standards / Wallet
Created: 2023-11-12
diff --git a/zips/draft-ecc-onchain-accountable-voting.md b/zips/draft-ecc-onchain-accountable-voting.md
index ec925b21a..5ee94d61a 100644
--- a/zips/draft-ecc-onchain-accountable-voting.md
+++ b/zips/draft-ecc-onchain-accountable-voting.md
@@ -1,6 +1,6 @@
ZIP: XXX
Title: On-chain Accountable Voting
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Status: Draft
Credits: Josh Swihart
Kris Nuttycombe
diff --git a/zips/draft-str4d-orchard-balance-proof.md b/zips/draft-str4d-orchard-balance-proof.md
index 98988cd88..77647e0d8 100644
--- a/zips/draft-str4d-orchard-balance-proof.md
+++ b/zips/draft-str4d-orchard-balance-proof.md
@@ -1,7 +1,7 @@
ZIP: unassigned
Title: Air drops, Proof-of-Balance, and Stake-weighted Polling
- Owners: Daira-Emma Hopwood
- Jack Grigg
+ Owners: Daira-Emma Hopwood
+ Jack Grigg
Status: Draft
Category: Informational
Created: 2023-12-07
diff --git a/zips/zip-0000.rst b/zips/zip-0000.rst
index 355df761b..efbe05be1 100644
--- a/zips/zip-0000.rst
+++ b/zips/zip-0000.rst
@@ -2,16 +2,16 @@
ZIP: 0
Title: ZIP Process
- Owners: Jack Grigg
+ Owners: Jack Grigg
Mark Henderson
- Daira-Emma Hopwood
+ Daira-Emma Hopwood
Arya
Kris Nuttycombe
Sam H. Smith
Original-Authors: Josh Cincinnati
George Tankersley
Deirdre Connolly
- teor
+ Teor
Aditya Bharadwaj
Conrado Gouvêa
Credits: Luke Dashjr
@@ -186,32 +186,33 @@ ZIP Editors
The current ZIP Editors are:
-* Jack Grigg, Daira-Emma Hopwood, and Kris Nuttycombe, associated with
- the Electric Coin Company;
+* Jack Grigg, Daira-Emma Hopwood, and Kris Nuttycombe in their individual
+ capacities.
* Arya, associated with the Zcash Foundation.
* Mark Henderson and Sam H. Smith, associated with Shielded Labs.
All can be reached at zips@z.cash. The current design of the ZIP Process
-dictates that there are always at least two ZIP Editors: at least one
-from the Electric Coin Company and at least one from the Zcash Foundation.
+dictates that there are always at least two ZIP Editors, including at least
+one from the Zcash Foundation.
ZIP Editors MUST declare any potential or perceived conflict of interest
they have relating to their responsibilities as ZIP Editors.
Daira-Emma Hopwood declares a conflict of interest in acting as a ZIP Editor
-and as the R&D Engineering Manager of Electric Coin Company, and will
-endeavour to minimize the downsides of that confluence of roles as far as
-possible. In particular, ze commits to stepping down from the ZIP Editor
-role after the deployment of Zcash Shielded Assets, assuming ze is still
-in a management role at ECC at that point.
+and as Head of Research and Assurance at Znewco, Inc., and will endeavour
+to minimize the downsides of that confluence of roles as far as possible.
+In particular, ze commits to stepping down from the ZIP Editor role after
+the deployment of Zcash Shielded Assets, assuming ze is still in a
+management role at a company primarily involved with the development of
+Zcash at that point.
ZIP Editors MUST be publicly transparent about any external influence
or constraints that have been placed or attempted to be placed on their
-actions as ZIP Editors (including from the Electric Coin Company,
-Zcash Foundation, Shielded Labs, or other organizations with which the
-Editors are associated), whether or not it affects those actions. This
-should not be interpreted as requiring ZIP Editors to reveal knowledge
-of undisclosed security vulnerabilities or mitigations.
+actions as ZIP Editors (including from Zcash Foundation, Shielded Labs,
+or other organizations with which the Editors are associated), whether
+or not it affects those actions. This should not be interpreted as
+requiring ZIP Editors to reveal knowledge of undisclosed security
+vulnerabilities or mitigations.
Additional Editors may be selected, with their consent, by consensus
among the current Editors.
@@ -972,7 +973,7 @@ See Also
Acknowledgements
================
-We thank George Tankersley, Deirdre Connolly, teor, Aditya Bharadwaj, and
+We thank George Tankersley, Deirdre Connolly, Teor, Aditya Bharadwaj, and
Conrado Gouvêa for their past contributions as ZIP Editors.
diff --git a/zips/zip-0032.rst b/zips/zip-0032.rst
index fe1d40bcf..8fba1d59b 100644
--- a/zips/zip-0032.rst
+++ b/zips/zip-0032.rst
@@ -2,8 +2,8 @@
ZIP: 32
Title: Shielded Hierarchical Deterministic Wallets
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Credits: Sean Bowe
Kris Nuttycombe
Ying Tong Lai
@@ -66,8 +66,8 @@ Zcash's transparent addresses [#slip-0044]_) generate keys and addresses determi
advantages over random generation:
- Wallets only need to store a single seed (particularly useful for hardware wallets).
-- A one-time backup of the seed (usually stored as a word phrase [#bip-0039]_) can be used to recover funds
- from all future addresses.
+- A one-time backup of the seed (usually stored as a BIP 39 mnemonic [#bip-0039]_ or SLIP 39 shares
+ [#slip-0039]_) can be used to recover funds from all future addresses.
- Keys are arranged into a tree of chains, enabling wallets to represent "accounts" or other high-level
structures.
- Viewing authority or spending authority can be delegated independently for sub-trees without compromising
@@ -148,6 +148,51 @@ Note: no corresponding notation is currently defined for the result of
`Hardened-only child key derivation`_ with non-zero $\mathsf{lead}$ and/or non-empty $\mathsf{tag}$.
+Specification: Wallet seeds
+===========================
+
+Several of the key derivation algorithms specified in this ZIP derive a master key from a
+seed byte sequence. Any such seed byte sequence MUST be at least 32 and at most 252 bytes.
+
+The method of generating such a seed byte sequence for Zcash purposes MUST ensure that it
+has at least 256 bits of entropy. This requirement also applies to any mnemonic or input
+randomness used to obtain the seed byte sequence. See ZIP 315 [#zip-0315-wallet-seeds]_ for
+further guidance.
+
+Rationale for the 256-bit entropy requirement
+---------------------------------------------
+
+.. raw:: html
+
+
+ Click to show/hide
+
+Zcash consistently uses cryptovalues of length at or close to 256 bits, throughout its
+cryptographic design. Although the target security level for the protocol against classical
+cryptanalytic attacks is $2^{125}$ (i.e. any such attack should take at least $2^{125}$
+operations, as explained in [#zcash-security]_), this does not imply that 128-bit keys or
+seeds are sufficient. The apparent gap between the security target and the key length is
+well motivated: it provides better resistance to attacks using parallel hardware
+[#Bernstein2005]_ in the multi-user setting [#Zaverucha2012]_; it takes into account small
+entropy losses in the key derivation process; and it simplifies the analysis of the protocol
+against quantum attacks for unknown addresses [#zcash-security]_, or in the context of a
+future post-quantum recovery protocol [#zip-2005]_.
+
+In particular, for the hierarchical key derivation method described in this ZIP, if the seed
+or mnemonic has entropy less than 256 bits, it will be a weak link in the derivation of
+*all* keys belonging to that wallet.
+
+It should be noted that an adversary can search for uses of lower-entropy mnemonics across
+multiple wallets simultaneously. They can collect a large set of (transparent or shielded)
+target addresses and/or viewing keys, and then perform a brute-force search over mnemonics
+in a lower-entropy subspace, efficiently checking whether the first few addresses or viewing
+keys that would be generated from each mnemonic match any of the targets.
+
+.. raw:: html
+
+
+
+
Specification: Sapling key derivation
=====================================
@@ -187,7 +232,7 @@ Define
Sapling master key generation
-----------------------------
-Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
+Let $S$ be a seed byte sequence meeting the requirements in `Specification: Wallet seeds`_.
- Calculate $I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Sapling”}, S)$.
- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$.
@@ -440,7 +485,7 @@ is the normal Orchard spending key (opaque 32 bytes), and $\mathsf{c}$ is the ch
Orchard master key generation
-----------------------------
-Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
+Let $S$ be a seed byte sequence meeting the requirements in `Specification: Wallet seeds`_.
- Return $\mathsf{MKGh}^\mathsf{Orchard}(S)$ as the master extended spending key
$m_\mathsf{Orchard}$.
@@ -552,7 +597,7 @@ We instantiate the hardened key generation process with the following constants:
Registered subtree root key generation
--------------------------------------
-Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
+Let $S$ be a seed byte sequence meeting the requirements in `Specification: Wallet seeds`_.
The registered subtree root is obtained as:
@@ -624,7 +669,7 @@ We instantiate the hardened key derivation process with the following constants:
Ad-hoc master key generation (deprecated)
-----------------------------------------
-Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.
+Let $S$ be a seed byte sequence meeting the requirements in `Specification: Wallet seeds`_.
The master extended ad-hoc key is:
@@ -872,6 +917,7 @@ References
.. [#BCP14] `Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" `_
.. [#bip-0032] `BIP 32: Hierarchical Deterministic Wallets `_
.. [#bip-0039] `BIP 39: Mnemonic code for generating deterministic keys `_
+.. [#slip-0039] `SLIP 39: Shamir's Secret-Sharing for Mnemonic Codes `_
.. [#bip-0043] `BIP 43: Purpose Field for Deterministic Wallets `_
.. [#bip-0044] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets `_
.. [#slip-0044] `SLIP 44: Registered coin types for BIP-0044 `_
@@ -890,5 +936,10 @@ References
.. [#protocol-orchardfullviewingkeyencoding] `Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.4: Orchard Raw Full Viewing Keys `_
.. [#protocol-orchardspendingkeyencoding] `Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.5: Orchard Spending Keys `_
.. [#NIST-SP-800-38G] `NIST Special Publication 800-38G — Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption `_
+.. [#zcash-security] `Understanding the Security of Zcash. Presentation by Daira-Emma Hopwood at Zcon3 `_ (`slides `_).
+.. [#Bernstein2005] `Understanding brute force. Daniel Bernstein, 2005. `_
+.. [#Zaverucha2012] `Hybrid Encryption in the Multi-User Setting. Gregory M. Zaverucha, 2012. `_
.. [#zip-0000] `ZIP 0: ZIP Process `_
+.. [#zip-0315-wallet-seeds] `ZIP 315: Best Practices for Wallet Implementations — Specification: Wallet seeds `_
.. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_
+.. [#zip-2005] `ZIP 2005: Orchard Quantum Recoverability `_
diff --git a/zips/zip-0048.md b/zips/zip-0048.md
index d5572609c..a0c3a45d5 100644
--- a/zips/zip-0048.md
+++ b/zips/zip-0048.md
@@ -1,9 +1,9 @@
ZIP: 48
Title: Transparent Multisig Wallets
- Owners: Kris Nuttycombe
- Jack Grigg
- Daira-Emma Hopwood
+ Owners: Kris Nuttycombe
+ Jack Grigg
+ Daira-Emma Hopwood
Arya
Credits: Fontaine
Status: Draft
diff --git a/zips/zip-0068.rst b/zips/zip-0068.rst
index 1c22879e8..2f567313c 100644
--- a/zips/zip-0068.rst
+++ b/zips/zip-0068.rst
@@ -2,10 +2,11 @@
ZIP: 68
Title: Relative lock-time using consensus-enforced sequence numbers
- Credits: Mark Friedenbach
- BtcDrak
- Nicolas Dorier
- kinoshitajona
+ Owners: Daira-Emma Hopwood
+ Credits: Mark Friedenbach
+ BtcDrak
+ Nicolas Dorier
+ kinoshitajona
Category: Consensus
Status: Draft
Created: 2016-06-06
diff --git a/zips/zip-0076.rst b/zips/zip-0076.rst
index 35ba78a96..1da99476d 100644
--- a/zips/zip-0076.rst
+++ b/zips/zip-0076.rst
@@ -2,8 +2,8 @@
ZIP: 76
Title: Transaction Signature Validation before Overwinter
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Status: Reserved
Category: Consensus
Discussions-To:
diff --git a/zips/zip-0112.rst b/zips/zip-0112.rst
index a6c130c0b..7eba047a2 100644
--- a/zips/zip-0112.rst
+++ b/zips/zip-0112.rst
@@ -2,10 +2,10 @@
ZIP: 112
Title: CHECKSEQUENCEVERIFY
- Author: Daira Hopwood
- Credits: BtcDrak
- Mark Friedenbach
- Eric Lombrozo
+ Owners: Daira-Emma Hopwood
+ Credits: BtcDrak
+ Mark Friedenbach
+ Eric Lombrozo
Category: Consensus
Status: Draft
Created: 2019-06-06
diff --git a/zips/zip-0113.rst b/zips/zip-0113.rst
index d7d657a4c..e4d94d21b 100644
--- a/zips/zip-0113.rst
+++ b/zips/zip-0113.rst
@@ -2,9 +2,9 @@
ZIP: 113
Title: Median Time Past as endpoint for lock-time calculations
- Author: Daira Hopwood
- Credits: Thomas Kerin
- Mark Friedenbach
+ Owners: Daira-Emma Hopwood
+ Credits: Thomas Kerin
+ Mark Friedenbach
Gregory Maxwell
Category: Consensus
Status: Draft
diff --git a/zips/zip-0129.md b/zips/zip-0129.md
index b89315cf1..61148ce3f 100644
--- a/zips/zip-0129.md
+++ b/zips/zip-0129.md
@@ -1,8 +1,8 @@
ZIP: 129
Title: Zcash Transparent Multisig Setup
- Owners: Kris Nuttycombe
- Jack Grigg
+ Owners: Kris Nuttycombe
+ Jack Grigg
Arya
Credits: Hugo Nguyen
Peter Gray
diff --git a/zips/zip-0143.rst b/zips/zip-0143.rst
index af07101d5..09b14306f 100644
--- a/zips/zip-0143.rst
+++ b/zips/zip-0143.rst
@@ -2,8 +2,8 @@
ZIP: 143
Title: Transaction Signature Validation for Overwinter
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Credits: Johnson Lau
Pieter Wuille
Bitcoin-ABC
diff --git a/zips/zip-0155.rst b/zips/zip-0155.rst
index 214091629..1a5088331 100644
--- a/zips/zip-0155.rst
+++ b/zips/zip-0155.rst
@@ -2,7 +2,7 @@
ZIP: 155
Title: addrv2 message
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Credits: Wladimir J. van der Laan
Zancas Wilcox
Status: Proposed
diff --git a/zips/zip-0173.rst b/zips/zip-0173.rst
index 70ca789f5..75ce013e7 100644
--- a/zips/zip-0173.rst
+++ b/zips/zip-0173.rst
@@ -2,9 +2,9 @@
ZIP: 173
Title: Bech32 Format
- Owners: Daira-Emma Hopwood
- Credits: Pieter Wuille
- Greg Maxwell
+ Owners: Daira-Emma Hopwood
+ Credits: Pieter Wuille
+ Greg Maxwell
Rusty Russell
Mark Friedenbach
Status: Final
diff --git a/zips/zip-0200.rst b/zips/zip-0200.rst
index 5b3733370..4db92a743 100644
--- a/zips/zip-0200.rst
+++ b/zips/zip-0200.rst
@@ -2,7 +2,7 @@
ZIP: 200
Title: Network Upgrade Mechanism
- Owners: Jack Grigg
+ Owners: Jack Grigg
Status: Final
Category: Consensus
Created: 2018-01-08
diff --git a/zips/zip-0201.rst b/zips/zip-0201.rst
index 2aae78503..0ea061814 100644
--- a/zips/zip-0201.rst
+++ b/zips/zip-0201.rst
@@ -2,7 +2,7 @@
ZIP: 201
Title: Network Peer Management for Overwinter
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Original-Authors: Simon Liu
Status: Final
Category: Network
diff --git a/zips/zip-0202.rst b/zips/zip-0202.rst
index adc7728df..97b365642 100644
--- a/zips/zip-0202.rst
+++ b/zips/zip-0202.rst
@@ -2,7 +2,7 @@
ZIP: 202
Title: Version 3 Transaction Format for Overwinter
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Original-Authors: Simon Liu
Status: Final
Category: Consensus
diff --git a/zips/zip-0203.rst b/zips/zip-0203.rst
index a49f0b349..e9ed61950 100644
--- a/zips/zip-0203.rst
+++ b/zips/zip-0203.rst
@@ -2,7 +2,7 @@
ZIP: 203
Title: Transaction Expiry
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Original-Authors: Jay Graber
Status: Final
Category: Consensus
diff --git a/zips/zip-0204.rst b/zips/zip-0204.rst
index 77b5cdf52..f2184128e 100644
--- a/zips/zip-0204.rst
+++ b/zips/zip-0204.rst
@@ -2,7 +2,1394 @@
ZIP: 204
Title: Zcash P2P Network Protocol
- Owners: Daira-Emma Hopwood
- Status: Reserved
+ Owners: Daira-Emma Hopwood
+ Kris Nuttycombe
+ Status: Draft
Category: Network
+ Created: 2026-02-05
+ License: MIT
Discussions-To:
+
+
+Terminology
+===========
+
+The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "RECOMMENDED" in this
+document are to be interpreted as described in BCP 14 [#BCP14]_ when, and only when,
+they appear in all capitals.
+
+The terms "Mainnet" and "Testnet" are to be interpreted as described in section 3.12 of
+the Zcash Protocol Specification. [#protocol-networks]_
+
+The term "network upgrade" is to be interpreted as described in ZIP 200. [#zip-0200]_
+
+The term "block chain" in this document is to be interpreted as described in section 3.3
+of the Zcash Protocol Specification. [#protocol-blockchain]_
+
+peer
+ A network node that participates in the Zcash P2P protocol by maintaining one or more
+ TCP connections to other peers and exchanging protocol messages.
+
+connection
+ A TCP session between two peers over which P2P messages are exchanged.
+
+inbound connection
+ A connection that was initiated by the remote peer.
+
+outbound connection
+ A connection that was initiated by the local node.
+
+protocol version
+ A 32-bit integer identifying the set of protocol features supported by a node. Higher
+ values indicate support for more recent features.
+
+
+Abstract
+========
+
+This ZIP specifies the Zcash peer-to-peer network protocol, including connection setup,
+message framing, message types, and relay behavior. It is intended to be sufficient for
+an implementor to build a conformant Zcash network peer.
+
+
+Motivation
+==========
+
+There is currently no single document that specifies the full Zcash P2P network
+protocol. While Bitcoin protocol documentation exists, the Zcash protocol has diverged
+in several significant ways: network magic bytes differ, protocol version numbers follow
+an independent numbering scheme, inventory types include ``MSG_WTX`` [#zip-0239]_,
+and network upgrade activation drives protocol versioning and peer management
+[#zip-0200]_ [#zip-0201]_.
+
+This ZIP consolidates the protocol specification into a single normative reference,
+enabling independent implementations and protocol analysis.
+
+This ZIP does not specify the encoding of transactions and blocks; for those, refer to
+the Zcash Protocol Specification [#protocol-txnencoding]_ [#protocol-blockencoding]_.
+
+
+Specification
+=============
+
+Network Parameters
+------------------
+
+Magic Bytes
+```````````
+
+Each Zcash network is identified by a 4-byte magic value that appears at the start of
+every protocol message. A node MUST reject messages whose magic bytes do not match the
+expected network.
+
++-----------+---------------------+
+| Network | Magic Bytes (hex) |
++===========+=====================+
+| Mainnet | ``24 e9 27 64`` |
++-----------+---------------------+
+| Testnet | ``fa 1a f9 bf`` |
++-----------+---------------------+
+| Regtest | ``aa e8 3f 5f`` |
++-----------+---------------------+
+
+Default Ports
+`````````````
+
++-----------+----------------+
+| Network | Default Port |
++===========+================+
+| Mainnet | 8233 |
++-----------+----------------+
+| Testnet | 18233 |
++-----------+----------------+
+| Regtest | 18344 |
++-----------+----------------+
+
+DNS Seeds
+`````````
+
+The following DNS seed hostnames are used for initial peer discovery.
+
+**Mainnet:**
+
+- ``dnsseed.z.cash``
+- ``dnsseed.str4d.xyz``
+- ``mainnet.seeder.zfnd.org``
+- ``mainnet.is.yolo.money``
+
+**Testnet:**
+
+- ``dnsseed.testnet.z.cash``
+- ``testnet.seeder.zfnd.org``
+- ``testnet.is.yolo.money``
+
+Regtest does not use DNS seeds or hardcoded seed nodes.
+
+
+Peer Discovery
+--------------
+
+A node discovers peers through the following mechanisms:
+
+1. **DNS seeding.** On startup, a node queries the DNS seed hostnames listed above
+ for A and AAAA records. The zcashd implementation does this only if the address
+ manager is empty or if fewer than 2 outbound connections have been established
+ within 11 seconds; the Zebra implementation always performs DNS lookups on
+ startup (alongside consulting a persistent address cache).
+
+2. **Hardcoded seed nodes.** If DNS seeding fails or is insufficient, the node
+ MAY fall back to a compiled-in list of seed node addresses. In the zcashd
+ implementation these hardcoded addresses may be found in the chain
+ parameters for the relevant network. DNS seeding is preferred over
+ hardcoded seed nodes.
+
+3. **Address relay.** Connected peers exchange address information using ``addr`` and
+ ``getaddr`` messages (see `addr`_ and `getaddr`_). This mechanism operates
+ independently of the above.
+
+
+Connection Handling
+-------------------
+
+Transport
+`````````
+
+All connections use unencrypted TCP. The protocol does not provide transport-layer
+encryption or authentication.
+
+Connection Limits
+`````````````````
+
+The specific connection limits are implementation-defined. The zcashd implementation
+defaults to a maximum of 125 peer connections (``DEFAULT_MAX_PEER_CONNECTIONS``), of
+which a maximum of 8 are outbound connections (``MAX_OUTBOUND_CONNECTIONS``). The Zebra
+implementation computes its limits from a configurable initial target size (default 25),
+applying multipliers to derive an outbound limit of 75 and an inbound limit of 125.
+
+Timeouts
+````````
+
+A node SHOULD disconnect a peer if no message has been received from that peer within
+a reasonable timeout period. The zcashd implementation uses 1200 seconds (20 minutes,
+``TIMEOUT_INTERVAL``) for this purpose; the Zebra implementation uses a 20-second
+request timeout (``REQUEST_TIMEOUT``). Automatic ``ping`` messages (see `ping`_) are
+sent periodically to keep connections alive and measure latency.
+
+Additional timeout rules:
+
+- A node SHOULD close the connection if a peer has not sent a ``version`` message
+ within a reasonable time after connection establishment. The zcashd implementation
+ uses 60 seconds; the Zebra implementation uses 3 seconds (``HANDSHAKE_TIMEOUT``).
+- A node SHOULD close the connection if a peer has not responded to a ``ping`` with
+ a corresponding ``pong`` within a reasonable time. The zcashd implementation uses
+ 1200 seconds (20 minutes); the Zebra implementation uses 20 seconds
+ (``REQUEST_TIMEOUT``).
+
+The specific timeout values are implementation-defined.
+
+
+Message Framing
+---------------
+
+Every protocol message consists of a 24-byte header followed by a variable-length
+payload.
+
+Message Header
+``````````````
+
++--------+------+----------------+----------------------------------------------------+
+| Offset | Size | Field | Description |
++========+======+================+====================================================+
+| 0 | 4 | ``magic`` | Network magic bytes (see `Magic Bytes`_). |
++--------+------+----------------+----------------------------------------------------+
+| 4 | 12 | ``command`` | ASCII command string, NUL-padded to 12 bytes. |
++--------+------+----------------+----------------------------------------------------+
+| 16 | 4 | ``length`` | Payload size in bytes (``uint32``, little-endian). |
++--------+------+----------------+----------------------------------------------------+
+| 20 | 4 | ``checksum`` | First 4 bytes of ``SHA-256d(payload)``. |
++--------+------+----------------+----------------------------------------------------+
+
+The total header size is 24 bytes.
+
+Command String Validation
+`````````````````````````
+
+The ``command`` field MUST contain only printable ASCII characters (bytes in the range
+``0x20`` to ``0x7E`` inclusive) up to the first NUL byte (``0x00``). After the first NUL
+byte, all remaining bytes MUST be ``0x00``. A message that violates these constraints
+MUST be ignored.
+
+The following command strings are currently used on the Zcash network:
+
+``version``, ``verack``, ``ping``, ``pong``, ``reject``, ``addr``, ``addrv2``,
+``getaddr``, ``inv``, ``getdata``, ``notfound``, ``getblocks``, ``getheaders``,
+``headers``, ``block``, ``tx``, ``mempool``, ``filterload``, ``filteradd``,
+``filterclear``, ``alert``.
+
+Maximum Message Size
+````````````````````
+
+The maximum payload size is 2,097,152 bytes (2 MiB). A node MUST reject any message
+whose ``length`` field exceeds this limit.
+
+Checksum Verification
+`````````````````````
+
+The ``checksum`` field contains the first 4 bytes of the double-SHA-256 hash of the
+payload:
+
+ ``checksum = SHA-256(SHA-256(payload))[0..4]``
+
+A node MUST verify the checksum after receiving the full payload and MUST reject the
+message if the checksum does not match.
+
+
+Data Types and Encoding
+-----------------------
+
+All multi-byte integer types are encoded in little-endian byte order unless otherwise
+specified. The integer types used in this specification (``uint8``, ``uint16``,
+``int32``, ``uint32``, ``int64``, ``uint64``) have their conventional meanings.
+
+CompactSize
+```````````
+
+.. note::
+
+ The CompactSize encoding is used in the Zcash Protocol Specification (section 7)
+ but is not formally defined there. It is defined here for completeness.
+
+A variable-length unsigned integer encoding used for lengths and counts:
+
++------------------------------------------+---------------+---------------------------------------------------+
+| Value Range | Encoding Size | Format |
++==========================================+===============+===================================================+
+| 0 to 252 | 1 byte | Single byte with the value directly. |
++------------------------------------------+---------------+---------------------------------------------------+
+| 253 to 0xFFFF | 3 bytes | ``0xFD`` followed by the value as ``uint16``. |
++------------------------------------------+---------------+---------------------------------------------------+
+| 0x10000 to 0xFFFFFFFF | 5 bytes | ``0xFE`` followed by the value as ``uint32``. |
++------------------------------------------+---------------+---------------------------------------------------+
+| 0x100000000 to 0xFFFFFFFFFFFFFFFF | 9 bytes | ``0xFF`` followed by the value as ``uint64``. |
++------------------------------------------+---------------+---------------------------------------------------+
+
+Encodings MUST be canonical: the shortest possible encoding MUST be used for any given
+value. A node MUST reject messages containing non-canonical CompactSize encodings.
+
+Strings
+```````
+
+Character strings are encoded as a CompactSize length prefix followed by that many bytes
+of string data. There is no NUL terminator.
+
+Network Address (``CService``)
+``````````````````````````````
+
+A network address without associated metadata, as inherited from the Bitcoin protocol:
+
++------+----------+--------------------------------------------------------------+
+| Size | Field | Description |
++======+==========+==============================================================+
+| 16 | ``ip`` | IPv6 address (or IPv4-mapped IPv6 address [#rfc4291]_ for |
+| | | IPv4 peers). |
++------+----------+--------------------------------------------------------------+
+| 2 | ``port`` | TCP port number (big-endian, i.e. network byte order). |
++------+----------+--------------------------------------------------------------+
+
+IPv4 addresses are represented as IPv4-mapped IPv6 addresses as defined in RFC 4291
+section 2.5.5.2 [#rfc4291]_: the first 12 bytes are ``00 00 00 00 00 00 00 00 00 00 FF FF``
+followed by the 4-byte IPv4 address.
+
+Peer Address (``CAddress``)
+```````````````````````````
+
+A network address with associated metadata, used in ``version``, ``addr``, and other
+messages:
+
++------+--------------+-----------------------------------------------------+
+| Size | Field | Description |
++======+==============+=====================================================+
+| 8 | ``services`` | Bitfield of service flags (``uint64``, |
+| | | little-endian). |
++------+--------------+-----------------------------------------------------+
+| 16 | ``ip`` | IPv6 address (or IPv4-mapped IPv6). |
++------+--------------+-----------------------------------------------------+
+| 2 | ``port`` | TCP port number (big-endian). |
++------+--------------+-----------------------------------------------------+
+
+When the negotiated protocol version (see `Protocol Version Negotiation`_) is
+≥ 31402 (``CADDR_TIME_VERSION``) and the address appears in a context other than a
+``version`` message, the encoding is preceded by a ``uint32`` timestamp field:
+
++------+--------------+-----------------------------------------------------+
+| Size | Field | Description |
++======+==============+=====================================================+
+| 4 | ``time`` | Unix-epoch UTC time in seconds when the node |
+| | | was last seen (``uint32``, little-endian). |
++------+--------------+-----------------------------------------------------+
+| 8 | ``services`` | Bitfield of service flags (``uint64``, |
+| | | little-endian). |
++------+--------------+-----------------------------------------------------+
+| 16 | ``ip`` | IPv6 address (or IPv4-mapped IPv6). |
++------+--------------+-----------------------------------------------------+
+| 2 | ``port`` | TCP port number (big-endian). |
++------+--------------+-----------------------------------------------------+
+
+
+Service Flags
+-------------
+
+Service flags are advertised in the ``services`` field of ``version`` messages and
+``CAddress`` structures. In the table below, bit $k$ refers to the bit with
+numeric weight $2^k;$ that is, the ``services`` field has the corresponding flag
+set if and only if ``services & (1 << k) != 0``.
+
++------------------+-----+------------------------------------------------------+
+| Name | Bit | Description |
++==================+=====+======================================================+
+| ``NODE_NETWORK`` | 0 | The node is capable of serving the complete block |
+| | | chain. |
++------------------+-----+------------------------------------------------------+
+| ``NODE_BLOOM`` | 2 | The node supports Bloom-filtered connections |
+| | | (BIP 37 [#bip-0037]_). Zcash nodes used to support |
+| | | this by default without advertising the bit, but no |
+| | | longer do as of protocol version 170004 |
+| | | (``NO_BLOOM_VERSION``). |
++------------------+-----+------------------------------------------------------+
+
+Bits 24–31 are reserved for temporary experiments.
+
+
+Inventory Vectors
+-----------------
+
+Inventory vectors identify objects (transactions and blocks) for relay. The format
+depends on the type:
+
++------------------------+------+------------+-------------------------------------------+
+| Type | Code | Entry Size | Description |
++========================+======+============+===========================================+
+| ``MSG_TX`` | 1 | 36 bytes | Transaction identified by txid. |
+| | | | 4-byte type code + 32-byte txid. |
++------------------------+------+------------+-------------------------------------------+
+| ``MSG_BLOCK`` | 2 | 36 bytes | Block identified by block hash. |
+| | | | 4-byte type code + 32-byte block hash. |
++------------------------+------+------------+-------------------------------------------+
+| ``MSG_FILTERED_BLOCK`` | 3 | 36 bytes | Filtered block (``getdata`` only). |
+| | | | 4-byte type code + 32-byte block hash. |
++------------------------+------+------------+-------------------------------------------+
+| ``MSG_WTX`` | 5 | 68 bytes | Transaction identified by wtxid. |
+| | | | 4-byte type code + 32-byte txid + |
+| | | | 32-byte authorizing data commitment |
+| | | | (``auth_digest``). Requires negotiated |
+| | | | protocol version ≥ 170014 |
+| | | | (``CINV_WTX_VERSION``). |
+| | | | See ZIP 239 [#zip-0239]_. |
++------------------------+------+------------+-------------------------------------------+
+
+Because ``MSG_TX`` and ``MSG_WTX`` entries have different sizes (36 and 68 bytes
+respectively), they may be mixed in a single ``inv`` or ``getdata`` message. The total
+message size is therefore not determined solely by the entry count and MUST be determined
+by parsing each entry individually.
+
+A node MUST reject inventory vectors with unrecognized type codes. A node MUST reject
+``MSG_WTX`` inventory vectors if the negotiated protocol version is less than 170014.
+
+
+Connection Handshake
+--------------------
+
+Peers perform a version handshake immediately upon establishing a TCP connection.
+
+Handshake Sequence
+``````````````````
+
+1. The initiating (outbound) peer sends a ``version`` message.
+2. The receiving (inbound) peer sends its own ``version`` message.
+3. Each peer, upon receiving a valid ``version`` message, responds with a ``verack``
+ message.
+4. The negotiated protocol version is ``min(local_version, remote_version)``.
+
+A peer MUST NOT send any message other than ``version`` before receiving the remote
+peer's ``version`` message. A peer MUST NOT send any message other than ``verack`` after
+sending its ``version`` and before receiving the remote peer's ``verack``.
+
+If validation of the ``version`` message received from a peer fails, the node
+MUST disconnect the peer. See (see `Version Validation`_) below for additional
+details.
+
+Protocol Version Negotiation
+````````````````````````````
+
+Each peer advertises its own protocol version in its ``version`` message. The
+*negotiated protocol version* for the connection is defined as:
+
+ ``negotiated_version = min(local_version, remote_version)``
+
+Before the handshake completes, messages are serialized using the initial protocol
+version 209 (``INIT_PROTO_VERSION``). Once both ``version`` and ``verack`` messages
+have been exchanged, the negotiated protocol version is used for all subsequent
+interpretation of protocol features and message semantics on that connection. In
+particular, the negotiated protocol version determines:
+
+- Whether ``CAddress`` structures include a ``time`` field (version ≥ 31402).
+- Whether ``MSG_WTX`` inventory vectors are permitted (version ≥ 170014).
+- Whether ``addrv2`` messages are supported (see `addrv2`_).
+- Whether the peer meets the minimum version requirements for the current network
+ epoch (see `Network Upgrade Epoch Enforcement`_).
+
+Note that "the protocol version" as used in this document refers to the negotiated
+protocol version unless otherwise specified. A node's *advertised* protocol version
+is the version it includes in its ``version`` message.
+
+Version Message
+```````````````
+
+The ``version`` message payload has the following format:
+
++--------+---------+------------------+------------------------------------------------+
+| Offset | Size | Field | Description |
++========+=========+==================+================================================+
+| 0 | 4 | ``version`` | Protocol version (``int32``). |
++--------+---------+------------------+------------------------------------------------+
+| 4 | 8 | ``services`` | Bitfield of service flags (``uint64``). |
++--------+---------+------------------+------------------------------------------------+
+| 12 | 8 | ``timestamp`` | Unix-epoch UTC time in seconds (``int64``). |
++--------+---------+------------------+------------------------------------------------+
+| 20 | 26 | ``addr_recv`` | Address of the receiving node (``CAddress`` |
+| | | | without ``time`` field). |
++--------+---------+------------------+------------------------------------------------+
+| 46 | 26 | ``addr_from`` | Address of the sending node (``CAddress`` |
+| | | | without ``time`` field). |
++--------+---------+------------------+------------------------------------------------+
+| 72 | 8 | ``nonce`` | Random nonce for self-connection detection |
+| | | | (``uint64``). |
++--------+---------+------------------+------------------------------------------------+
+| 80 | varies | ``user_agent`` | User agent string (CompactSize-prefixed, |
+| | | | max 256 bytes). |
++--------+---------+------------------+------------------------------------------------+
+| varies | 4 | ``start_height`` | Best block height known to the sender |
+| | | | (``int32``). |
++--------+---------+------------------+------------------------------------------------+
+| varies | 1 | ``relay`` | Whether the sender wants transaction relay |
+| | | (optional) | (``uint8``; 0 for false, nonzero for true). |
++--------+---------+------------------+------------------------------------------------+
+
+The ``addr_recv`` and ``addr_from`` fields use the ``CAddress`` encoding *without*
+the ``time`` field, regardless of the protocol version being negotiated.
+
+The ``nonce`` field is used for self-connection detection. If a node receives a
+``version`` message containing its own nonce, it MUST close the connection.
+
+The ``user_agent`` string MUST NOT exceed 256 bytes. A node SHOULD disconnect peers
+that send a longer user agent.
+
+The ``relay`` field is optional; if not present, its value MUST be interpreted as true.
+A node SHOULD reject ``version`` messages in which the ``relay`` field is present with
+a value other than 0 or 1. Nodes SHOULD create `version` messages with this field
+present.
+
+Version Validation
+``````````````````
+
+A receiving node MUST validate the ``version`` message as follows:
+
+- The ``version`` field MUST be at least 170002 (``MIN_PEER_PROTO_VERSION``).
+- On Testnet, the ``version`` field MUST be at least 170040
+ (``MIN_TESTNET_PEER_PROTO_VERSION``).
+- The ``version`` field MUST be at least the protocol version associated with
+ the current network epoch (see `Network Upgrade Peer Management`_).
+- The ``nonce`` MUST NOT match the local node's nonce (self-connection detection).
+- A peer MUST NOT send more than one ``version`` message per connection. Duplicate
+ ``version`` messages incur a misbehavior penalty.
+
+If any of these checks fail, the node MUST disconnect the peer. A ``reject`` message
+with code ``REJECT_OBSOLETE`` (``0x11``) SHOULD be sent before disconnecting for
+version-related failures.
+
+Protocol Versioning
+-------------------
+
+Protocol versions are 32-bit integers. The following versions are significant:
+
++---------+-------------------------------------+------------------------------------------+
+| Version | Constant | Significance |
++=========+=====================================+==========================================+
+| 209 | ``INIT_PROTO_VERSION`` | Initial protocol version. Used as the |
+| | | serialization version before the |
+| | | ``version``/``verack`` handshake |
+| | | completes. |
++---------+-------------------------------------+------------------------------------------+
+| 31402 | ``CADDR_TIME_VERSION`` | Adds the ``time`` field to ``CAddress`` |
+| | | in ``addr`` messages. Also affects |
+| | | encoding of the ``addr_from`` field in |
+| | | ``version`` messages. |
++---------+-------------------------------------+------------------------------------------+
+| 60000 | ``BIP0031_VERSION`` | ``ping`` messages include a ``uint64`` |
+| | | nonce and expect a ``pong`` response. |
+| | | For protocol versions ≤ 60000, ``ping`` |
+| | | has an empty payload. |
++---------+-------------------------------------+------------------------------------------+
+| 170002 | ``MIN_PEER_PROTO_VERSION`` | Minimum protocol version for Mainnet |
+| | | peers. |
++---------+-------------------------------------+------------------------------------------+
+| 170004 | ``NO_BLOOM_VERSION`` | Bloom filter commands (``filterload``, |
+| | | ``filteradd``, ``filterclear``) are |
+| | | disabled unless the node advertises |
+| | | ``NODE_BLOOM``. |
++---------+-------------------------------------+------------------------------------------+
+| 170014 | ``CINV_WTX_VERSION`` | Adds ``MSG_WTX`` inventory type for v5 |
+| | | transaction relay. See ZIP 239 |
+| | | [#zip-0239]_. |
++---------+-------------------------------------+------------------------------------------+
+| 170040 | ``MIN_TESTNET_PEER_PROTO_VERSION`` | Minimum protocol version for Testnet |
+| | | peers. |
++---------+-------------------------------------+------------------------------------------+
+| 170140 | ``PROTOCOL_VERSION`` | Current protocol version. |
++---------+-------------------------------------+------------------------------------------+
+
+Network Upgrade Epoch Enforcement
+`````````````````````````````````
+
+Each network upgrade defines a minimum protocol version. When a network upgrade activates
+(as defined in ZIP 200 [#zip-0200]_), a node MUST disconnect any peer whose negotiated
+protocol version is less than the protocol version associated with the current epoch.
+The node SHOULD send a ``reject`` message with code ``REJECT_OBSOLETE`` (``0x11``)
+before disconnecting.
+
+The following protocol versions are associated with network upgrades on Mainnet:
+
++-------------------+------------------+-------------------+
+| Network Upgrade | Protocol Version | Activation Height |
++===================+==================+===================+
+| Sprout | 170002 | (always active) |
++-------------------+------------------+-------------------+
+| Overwinter | 170005 | 347,500 |
++-------------------+------------------+-------------------+
+| Sapling | 170007 | 419,200 |
++-------------------+------------------+-------------------+
+| Blossom | 170009 | 653,600 |
++-------------------+------------------+-------------------+
+| Heartwood | 170011 | 903,000 |
++-------------------+------------------+-------------------+
+| Canopy | 170013 | 1,046,400 |
++-------------------+------------------+-------------------+
+| NU5 | 170100 | 1,687,104 |
++-------------------+------------------+-------------------+
+| NU6 | 170120 | 2,726,400 |
++-------------------+------------------+-------------------+
+| NU6.1 | 170140 | 3,146,400 |
++-------------------+------------------+-------------------+
+
+The following protocol versions are associated with network upgrades on Testnet:
+
++-------------------+------------------+-------------------+
+| Network Upgrade | Protocol Version | Activation Height |
++===================+==================+===================+
+| Sprout | 170002 | (always active) |
++-------------------+------------------+-------------------+
+| Overwinter | 170003 | 207,500 |
++-------------------+------------------+-------------------+
+| Sapling | 170007 | 280,000 |
++-------------------+------------------+-------------------+
+| Blossom | 170008 | 584,000 |
++-------------------+------------------+-------------------+
+| Heartwood | 170010 | 903,800 |
++-------------------+------------------+-------------------+
+| Canopy | 170012 | 1,028,500 |
++-------------------+------------------+-------------------+
+| NU5 | 170050 | 1,842,420 |
++-------------------+------------------+-------------------+
+| NU6 | 170110 | 2,976,000 |
++-------------------+------------------+-------------------+
+| NU6.1 | 170130 | 3,536,500 |
++-------------------+------------------+-------------------+
+
+Note that Testnet protocol versions differ from Mainnet for several upgrades
+(Overwinter, Blossom, Heartwood, Canopy, NU5, NU6, and NU6.1).
+
+
+Message Types
+-------------
+
+This section defines each protocol message. For each message, the command string,
+direction, payload format, and semantics are specified.
+
+Control Messages
+````````````````
+
+``version``
+'''''''''''
+
+:Command: ``version``
+:Direction: Both (sent by each side during handshake)
+:Payload: See `Version Message`_.
+
+Initiates the connection handshake. The details of this message are specified in
+`Connection Handshake`_.
+
+
+``verack``
+''''''''''
+
+:Command: ``verack``
+:Direction: Both
+:Payload: Empty (0 bytes).
+
+Acknowledges receipt of a ``version`` message. After exchanging ``version`` and
+``verack`` messages, the connection is considered established.
+
+
+``ping``
+''''''''
+
+:Command: ``ping``
+:Direction: Both
+:Payload:
+
+ +------+-----------+-----------------------------------+
+ | Size | Field | Description |
+ +======+===========+===================================+
+ | 8 | ``nonce`` | Random value (``uint64``). |
+ +------+-----------+-----------------------------------+
+
+Sent periodically to measure latency and detect dead connections. The zcashd
+implementation sends ``ping`` messages every 120 seconds (``PING_INTERVAL``); the Zebra
+implementation uses a 59-second heartbeat interval (``HEARTBEAT_INTERVAL``).
+The receiving node MUST respond with a ``pong`` message containing the same nonce.
+
+.. note::
+
+ Historically (BIP 31 [#bip-0031]_), ``ping`` messages had an empty payload for
+ protocol versions ≤ 60000 (``BIP0031_VERSION``). Since the minimum Zcash peer
+ protocol version is 170002 (``MIN_PEER_PROTO_VERSION``), well above this threshold,
+ all conformant Zcash peers use the nonce-bearing format. The empty-payload variant
+ will never be encountered on the Zcash network.
+
+
+``pong``
+''''''''
+
+:Command: ``pong``
+:Direction: Both
+:Payload:
+
+ +------+-----------+------------------------------------------------------+
+ | Size | Field | Description |
+ +======+===========+======================================================+
+ | 8 | ``nonce`` | The nonce from the corresponding ``ping`` message |
+ | | | (``uint64``). |
+ +------+-----------+------------------------------------------------------+
+
+Sent in response to a ``ping``. The ``nonce`` MUST match the ``nonce`` from the ``ping``
+that is being responded to.
+
+
+``reject``
+''''''''''
+
+:Command: ``reject``
+:Direction: Both
+:Payload:
+
+ +---------+-------------+---------------------------------------------------+
+ | Size | Field | Description |
+ +=========+=============+===================================================+
+ | varies | ``message`` | The command string of the rejected message |
+ | | | (CompactSize-prefixed string). |
+ +---------+-------------+---------------------------------------------------+
+ | 1 | ``ccode`` | Reject code (``uint8``). See `Reject Codes`_. |
+ +---------+-------------+---------------------------------------------------+
+ | varies | ``reason`` | Human-readable rejection reason |
+ | | | (CompactSize-prefixed string). |
+ +---------+-------------+---------------------------------------------------+
+ | 0 or 32 | ``data`` | Optional. For ``tx`` and ``block`` rejections, |
+ | | | the 32-byte hash of the rejected object. |
+ +---------+-------------+---------------------------------------------------+
+
+Notifies the peer of a rejected message. This message is informational; receipt of a
+``reject`` message does not require any specific action by the receiving node.
+
+
+``alert``
+'''''''''
+
+:Command: ``alert``
+:Direction: Both
+:Payload:
+
+ +---------+---------------+--------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+==================================================+
+ | varies | ``payload`` | Serialized alert data (CompactSize-prefixed |
+ | | | byte vector). |
+ +---------+---------------+--------------------------------------------------+
+ | varies | ``signature`` | ECDSA signature over the payload |
+ | | | (CompactSize-prefixed byte vector). |
+ +---------+---------------+--------------------------------------------------+
+
+ The serialized alert data contains:
+
+ +---------+------------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+==================+================================================+
+ | 4 | ``version`` | Alert format version (``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | 8 | ``relay_until`` | Timestamp after which nodes should stop |
+ | | | relaying (``int64``). |
+ +---------+------------------+------------------------------------------------+
+ | 8 | ``expiration`` | Timestamp after which the alert is no longer |
+ | | | in effect (``int64``). |
+ +---------+------------------+------------------------------------------------+
+ | 4 | ``id`` | Unique alert identifier (``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | 4 | ``cancel`` | ID of a previous alert to cancel (``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | varies | ``set_cancel`` | Set of alert IDs to cancel |
+ | | | (CompactSize-prefixed vector of ``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | 4 | ``min_ver`` | Minimum applicable client version (``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | 4 | ``max_ver`` | Maximum applicable client version (``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | varies | ``set_sub_ver`` | Set of applicable user agent substrings |
+ | | | (CompactSize-prefixed vector of strings). |
+ +---------+------------------+------------------------------------------------+
+ | 4 | ``priority`` | Alert priority (``int32``). |
+ +---------+------------------+------------------------------------------------+
+ | varies | ``comment`` | Comment for operators (CompactSize-prefixed |
+ | | | string, max 65536 bytes). |
+ +---------+------------------+------------------------------------------------+
+ | varies | ``status_bar`` | Status bar message (CompactSize-prefixed |
+ | | | string, max 256 bytes). |
+ +---------+------------------+------------------------------------------------+
+ | varies | ``rpc_error`` | RPC error message (CompactSize-prefixed |
+ | | | string, max 256 bytes). |
+ +---------+------------------+------------------------------------------------+
+
+The ``alert`` message is deprecated. It is documented here for completeness, as it
+remains part of the zcashd implementation but has been proposed for removal
+[#zcashd-remove-alert]_, and implementations MAY choose not to
+support it. Nodes that do support ``alert`` messages SHOULD validate the alert
+signature against the network's alert public key before processing or relaying alerts.
+
+
+Address Messages
+````````````````
+
+``addr``
+''''''''
+
+:Command: ``addr``
+:Direction: Both
+:Payload:
+
+ +---------+---------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+================================================+
+ | varies | ``count`` | Number of addresses (CompactSize). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``addr_list`` | List of ``CAddress`` entries (with ``time`` |
+ | | | field). |
+ +---------+---------------+------------------------------------------------+
+
+The ``count`` MUST NOT exceed 1000. A node receiving an ``addr`` message with more than
+1000 entries SHOULD assign a misbehavior penalty of 20 points to the sending peer.
+
+
+``getaddr``
+'''''''''''
+
+:Command: ``getaddr``
+:Direction: Both (but typically only sent to inbound peers)
+:Payload: Empty (0 bytes).
+
+Requests peer addresses from the remote node. The remote node responds by sending one or
+more ``addr`` messages. A node SHOULD only send ``getaddr`` once per connection, and
+SHOULD only process ``getaddr`` from inbound peers to prevent address-based fingerprinting
+attacks.
+
+
+``addrv2``
+''''''''''
+
+:Command: ``addrv2``
+:Direction: Both
+:Payload:
+
+ +---------+---------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+================================================+
+ | varies | ``count`` | Number of addresses (CompactSize). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``addr_list`` | List of address entries in ``addrv2`` format |
+ | | | (see below). |
+ +---------+---------------+------------------------------------------------+
+
+Each address entry has the following format:
+
+ +---------+---------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+================================================+
+ | 4 | ``time`` | Unix-epoch UTC time in seconds when the node |
+ | | | was last seen (``uint32``, little-endian). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``services`` | Service bits (CompactSize-encoded ``uint64``). |
+ +---------+---------------+------------------------------------------------+
+ | 1 | ``networkID`` | Network identifier (``uint8``). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``sizeAddr`` | Length of ``addr`` in bytes (CompactSize). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``addr`` | Network address (``sizeAddr`` bytes). |
+ | | | Interpretation depends on ``networkID``. |
+ +---------+---------------+------------------------------------------------+
+ | 2 | ``port`` | Network port (``uint16``, big-endian). MUST |
+ | | | be 0 if not relevant for the network. |
+ +---------+---------------+------------------------------------------------+
+
+The ``count`` MUST NOT exceed 1000. A node MUST reject messages with more than 1000
+addresses.
+
+The ``addr`` field MUST NOT exceed 512 bytes. A node MUST reject messages with a longer
+``addr`` field, irrespective of the network ID.
+
+The ``services`` field is encoded as a CompactSize, unlike the fixed 8-byte ``uint64``
+encoding used in ``addr`` messages. This makes the common case (few service bits) more
+compact.
+
+The following network IDs are defined:
+
+ +------------+-------------+--------------+-------------------------------------+
+ | Network ID | Name | Address Size | Description |
+ +============+=============+==============+=====================================+
+ | ``0x01`` | ``IPV4`` | 4 bytes | IPv4 address. |
+ +------------+-------------+--------------+-------------------------------------+
+ | ``0x02`` | ``IPV6`` | 16 bytes | IPv6 address. |
+ +------------+-------------+--------------+-------------------------------------+
+ | ``0x04`` | ``TORV3`` | 32 bytes | Tor v3 onion service address |
+ | | | | (Ed25519 public key). |
+ +------------+-------------+--------------+-------------------------------------+
+ | ``0x05`` | ``I2P`` | 32 bytes | I2P overlay network address |
+ | | | | (SHA-256 hash). |
+ +------------+-------------+--------------+-------------------------------------+
+ | ``0x06`` | ``CJDNS`` | 16 bytes | Cjdns overlay network address |
+ | | | | (IPv6 in ``fc00::/8``). |
+ +------------+-------------+--------------+-------------------------------------+
+
+Network ID ``0x03`` is reserved (it was assigned to Tor v2 in BIP 155 [#bip-0155]_, but
+Tor v2 addresses are no longer supported and MUST NOT be used).
+
+A node MUST reject addresses whose length does not match the expected length for the
+given network ID. A node MUST NOT gossip addresses with unrecognized network IDs.
+
+``IPV4`` and ``IPV6`` addresses are encoded in network byte order (big-endian). ``TORV3``
+addresses consist of the 32-byte Ed25519 master public key of the onion service.
+``I2P`` addresses consist of the decoded 32-byte SHA-256 hash. ``CJDNS`` addresses are
+16-byte IPv6 addresses in the ``fc00::/8`` range, encoded in network byte order.
+
+**Deployment:** Unlike BIP 155 [#bip-0155]_, which uses a ``sendaddrv2`` handshake
+message, Zcash signals ``addrv2`` support through protocol version negotiation, as
+specified in ZIP 155 [#zip-0155]_. The deployment version has not yet been assigned;
+see ZIP 155 for the status of this assignment.
+A node MUST NOT send ``addrv2`` messages on connections where the negotiated protocol
+version is below the deployment threshold. A node that supports ``addrv2`` MAY still
+send ``addr`` messages on any connection.
+
+The full specification of the ``addrv2`` message, including network address encoding
+details, is given in ZIP 155 [#zip-0155]_.
+
+
+Inventory Messages
+``````````````````
+
+``inv``
+'''''''
+
+:Command: ``inv``
+:Direction: Both
+:Payload:
+
+ +---------+---------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+================================================+
+ | varies | ``count`` | Number of inventory vectors (CompactSize). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``inventory`` | List of inventory vectors (see |
+ | | | `Inventory Vectors`_). |
+ +---------+---------------+------------------------------------------------+
+
+Announces one or more objects (transactions or blocks) that the sender has available.
+The ``count`` MUST NOT exceed 50,000. A node receiving an ``inv`` message with more than
+50,000 entries SHOULD assign a misbehavior penalty of 20 points.
+
+
+``getdata``
+'''''''''''
+
+:Command: ``getdata``
+:Direction: Both
+:Payload:
+
+ +---------+---------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+================================================+
+ | varies | ``count`` | Number of inventory vectors (CompactSize). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``inventory`` | List of inventory vectors (see |
+ | | | `Inventory Vectors`_). |
+ +---------+---------------+------------------------------------------------+
+
+Requests one or more objects from the remote peer. The ``count`` MUST NOT exceed 50,000.
+A node receiving a ``getdata`` message with more than 50,000 entries MUST assign a
+misbehavior penalty of 20 points.
+
+If the requested object is not available, the receiving node SHOULD respond with a
+``notfound`` message.
+
+
+``notfound``
+''''''''''''
+
+:Command: ``notfound``
+:Direction: Both
+:Payload:
+
+ +---------+---------------+------------------------------------------------+
+ | Size | Field | Description |
+ +=========+===============+================================================+
+ | varies | ``count`` | Number of inventory vectors (CompactSize). |
+ +---------+---------------+------------------------------------------------+
+ | varies | ``inventory`` | List of inventory vectors identifying objects |
+ | | | not found. |
+ +---------+---------------+------------------------------------------------+
+
+Sent in response to a ``getdata`` message for objects that the node does not have.
+
+
+Block Messages
+``````````````
+
+``getblocks``
+'''''''''''''
+
+:Command: ``getblocks``
+:Direction: Both
+:Payload:
+
+ +---------+---------------------------+------------------------------------------+
+ | Size | Field | Description |
+ +=========+===========================+==========================================+
+ | 4 | ``version`` | Protocol version (``uint32``). |
+ +---------+---------------------------+------------------------------------------+
+ | varies | ``block_locator_count`` | Number of block locator hashes |
+ | | | (CompactSize). |
+ +---------+---------------------------+------------------------------------------+
+ | varies | ``block_locator_hashes`` | Block locator hashes (each 32 bytes), |
+ | | | from highest to lowest height. |
+ +---------+---------------------------+------------------------------------------+
+ | 32 | ``hash_stop`` | Hash of the last desired block, or all |
+ | | | zeros to request as many as possible. |
+ +---------+---------------------------+------------------------------------------+
+
+Requests an ``inv`` message containing block hashes starting after the first block
+locator hash found in the responder's best chain, up to and including ``hash_stop`` or
+500 blocks, whichever comes first. A node MUST NOT return more than 500 blocks.
+
+
+``getheaders``
+''''''''''''''
+
+:Command: ``getheaders``
+:Direction: Both
+:Payload:
+
+ +---------+---------------------------+------------------------------------------+
+ | Size | Field | Description |
+ +=========+===========================+==========================================+
+ | 4 | ``version`` | Protocol version (``uint32``). |
+ +---------+---------------------------+------------------------------------------+
+ | varies | ``block_locator_count`` | Number of block locator hashes |
+ | | | (CompactSize). |
+ +---------+---------------------------+------------------------------------------+
+ | varies | ``block_locator_hashes`` | Block locator hashes (each 32 bytes), |
+ | | | from highest to lowest height. |
+ +---------+---------------------------+------------------------------------------+
+ | 32 | ``hash_stop`` | Hash of the last desired header, or all |
+ | | | zeros to request as many as possible. |
+ +---------+---------------------------+------------------------------------------+
+
+Requests a ``headers`` message containing block headers starting after the first
+block locator hash found in the responder's best chain, up to and including
+``hash_stop`` or 160 headers, whichever comes first. A node MUST NOT return more than
+160 headers (``MAX_HEADERS_RESULTS``).
+
+
+``headers``
+'''''''''''
+
+:Command: ``headers``
+:Direction: Both
+:Payload:
+
+ +---------+-------------+---------------------------------------------------+
+ | Size | Field | Description |
+ +=========+=============+===================================================+
+ | varies | ``count`` | Number of headers (CompactSize). |
+ +---------+-------------+---------------------------------------------------+
+ | varies | ``headers`` | Block headers. Each header is followed by a |
+ | | | transaction count field (CompactSize, always 0 in |
+ | | | ``headers`` messages). |
+ +---------+-------------+---------------------------------------------------+
+
+The ``count`` MUST NOT exceed 160. The headers MUST form a contiguous chain
+(each header's ``hashPrevBlock`` must match the hash of the preceding header). A
+node receiving non-contiguous headers SHOULD assign a misbehavior penalty of 20 points.
+
+For the encoding of block headers, see the Zcash Protocol Specification
+[#protocol-blockheader]_.
+
+
+``block``
+'''''''''
+
+:Command: ``block``
+:Direction: Both
+:Payload: A single serialized block.
+
+Sent in response to a ``getdata`` request for a ``MSG_BLOCK`` inventory entry. For the
+encoding of blocks, see the Zcash Protocol Specification [#protocol-blockencoding]_.
+
+
+Transaction Messages
+````````````````````
+
+``tx``
+''''''
+
+:Command: ``tx``
+:Direction: Both
+:Payload: A single serialized transaction.
+
+Sent in response to a ``getdata`` request for a ``MSG_TX`` or ``MSG_WTX`` inventory
+entry. For the encoding of transactions, see the Zcash Protocol Specification
+[#protocol-txnencoding]_.
+
+
+Bloom Filter Messages
+`````````````````````
+
+These messages implement BIP 37 [#bip-0037]_ Bloom filtering. As of protocol
+version 170004, a node MUST NOT send Bloom filter commands to a peer that does
+not advertise ``NODE_BLOOM`` in its service flags. Sending Bloom filter
+commands to a peer that does not advertise ``NODE_BLOOM`` SHOULD incur a
+misbehavior penalty of 100 points (immediate ban).
+
+``filterload``
+''''''''''''''
+
+:Command: ``filterload``
+:Direction: Both
+:Payload: A serialized Bloom filter, as defined in BIP 37 [#bip-0037]_.
+
+Sets a Bloom filter on the connection. After a filter is set, the peer will only relay
+transactions that match the filter.
+
+
+``filteradd``
+'''''''''''''
+
+:Command: ``filteradd``
+:Direction: Both
+:Payload:
+
+ +---------+----------+------------------------------------------------------+
+ | Size | Field | Description |
+ +=========+==========+======================================================+
+ | varies | ``data`` | Element to add to the Bloom filter |
+ | | | (CompactSize-prefixed, max 520 bytes). |
+ +---------+----------+------------------------------------------------------+
+
+Adds an element to the existing Bloom filter. The data MUST NOT exceed 520 bytes. A node
+receiving data exceeding 520 bytes SHOULD assign a misbehavior penalty of 100 points.
+
+
+``filterclear``
+'''''''''''''''
+
+:Command: ``filterclear``
+:Direction: Both
+:Payload: Empty (0 bytes).
+
+Removes the Bloom filter from the connection. Transaction relay resumes normally.
+
+
+Memory Pool
+```````````
+
+``mempool``
+'''''''''''
+
+:Command: ``mempool``
+:Direction: Both
+:Payload: Empty (0 bytes).
+
+Requests the contents of the peer's transaction memory pool. The peer responds by sending
+one or more ``inv`` messages listing the transactions in its mempool.
+
+
+Block Relay
+-----------
+
+Headers-First Synchronization
+`````````````````````````````
+
+Nodes MAY synchronize the block chain using a headers-first approach. The Zebra
+implementation uses headers-first synchronization; zcashd does not [#zcashd-6292]_.
+
+1. The synchronizing node sends a ``getheaders`` message with a block locator.
+2. The remote peer responds with a ``headers`` message containing up to 160 headers.
+3. The synchronizing node validates the headers and requests full blocks via ``getdata``
+ with ``MSG_BLOCK`` inventory entries.
+4. Steps 1–3 repeat until the node is synchronized with the network.
+
+Block Download Parameters
+`````````````````````````
+
+- **Download window:** A node SHOULD NOT request blocks more than 1024 blocks ahead
+ of its current validated tip (``BLOCK_DOWNLOAD_WINDOW``).
+- **Per-peer limit:** A node SHOULD NOT have more than 16 blocks in transit from a
+ single peer simultaneously (``MAX_BLOCKS_IN_TRANSIT_PER_PEER``).
+- **Stalling timeout:** If a peer has not delivered a requested block within 2 seconds
+ (``BLOCK_STALLING_TIMEOUT``) and there are other peers available with the same
+ block, the node MAY request the block from an alternative peer.
+- **Maximum headers per response:** 160 (``MAX_HEADERS_RESULTS``).
+
+Block Announcement
+``````````````````
+
+Blocks are announced immediately via ``inv`` messages; they are not subject to the
+trickling delay applied to transactions.
+
+
+Transaction Relay
+-----------------
+
+Inventory-Based Relay
+`````````````````````
+
+Transaction relay follows an inventory-based protocol:
+
+1. A node with a new transaction sends an ``inv`` message to its peers.
+2. Peers that want the transaction respond with a ``getdata`` message.
+3. The originating node sends the transaction in a ``tx`` message.
+
+Transactions with version ≤ 4 MUST be announced using ``MSG_TX`` inventory vectors.
+Transactions with version ≥ 5 MUST be announced using ``MSG_WTX`` inventory vectors.
+Using the wrong inventory type for a transaction version SHOULD incur a misbehavior
+penalty. See ZIP 239 [#zip-0239]_.
+
+Trickling
+`````````
+
+To impede network topology inference, transaction inventory SHOULD NOT be sent
+immediately but SHOULD instead be "trickled" at random intervals. The specific
+trickling parameters are implementation-defined. The zcashd implementation uses the
+following values:
+
+- The average broadcast interval is 5 seconds (``INVENTORY_BROADCAST_INTERVAL``).
+- For outbound peers, the effective interval in seconds is halved rounding down
+ (2 seconds on average).
+- At most 35 inventory entries (``INVENTORY_BROADCAST_MAX``) are sent per trickle
+ interval.
+- Broadcast times follow a Poisson distribution centered on the broadcast interval.
+
+The Zebra implementation uses a 7-second gossip delay (``PEER_GOSSIP_DELAY``).
+
+Transaction Expiry
+``````````````````
+
+A node SHOULD NOT relay a transaction that will expire within 3 blocks of its view of
+the current chain tip (``TX_EXPIRING_SOON_THRESHOLD``).
+
+Orphan Transactions
+```````````````````
+
+An orphan transaction is one that references inputs from unknown parent transactions.
+
+- A node SHOULD store at most 100 orphan transactions
+ (``DEFAULT_MAX_ORPHAN_TRANSACTIONS``).
+- Orphan transactions expire and are removed after 1200 seconds (20 minutes,
+ ``ORPHAN_TX_EXPIRE_TIME``).
+- Only fully transparent transactions are eligible for orphan storage.
+- When the orphan pool is full, the oldest orphan transactions are evicted.
+
+Relay Fee
+`````````
+
+Transactions are subject to a minimum relay fee. Both the zcashd and Zebra
+implementations use a base rate of 100 zatoshis per 1000 bytes
+(``DEFAULT_MIN_RELAY_TX_FEE``), though the zcashd implementation applies additional
+logic for low-fee and free transactions [#zcashd-relay-fee]_. A node SHOULD NOT relay
+transactions with fees below its minimum relay fee threshold.
+
+
+Address Relay
+-------------
+
+Address relay allows nodes to discover peers by propagating ``CAddress`` records through
+the network.
+
+Rate Limiting
+`````````````
+
+Address records SHOULD be subject to rate limiting to prevent address flooding. The
+specific rate-limiting mechanism is implementation-defined. The zcashd-specific
+rate-limiting mechanism uses a token-bucket algorithm:
+
+- Rate: 0.1 address records per second per peer (``MAX_ADDR_RATE_PER_SECOND``).
+- Bucket capacity: 1000 (``MAX_ADDR_PROCESSING_TOKEN_BUCKET``), replenished at 0.1
+ tokens per second.
+- Upon receiving a ``getaddr`` response, 1000 tokens (``MAX_ADDR_TO_SEND``) are added
+ to the bucket, exempt from the soft limit.
+- Whitelisted peers bypass address rate limiting.
+
+Address Broadcasting
+````````````````````
+
+The specific broadcast intervals are implementation-defined. The zcashd implementation
+uses the following values:
+
+- Addresses are broadcast to peers at an average interval of 30 seconds
+ (``AVG_ADDRESS_BROADCAST_INTERVAL``).
+- A node's own address is broadcast approximately every 9.6 hours
+ (``AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60 = 34560`` seconds).
+
+
+Misbehavior and Banning
+-----------------------
+
+Nodes SHOULD track misbehavior scores for each connected peer. The zcashd
+implementation bans a peer when its cumulative score reaches or exceeds 100
+(``DEFAULT_BANSCORE_THRESHOLD``), with bans lasting 24 hours
+(``DEFAULT_MISBEHAVING_BANTIME``). The Zebra implementation also uses a threshold of
+100 (``MAX_PEER_MISBEHAVIOR_SCORE``) but bans persist indefinitely. The ban threshold
+and duration are implementation-defined.
+
+Whitelisted peers accumulate misbehavior scores but are exempt from banning.
+
+The following table lists the misbehavior penalties assigned for specific protocol
+violations:
+
++--------+-------------------------------------------------------------------+
+| Points | Violation |
++========+===================================================================+
+| 1 | Duplicate ``version`` message. |
++--------+-------------------------------------------------------------------+
+| 1 | Message received before ``version`` handshake. |
++--------+-------------------------------------------------------------------+
+| 1 | Duplicate ``verack`` message. |
++--------+-------------------------------------------------------------------+
+| 10 | Alert processing failure. |
++--------+-------------------------------------------------------------------+
+| 20 | ``addr`` message with more than 1000 entries. |
++--------+-------------------------------------------------------------------+
+| 20 | ``inv`` message with more than 50,000 entries. |
++--------+-------------------------------------------------------------------+
+| 20 | ``getdata`` message with more than 50,000 entries. |
++--------+-------------------------------------------------------------------+
+| 20 | ``headers`` message with more than 160 entries. |
++--------+-------------------------------------------------------------------+
+| 20 | Non-contiguous headers sequence. |
++--------+-------------------------------------------------------------------+
+| 50 | Causing send buffer overflow. |
++--------+-------------------------------------------------------------------+
+| 100 | Bloom filter commands without ``NODE_BLOOM`` support. |
++--------+-------------------------------------------------------------------+
+| 100 | Invalid Bloom filter parameters. |
++--------+-------------------------------------------------------------------+
+| 100 | ``filteradd`` data exceeding 520 bytes. |
++--------+-------------------------------------------------------------------+
+| 100 | Using ``MSG_TX`` to announce a v5 transaction, or ``MSG_WTX`` |
+| | to announce a v4-or-earlier transaction (see ZIP 239 |
+| | [#zip-0239]_). |
++--------+-------------------------------------------------------------------+
+| varies | Transaction, block, or header validation failure. The penalty is |
+| | determined by the severity of the validation error. |
++--------+-------------------------------------------------------------------+
+
+
+Network Upgrade Peer Management
+-------------------------------
+
+Network upgrade peer management is specified in ZIP 201 [#zip-0201]_. This section
+summarizes the key behaviors.
+
+Pre-Activation
+``````````````
+
+In the 1728-block window (``NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD``) before a
+network upgrade activation height, a node SHOULD preferentially connect to peers that
+advertise a protocol version at or above the version required by the upcoming upgrade.
+This period corresponds to approximately 1.5 days at the post-Blossom block interval.
+
+Post-Activation
+```````````````
+
+After a network upgrade activates, a node MUST disconnect any peer whose negotiated
+protocol version is below the version required by the active epoch. The node SHOULD send
+a ``reject`` message with code ``REJECT_OBSOLETE`` (``0x11``) before disconnecting.
+
+
+Reject Codes
+=============
+
++----------+----------------------------+-----------------------------------------------+
+| Code | Constant | Description |
++==========+============================+===============================================+
+| ``0x01`` | ``REJECT_MALFORMED`` | The message could not be decoded. |
++----------+----------------------------+-----------------------------------------------+
+| ``0x10`` | ``REJECT_INVALID`` | The message was invalid (e.g., a block or |
+| | | transaction that fails validation). |
++----------+----------------------------+-----------------------------------------------+
+| ``0x11`` | ``REJECT_OBSOLETE`` | The message uses an obsolete protocol |
+| | | version. |
++----------+----------------------------+-----------------------------------------------+
+| ``0x12`` | ``REJECT_DUPLICATE`` | The message is a duplicate of one already |
+| | | received. |
++----------+----------------------------+-----------------------------------------------+
+| ``0x40`` | ``REJECT_NONSTANDARD`` | The transaction is valid but not standard. |
++----------+----------------------------+-----------------------------------------------+
+| ``0x41`` | ``REJECT_DUST`` | One or more transaction outputs are below |
+| | | the dust threshold. |
++----------+----------------------------+-----------------------------------------------+
+| ``0x42`` | ``REJECT_INSUFFICIENTFEE`` | The transaction fee is insufficient. |
++----------+----------------------------+-----------------------------------------------+
+| ``0x43`` | ``REJECT_CHECKPOINT`` | The block conflicts with a checkpoint. |
++----------+----------------------------+-----------------------------------------------+
+
+
+References
+==========
+
+.. [#BCP14] `Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" `_
+.. [#rfc4291] `RFC 4291: IP Version 6 Addressing Architecture, Section 2.5.5.2 `_
+.. [#protocol-networks] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet `_
+.. [#protocol-blockchain] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.3: The Block Chain `_
+.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1: Transaction Encoding and Consensus `_
+.. [#protocol-blockencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.6: Block Encoding `_
+.. [#protocol-blockheader] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.5: Block Header Encoding `_
+.. [#zip-0155] `ZIP 155: addrv2 message `_
+.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_
+.. [#zip-0201] `ZIP 201: Network Peer Management for Overwinter `_
+.. [#zip-0225] `ZIP 225: Version 5 Transaction Format `_
+.. [#zip-0239] `ZIP 239: Relay of Version 5 Transactions `_
+.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_
+.. [#bip-0031] `BIP 31: Pong Message `_
+.. [#bip-0037] `BIP 37: Connection Bloom filtering `_
+.. [#bip-0111] `BIP 111: NODE_BLOOM service bit `_
+.. [#bip-0130] `BIP 130: sendheaders message `_
+.. [#bip-0155] `BIP 155: addrv2 message `_
+.. [#zcashd-6292] `zcashd issue 6292: zcashd does not use headers-first sync `_
+.. [#zcashd-relay-fee] `zcashd relay fee policy (policy.h) `_
+.. [#zcashd-remove-alert] `zcashd PR 7039: Remove alert handling `_
+.. [#bitcoin-protocol] `Bitcoin Developer Reference: P2P Network `_
diff --git a/zips/zip-0205.rst b/zips/zip-0205.rst
index 963959a8a..7fb1a22c7 100644
--- a/zips/zip-0205.rst
+++ b/zips/zip-0205.rst
@@ -2,7 +2,7 @@
ZIP: 205
Title: Deployment of the Sapling Network Upgrade
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Credits: Simon Liu
Status: Final
Category: Consensus / Network
diff --git a/zips/zip-0206.rst b/zips/zip-0206.rst
index 16d61138b..fb76fa93b 100644
--- a/zips/zip-0206.rst
+++ b/zips/zip-0206.rst
@@ -2,7 +2,7 @@
ZIP: 206
Title: Deployment of the Blossom Network Upgrade
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Credits: Simon Liu
Status: Final
Category: Consensus / Network
diff --git a/zips/zip-0207.rst b/zips/zip-0207.rst
index 0cd2d0ecb..4f8ec0539 100644
--- a/zips/zip-0207.rst
+++ b/zips/zip-0207.rst
@@ -2,8 +2,8 @@
ZIP: 207
Title: Funding Streams
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Status: [Revision 0: Canopy, Revision 1: NU6] Final
Category: Consensus
Created: 2019-01-04
diff --git a/zips/zip-0208.rst b/zips/zip-0208.rst
index bfd02e4e9..c81865370 100644
--- a/zips/zip-0208.rst
+++ b/zips/zip-0208.rst
@@ -2,9 +2,8 @@
ZIP: 208
Title: Shorter Block Target Spacing
- Owners: Daira-Emma Hopwood
- Original-Authors: Daira-Emma Hopwood
- Simon Liu
+ Owners: Daira-Emma Hopwood
+ Original-Authors: Simon Liu
Status: Final
Category: Consensus
Created: 2019-01-10
diff --git a/zips/zip-0209.rst b/zips/zip-0209.rst
index ffb35f6fd..17aa3ab5d 100644
--- a/zips/zip-0209.rst
+++ b/zips/zip-0209.rst
@@ -2,8 +2,8 @@
ZIP: 209
Title: Prohibit Negative Shielded Chain Value Pool Balances
- Owners: Sean Bowe
- Daira-Emma Hopwood
+ Owners: Sean Bowe
+ Daira-Emma Hopwood
Status: Final
Category: Consensus
Created: 2019-02-25
diff --git a/zips/zip-0210.rst b/zips/zip-0210.rst
index bee141a97..a069f4adf 100644
--- a/zips/zip-0210.rst
+++ b/zips/zip-0210.rst
@@ -2,7 +2,7 @@
ZIP: 210
Title: Sapling Anchor Deduplication within Transactions
- Owners: Jack Grigg
+ Owners: Jack Grigg
Status: Withdrawn
Category: Consensus
Created: 2019-03-27
diff --git a/zips/zip-0211.rst b/zips/zip-0211.rst
index f857af188..ceef694fa 100644
--- a/zips/zip-0211.rst
+++ b/zips/zip-0211.rst
@@ -2,7 +2,7 @@
ZIP: 211
Title: Disabling Addition of New Value to the Sprout Chain Value Pool
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Credits: Sean Bowe
Status: Final
Category: Consensus
diff --git a/zips/zip-0212.rst b/zips/zip-0212.rst
index 271634e68..fb292d3a2 100644
--- a/zips/zip-0212.rst
+++ b/zips/zip-0212.rst
@@ -2,7 +2,8 @@
ZIP: 212
Title: Allow Recipient to Derive Ephemeral Secret from Note Plaintext
- Owners: Sean Bowe
+ Owners: Sean Bowe
+ Daira-Emma Hopwood
Status: Final
Category: Consensus
Created: 2019-03-31
diff --git a/zips/zip-0214.rst b/zips/zip-0214.rst
index 201f72fb5..ebe89aa23 100644
--- a/zips/zip-0214.rst
+++ b/zips/zip-0214.rst
@@ -2,7 +2,7 @@
ZIP: 214
Title: Consensus rules for a Zcash Development Fund
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Kris Nuttycombe
Status: [Revision 0: Canopy, Revision 1: NU6] Final, [Revision 2: NU6.1] Proposed
Category: Consensus
diff --git a/zips/zip-0216.rst b/zips/zip-0216.rst
index f0c5b18c1..0f62bd065 100644
--- a/zips/zip-0216.rst
+++ b/zips/zip-0216.rst
@@ -2,8 +2,8 @@
ZIP: 216
Title: Require Canonical Jubjub Point Encodings
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Status: Final
Category: Consensus
Created: 2021-02-11
diff --git a/zips/zip-0217.rst b/zips/zip-0217.rst
index 4562d86fc..69b1aaa36 100644
--- a/zips/zip-0217.rst
+++ b/zips/zip-0217.rst
@@ -2,7 +2,7 @@
ZIP: 217
Title: Aggregate Signatures
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Status: Reserved
Category: Consensus
Discussions-To:
diff --git a/zips/zip-0219.rst b/zips/zip-0219.rst
index 313032e95..931e90639 100644
--- a/zips/zip-0219.rst
+++ b/zips/zip-0219.rst
@@ -2,7 +2,7 @@
ZIP: 219
Title: Disabling Addition of New Value to the Sapling Chain Value Pool
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Status: Reserved
Category: Consensus
Discussions-To:
diff --git a/zips/zip-0220.rst b/zips/zip-0220.rst
index 5b9b8ee00..5ea14b140 100644
--- a/zips/zip-0220.rst
+++ b/zips/zip-0220.rst
@@ -2,8 +2,8 @@
ZIP: 220
Title: Zcash Shielded Assets
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Status: Withdrawn
Category: Consensus
Discussions-To:
diff --git a/zips/zip-0221.rst b/zips/zip-0221.rst
index ab8d61a38..4ee35acce 100644
--- a/zips/zip-0221.rst
+++ b/zips/zip-0221.rst
@@ -2,7 +2,7 @@
ZIP: 221
Title: FlyClient - Consensus-Layer Changes
- Owners: Jack Grigg
+ Owners: Jack Grigg
Original-Authors: Ying Tong Lai
James Prestwich
Georgios Konstantopoulos
diff --git a/zips/zip-0222.rst b/zips/zip-0222.rst
index 440ec86e0..54648716a 100644
--- a/zips/zip-0222.rst
+++ b/zips/zip-0222.rst
@@ -2,8 +2,8 @@
ZIP: 222
Title: Transparent Zcash Extensions
- Owners: Jack Grigg
- Kris Nuttycombe
+ Owners: Jack Grigg
+ Kris Nuttycombe
Credits: Zaki Manian
Daira-Emma Hopwood
Sean Bowe
diff --git a/zips/zip-0224.rst b/zips/zip-0224.rst
index 450b8118a..cbede7687 100644
--- a/zips/zip-0224.rst
+++ b/zips/zip-0224.rst
@@ -2,10 +2,10 @@
ZIP: 224
Title: Orchard Shielded Protocol
- Owners: Daira-Emma Hopwood
- Jack Grigg
- Sean Bowe
- Kris Nuttycombe
+ Owners: Daira-Emma Hopwood
+ Jack Grigg
+ Sean Bowe
+ Kris Nuttycombe
Original-Authors: Ying Tong Lai
Status: Final
Category: Consensus
diff --git a/zips/zip-0225.rst b/zips/zip-0225.rst
index 65f69bb42..e6b4cfb2a 100644
--- a/zips/zip-0225.rst
+++ b/zips/zip-0225.rst
@@ -2,10 +2,10 @@
ZIP: 225
Title: Version 5 Transaction Format
- Owners: Daira-Emma Hopwood
- Jack Grigg
- Sean Bowe
- Kris Nuttycombe
+ Owners: Daira-Emma Hopwood
+ Jack Grigg
+ Sean Bowe
+ Kris Nuttycombe
Original-Authors: Ying Tong Lai
Status: Final
Category: Consensus
diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst
index b2d3bf953..4b42c0057 100644
--- a/zips/zip-0226.rst
+++ b/zips/zip-0226.rst
@@ -4,8 +4,8 @@
Title: Transfer and Burn of Zcash Shielded Assets
Owners: Pablo Kogan
Vivek Arte
- Daira-Emma Hopwood
- Jack Grigg
+ Daira-Emma Hopwood
+ Jack Grigg
Credits: Daniel Benarroch
Aurelien Nicolas
Deirdre Connolly
@@ -207,6 +207,7 @@ Note that the OrchardZSA Protocol does not allow for the burning of the Native A
In the `OrchardZSA Transaction Structure`_, there is now an $\mathsf{assetBurn}$ set.
For every Custom Asset (represented by its $\mathsf{AssetBase}$) that is burnt in the transaction, the sender adds to $\mathsf{assetBurn}$ the tuple $(\mathsf{AssetBase}, \mathsf{v})$, where $\mathsf{v}$ is the amount of the Custom Asset the sender wants to burn.
+We define a constant $\mathsf{MAX\_BURN\_VALUE} := 2^{63} - 1$, which denotes the maximum amount of a given Custom Asset that can be burnt in a transaction.
We denote by $L$ the cardinality of the $\mathsf{assetBurn}$ set in a transaction.
As described in `Value Balance Verification`_, this provides the information for the validator of the transaction to compute the value commitment with the corresponding Asset Base.
@@ -216,7 +217,7 @@ Additional Consensus Rules for the assetBurn set
````````````````````````````````````````````````
1. It MUST be the case that for every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}$. That is, the Native Asset is not allowed to be burnt by this mechanism.
-2. It MUST be that for every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0$.
+2. It MUST be that for every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} > 0$ and $\mathsf{v} \leq \mathsf{MAX\_BURN\_VALUE}$.
3. There MUST be no duplication of Custom Assets in the $\mathsf{assetBurn}$ set. That is, every $\mathsf{AssetBase}$ has at most one entry in $\mathsf{assetBurn}$.
The other consensus rule changes for the OrchardZSA protocol are specified in ZIP 227 [#zip-0227-consensus]_.
@@ -224,6 +225,12 @@ The other consensus rule changes for the OrchardZSA protocol are specified in ZI
**Note:** The transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure.
This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets.
+Rationale for MAX_BURN_VALUE
+````````````````````````````
+
+The maximum amount of any Custom Asset allowed to be burnt in a transaction is set to $\mathsf{MAX\_BURN\_VALUE}$ in order to prevent it from being incompatible with other valueBalance fields, which are signed 64-bit integers.
+It will also allow for compatibility with future Custom-asset-specific value balances in subsequent pools that support transferring ZSAs from the Orchard pool via a turnstile.
+
Value Balance Verification
--------------------------
diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst
index 7a58b4e3f..51841ad6d 100644
--- a/zips/zip-0227.rst
+++ b/zips/zip-0227.rst
@@ -4,8 +4,8 @@
Title: Issuance of Zcash Shielded Assets
Owners: Pablo Kogan
Vivek Arte
- Daira-Emma Hopwood
- Jack Grigg
+ Daira-Emma Hopwood
+ Jack Grigg
Credits: Daniel Benarroch
Aurelien Nicolas
Deirdre Connolly
diff --git a/zips/zip-0228.rst b/zips/zip-0228.rst
index c1c19c70e..b43648fe4 100644
--- a/zips/zip-0228.rst
+++ b/zips/zip-0228.rst
@@ -4,8 +4,8 @@
Title: Asset Swaps for Zcash Shielded Assets
Owners: Pablo Kogan
Vivek Arte
- Daira-Emma Hopwood
- Jack Grigg
+ Daira-Emma Hopwood
+ Jack Grigg
Credits: Daniel Benarroch
Aurelien Nicolas
Status: Reserved
diff --git a/zips/zip-0230.rst b/zips/zip-0230.rst
index 42898b064..7ad1dcf3a 100644
--- a/zips/zip-0230.rst
+++ b/zips/zip-0230.rst
@@ -2,10 +2,10 @@
ZIP: 230
Title: Version 6 Transaction Format
- Owners: Daira-Emma Hopwood
- Jack Grigg
- Sean Bowe
- Kris Nuttycombe
+ Owners: Daira-Emma Hopwood
+ Jack Grigg
+ Sean Bowe
+ Kris Nuttycombe
Pablo Kogan
Vivek Arte
Original-Authors: Greg Pfeil
@@ -274,8 +274,11 @@ The OrchardZSA Action Group Description is encoded in a transaction as an instan
+-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
| 372 × ``nActionsOrchard`` |``vActionsOrchard`` |``OrchardZSAAction[nActionsOrchard]`` |A sequence of OrchardZSA Action descriptions in the Action Group. |
+-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
-| 1 |``flagsOrchard`` |``byte`` |As defined in §7.1 ‘Transaction Encoding and Consensus’ |
-| | | |[#protocol-txnencoding]_. |
+|``1`` |``flagsOrchard`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: |
+| | | | * ``enableSpendsOrchard`` |
+| | | | * ``enableOutputsOrchard`` |
+| | | | * ``enableZSAs`` |
+| | | | * The remaining bits are set to :math:`0\!`. |
+-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
| 32 |``anchorOrchard`` |``byte[32]`` |As defined in §7.1 ‘Transaction Encoding and Consensus’ |
| | | |[#protocol-txnencoding]_. |
@@ -364,10 +367,11 @@ An OrchardZSA Asset Burn description is encoded in a transaction as an instance
| | | |:math:`\mathsf{AssetBase^{Orchard}}\!`. |
+-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
| 8 |``valueBurn`` |``uint64`` |The amount being burnt. The value is checked by consensus to be |
-| | | |non-zero. |
+| | | |non-zero, and less than :math:`\mathsf{MAX\_BURN\_VALUE}` |
+| | | |[#zip-0226-burn-mechanism]_. |
+-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+
-The encodings of each of these elements are defined in ZIP 226 [#zip-0226]_.
+The encodings of each of these elements are defined in ZIP 226 [#zip-0226-burn-mechanism]_.
Transparent Sighash Information (``TransparentSighashInfo``)
------------------------------------------------------------
@@ -698,6 +702,7 @@ References
.. [#zip-0225] `ZIP 225: Version 5 Transaction Format `_
.. [#zip-0225-transaction-format] `ZIP 225: Version 5 Transaction Format. Specification: Transaction Format `_
.. [#zip-0226] `ZIP 226: Transfer and Burn of Zcash Shielded Assets `_
+.. [#zip-0226-burn-mechanism] `ZIP 226: Transfer and Burn of Zcash Shielded Assets - Burn Mechanism `_
.. [#zip-0226-orchardzsa-transaction-structure] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — OrchardZSA Transaction Structure `_
.. [#zip-0226-note-structure-and-commitment] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — Note Structure and Commitment `_
.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_
diff --git a/zips/zip-0231.md b/zips/zip-0231.md
index 909ce8a41..2f9b208f9 100644
--- a/zips/zip-0231.md
+++ b/zips/zip-0231.md
@@ -1,8 +1,8 @@
ZIP: 231
Title: Memo Bundles
- Owners: Jack Grigg
- Kris Nuttycombe
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Kris Nuttycombe
+ Daira-Emma Hopwood
Arya Solhi
Credits: Sean Bowe
Nate Wilcox
@@ -31,47 +31,75 @@ The terms "Mainnet" and "Testnet" are to be interpreted as described in
# Abstract
-Currently, the memo sent in a shielded output is limited to at most 512 bytes.
-This ZIP proposes to allow larger memos, and to enable memo data to be shared
-between multiple recipients of a transaction.
+Currently, the memo associated with a shielded output is fixed to 512 bytes of data.
+
+This ZIP proposes to decouple memo data from outputs. This will:
+* reduce the memo data of a transaction with two shielded outputs from a minimum
+ of 1024 bytes to approximately 576 bytes;
+* allow larger memos, with a proportionate increase in fees;
+* enable memo data to be shared between multiple recipients of a transaction;
+* enable memo data to be pruned from a stored transaction without impairing the
+ ability of a consensus node to validate the transaction.
# Motivation
In Zcash transaction versions v2 to v5 inclusive, each Sapling or Orchard
-shielded output contains a ciphertext comprised of a 52-byte note plaintext,
-and a corresponding 512-byte memo field. [^protocol-noteptconcept] Recipients
-can only decrypt the outputs sent to them, and thus can also only observe the
-memo fields included with the outputs they can decrypt.
-
-The shielded transaction protocol hides the sender(s) (that is, the addresses
-corresponding to the keys used to spend the input notes) from all of the
-recipients. For certain kinds of transactions, it is desirable to make one or
-more sender addresses available to one or more recipients (for example, a reply
-address). In such circumstances it is important to authenticate the sender
-addresses, to give the recipient a guarantee that the address is controlled by
-a sender of the transaction; failure to authenticate this address can enable
-phishing attacks. These Authenticated Reply Addresses require zero-knowledge
-proofs, and for the Orchard protocol these proofs are too large to fit into a
-512-byte memo field.
-
-It is also desirable, for clients with more stringent bandwidth constraints,
-to be able to transmit encrypted notes to the client without including the
-encrypted memo data. In the current light client protocol [^zip-0307], this
-is done by truncating the note ciphertext to just the part that encrypts the
-memo. However, that has the effect of truncating the authentication tag, and
-so the resulting decryption algorithm does not meet standard security notions
-for an authenticated encryption scheme. It is a goal of this proposal to
-rectify this, simplifying the security argument.
-
-Instead of the memo data, this ZIP proposes that it is possible to indicate whether
-a memo is present for the recipient. When using the light client protocol, a recipient
-need not download full transaction information if this indication tells them that they
-have not received any memo in the transaction.
-
-At present, it is not possible to transmit the same memo data to multiple
-transaction recipients without redundantly encoding that data, and sending
-memo data greater than 512 bytes requires sending multiple outputs; the
+shielded output contains a ciphertext comprised of a 52-byte note plaintext and
+corresponding 512-byte memo field, with a 16-byte authentication tag
+[^protocol-noteptconcept]. Recipients can only decrypt the outputs sent to
+them, and thus can also only observe the memo fields included with the outputs
+they can decrypt.
+
+An ordinary transaction is one that is padded to 2 inputs and 2 outputs (or 2
+Orchard actions), so as to make transfers that fully transfer a note
+indistinguishable from an ordinary transaction with change. Such a transaction
+will consume 1024 bytes of block space for memo data. An Orchard transfer that
+spends a larger number of notes will incur a memo data cost of $512 \times n$
+bytes on-chain, where $n$ is the number of notes being spent as inputs.
+Ordinarily, most of this data space is wasted, as most wallets support only a
+single 512-byte memo to be sent to the recipient of the transfer. Virtually all
+transactions with shielded components consume at least 1024 bytes of block
+space for memo data, and between half and 3/4 of that data payload is
+ordinarily waste. Adopting this ZIP will eliminate a significant source of
+chain bloat.
+
+Beyond reducing chain bloat, decoupling memos from shielded outputs allows for
+some important use cases to be served. The shielded transaction protocol always
+hides the sender(s) (that is, the addresses corresponding to the keys used to
+spend the input notes) from all of the recipients. For certain kinds of
+transactions, it is desirable to make one or more sender addresses available to
+one or more recipients (for example, a reply address). In such circumstances it
+is important to authenticate the sender address(es), to give the recipient a
+guarantee that the address is controlled by a sender of the transaction;
+failure to authenticate this address can enable phishing attacks. These
+Authenticated Reply Addresses require zero-knowledge proofs, and for the
+Orchard protocol these proofs are too large to fit into the existing 512-byte
+memo field. This ZIP makes the maximum size of memo data large enough to
+support the inclusion of such proofs.
+
+Another motivation is that it is desirable, for clients with more stringent
+bandwidth constraints, to be able to transmit encrypted notes to the client
+without including the encrypted memo data. In the current light client protocol
+[^zip-0307], this is done by truncating the note ciphertext to just the part
+that encrypts the memo. However, that has the effect of truncating the
+authentication tag, and so the resulting decryption algorithm does not meet
+standard security notions for an authenticated encryption scheme. It is a goal
+of this proposal to rectify this, simplifying the security argument.
+
+Instead of the memo data, this ZIP proposes that it is possible to indicate
+whether a memo is present for the recipient. When using the light client
+protocol, a recipient need not download full transaction information if this
+indication tells them that they have not received any memo in the transaction.
+
+In addition to reducing chain bloat by eliminating wasted memo space, this ZIP
+defines a mechanism by which validating nodes may reduce their long-term
+storage requirements by pruning memo data, without impairing their ability to
+validate the entire chain.
+
+Finally, at present, it is not possible to transmit the same memo data to
+multiple transaction recipients without redundantly encoding that data, and
+sending memo data greater than 512 bytes requires sending multiple outputs; the
problem is compounded when attempting to send more than 512 bytes to each
recipient. By separating memo data from the decryption capability for those
memos, it admits a greater variety of applications that utilize memo data,
@@ -111,6 +139,11 @@ potential distinguisher along another.
# Requirements
+- Standard Zcash shielded transactions continue to include a single 512-byte
+ memo.
+- The mechanism should be able to reproduce the existing functionality where
+ each output may include a corresponding 512 bytes of memo data that is
+ decryptable only by the recipient of that output.
- Recipients can receive memo data that is greater than 512 bytes in length.
- Multiple recipients, across any of the shielded pools, can be given the
capability to view the same memo data.
diff --git a/zips/zip-0233.md b/zips/zip-0233.md
index bca2ef1f7..af4a81eaa 100644
--- a/zips/zip-0233.md
+++ b/zips/zip-0233.md
@@ -51,10 +51,12 @@ checks.
# Abstract
This ZIP proposes the introduction of a mechanism to voluntarily remove funds
-entirely from circulation on the network. This mechanism, in combination with
-ZIP 234 [^zip-0234] and ZIP 235 [^zip-0235], comprises a long-term strategy for
-the sustainability of the network. We will refer to the combined effects of
-these three ZIPs as the “Network Sustainability Mechanism”.
+entirely from circulation on the network. The explicit intent of this removal
+is that the funds will be returned to circulation through future block subsidies,
+rather than being permanently destroyed or held in reserve for discretionary use.
+This mechanism, in combination with ZIP 234 and ZIP 235 [^zip-0235], comprises a
+long-term strategy for the sustainability of the network. We will refer to the
+combined effects of these three ZIPs as the “Network Sustainability Mechanism”.
# Motivation
@@ -66,7 +68,9 @@ design shared by Bitcoin-like systems:
circulation, the network gains the ability to create "headroom" between the
chain value and $\mathsf{MAX\_MONEY}$. This lays necessary groundwork for
extending the block subsidy system, which currently has a clear final end
- date.
+ date. The intent is that removed funds will be automatically and
+ algorithmically reissued through future block subsidies, sustaining the
+ network's long-term security budget.
2. **Benefits to ZEC Holders:** Removing funds from circulation reduces the
circulating supply of ZEC. To the extent that this potentially contributes to
an increase in the value of remaining ZEC, it can be argued to benefit network
@@ -100,8 +104,8 @@ chain value pool, and therefore from the point at which the transaction is
applied to the global chain state, $\mathsf{zip233\_amount}$ is subtracted from
the issued supply. It is unavailable for circulation on the network at least
through to the end of the block in which the transaction is mined. ZIP 234
-[^zip-0234] specifies a potential mechanism by which the funds removed from
-circulation would again become available.
+[^zip-0234] specifies the mechanism by which the funds removed from
+circulation are reissued through future block subsidies.
## Changes to ZIP 230 [^zip-0230]
diff --git a/zips/zip-0234.md b/zips/zip-0234.md
index 8dbb4cdcf..9c34e9115 100644
--- a/zips/zip-0234.md
+++ b/zips/zip-0234.md
@@ -73,6 +73,11 @@ retains the overall supply cap of `MAX_MONEY`.
# Motivation
+The current block reward halving schedule is fixed and does not provide a way
+to “recycle” funds removed from circulation via ZIP-233 into future issuance.
+Once scheduled issuance ends, the network becomes reliant on transaction fees
+for the security budget.
+
Key Objectives:
1. We want to introduce an automated mechanism that allows users of the network
@@ -87,19 +92,31 @@ Key Objectives:
the current issuance as possible.
The current Zcash economic model, inherited from Bitcoin, includes a halving
-mechanism that dictates the issuance of new coins. While this has been
-foundational, halvings can lead to abrupt changes in the rate of new coins
-being introduced to the market. Such sudden shifts can potentially disrupt the
-network's economic model, potentially impacting its security and stability.
-Furthermore, the halvings schedule is fixed and does not provide any way to
-"recycle" funds into future issuance.
-
-This new NSM-based issuance scheme solves these problems by ensuring a more
+mechanism that dictates the issuance of new coins via the mining block reward.
+Halvings have since become culturally foundational, but abrupt reductions in
+miner revenue can lead to short-term drops in mining participation, as evidenced
+by hashrate/difficulty.
+
+In Zcash, difficulty declined materially after recent halving events: following the
+2020-11-18 halving, weekly difficulty fell about 20.6% within roughly a week and was
+still about 9.1% lower around 30 days later. Following the 2024-11-23 halving,
+weekly difficulty fell about 17% within roughly a week and about 23% around 30 days
+later. [^zechub-difficulty] As difficulty adjusts in response to hashrate, these short-term
+drops are consistent with discrete subsidy cuts producing measurable reductions in mining
+participation.
+
+While Bitcoin halvings are often accompanied by bullish narratives and have
+sometimes been followed by strong price performance, Zcash has not consistently
+followed the same pattern. Thus, by smoothing out the issuance curve, we
+mitigate the risks associated with abrupt changes in issuance rates.
+
+This new NSM-based issuance scheme addresses these problems by ensuring a more
consistent and predictable rate of coin issuance, while preserving the core
-aspects of Zcash's issuance policy and the 21-million-coin cap. At the same
-time, it introduces the first mechanism to recreate and distribute ZEC that has
-been removed from circulation, as well as unclaimed transaction fees, across
-future block subsidies.
+aspects of Zcash's issuance policy and the 21-million-coin cap. Critically,
+it establishes the intended path for ZEC that has been voluntarily removed from
+circulation, as well as transaction fees that are deliberately redirected into
+the reserve: these funds are automatically and algorithmically reissued over
+future block subsidies, ensuring they benefit the network's long-term security.
# Requirements
@@ -140,7 +157,7 @@ The block height will be chosen by the following criteria:
## Issuance Calculation
-At the $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, nodes should switch from the current issuance
+At the $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, nodes MUST switch from the current issuance
calculation, to the following:
$\mathsf{BlockSubsidy}(\mathsf{height}) = \mathsf{ceiling}(\mathsf{BLOCK\_SUBSIDY\_FRACTION} \cdot \mathsf{MoneyReserveAfter}(\mathsf{height} - 1))$
@@ -154,6 +171,8 @@ All of these changes apply identically to Mainnet and Testnet.
* Using an exponential decay function satisfies **Requirements 1** and **2** above.
* We round up to the next zatoshi to satisfy **Requirement 3** above.
+* The issuance formula depends only on `MoneyReserveAfter(height - 1)` and a
+ single constant fraction, making it simple to implement, explain, and verify.
## Parameters
@@ -280,3 +299,5 @@ Circulation" [^zip-0233]).
[^zip-0233]: [ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation](zip-0233.md)
[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md)
+
+[^zechub-difficulty]: [ZecHub weekly difficulty dataset](https://raw.githubusercontent.com/ZecHub/zechub-wiki/refs/heads/main/public/data/zcash/difficulty.json)
diff --git a/zips/zip-0235.md b/zips/zip-0235.md
index 42709f412..4646e622b 100644
--- a/zips/zip-0235.md
+++ b/zips/zip-0235.md
@@ -44,9 +44,10 @@ ZIP 233. [^zip-0233]
# Abstract
This ZIP proposes to remove 60% of transaction fees from circulation, while
-the remaining 40% is directed as before, providing a deflationary effect, and
-building the groundwork for long-term support of the Zcash network via the new
-block subsidy rules proposed by ZIP 234 [^zip-0234].
+the remaining 40% is directed as before. The intent of this removal is that the
+funds will be automatically and algorithmically reissued through future block
+subsidies, rather than being permanently destroyed or held as a discretionary
+reserve.
# Motivation
@@ -63,9 +64,8 @@ of the network as described below:
1. **Network Sustainability**: This mechanism involves temporarily reducing the
supply of ZEC, similar to asset burning in Ethereum’s EIP-1559 [^eip-1559],
- but with long-term sustainability benefits, as the funds removed from
- circulation effectively boost future mining rewards, making it an attractive
- option for current and future Zcash users.
+ but with long-term sustainability benefits. Unlike a permanent burn, the
+ removed funds are intended to be reissued through future block subsidies.
2. **Incentivizing Transaction Inclusion**: By maintaining a 40% share of
transaction fees for miners, we continue incentivizing miners to prioritize
including transactions in their blocks. This helps ensure the continued
@@ -81,9 +81,9 @@ of the network as described below:
network's reputation and security.
4. **Future-Proofing the Network**: Removing a portion of transaction fees from
circulation is a forward-looking approach that prepares the Zcash network for
- future challenges and opportunities. It establishes a financial buffer that
- can be instrumental in addressing unforeseen issues and seizing strategic
- advantages as the Zcash ecosystem evolves.
+ long-term sustainability. By returning these funds to circulation through
+ future block subsidies, the network maintains a viable security budget
+ beyond the original issuance schedule.
# Requirements
diff --git a/zips/zip-0236.rst b/zips/zip-0236.rst
index c872c457d..17c10d41c 100644
--- a/zips/zip-0236.rst
+++ b/zips/zip-0236.rst
@@ -2,7 +2,7 @@
ZIP: 236
Title: Blocks should balance exactly
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Credits: Jack Grigg
Kris Nuttycombe
Status: Final
diff --git a/zips/zip-0239.rst b/zips/zip-0239.rst
index 23f18ffa4..e9dd6ca79 100644
--- a/zips/zip-0239.rst
+++ b/zips/zip-0239.rst
@@ -2,8 +2,8 @@
ZIP: 239
Title: Relay of Version 5 Transactions
- Owners: Daira-Emma Hopwood
- Jack Grigg
+ Owners: Daira-Emma Hopwood
+ Jack Grigg
Status: Final
Category: Network
Created: 2021-05-29
diff --git a/zips/zip-0243.rst b/zips/zip-0243.rst
index 47c574b07..5074c58b8 100644
--- a/zips/zip-0243.rst
+++ b/zips/zip-0243.rst
@@ -2,8 +2,8 @@
ZIP: 243
Title: Transaction Signature Validation for Sapling
- Owners: Jack Grigg
- Daira-Emma Hopwood
+ Owners: Jack Grigg
+ Daira-Emma Hopwood
Credits: Simon Liu
Status: Final
Category: Consensus
diff --git a/zips/zip-0244.rst b/zips/zip-0244.rst
index 19f5e10c3..a553f7045 100644
--- a/zips/zip-0244.rst
+++ b/zips/zip-0244.rst
@@ -2,9 +2,9 @@
ZIP: 244
Title: Transaction Identifier Non-Malleability
- Owners: Kris Nuttycombe
- Daira-Emma Hopwood
- Jack Grigg
+ Owners: Kris Nuttycombe
+ Daira-Emma Hopwood
+ Jack Grigg
Status: Final
Category: Consensus
Created: 2021-01-06
diff --git a/zips/zip-0245.rst b/zips/zip-0245.rst
index fd55a7c90..b8f5aa390 100644
--- a/zips/zip-0245.rst
+++ b/zips/zip-0245.rst
@@ -2,8 +2,8 @@
ZIP: 245
Title: Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions
- Owners: Kris Nuttycombe
- Daira-Emma Hopwood
+ Owners: Kris Nuttycombe
+ Daira-Emma Hopwood
Status: Draft
Category: Consensus
Created: 2021-01-13
diff --git a/zips/zip-0246.rst b/zips/zip-0246.rst
index c50da7521..b53fc797d 100644
--- a/zips/zip-0246.rst
+++ b/zips/zip-0246.rst
@@ -4,9 +4,9 @@
Title: Digests for the Version 6 Transaction Format
Owners: Arya
Conrado Gouvea
- Daira-Emma Hopwood
- Jack Grigg
- Kris Nuttycombe
+ Daira-Emma Hopwood
+ Jack Grigg
+ Kris Nuttycombe
Status: Draft
Category: Consensus
Created: 2025-02-12
diff --git a/zips/zip-0250.rst b/zips/zip-0250.rst
index 0c0757a8b..54d2785d3 100644
--- a/zips/zip-0250.rst
+++ b/zips/zip-0250.rst
@@ -2,7 +2,7 @@
ZIP: 250
Title: Deployment of the Heartwood Network Upgrade
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood
Status: Final
Category: Consensus / Network
Created: 2020-02-28
diff --git a/zips/zip-0251.rst b/zips/zip-0251.rst
index c906e0b69..bd0584fde 100644
--- a/zips/zip-0251.rst
+++ b/zips/zip-0251.rst
@@ -2,7 +2,7 @@
ZIP: 251
Title: Deployment of the Canopy Network Upgrade
- Owners: Daira-Emma Hopwood
+ Owners: Daira-Emma Hopwood