From 34284f8a68c6f7451d1dbd1a84ccf714bcf5c7cd Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 6 Oct 2020 19:36:14 -0300 Subject: [PATCH 01/62] create block subsidy rfc --- book/src/dev/rfcs/xxxx-block-subsidy.md | 207 ++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 book/src/dev/rfcs/xxxx-block-subsidy.md diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md new file mode 100644 index 00000000000..786a4114a5d --- /dev/null +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -0,0 +1,207 @@ +- Feature Name: Block subsidy +- Start Date: 2020-10-05 +- Design PR: [ZcashFoundation/zebra#0000](https://github.com/ZcashFoundation/zebra/pull/0000) +- Zebra Issue: [ZcashFoundation/zebra#0000](https://github.com/ZcashFoundation/zebra/issues/0000) + +# Summary +[summary]: #summary + +Block subsidy is the calculation and validation of rules defined in the Zcash protocol that apply to the coinbase transaction of all incoming blocks. The calculation of block subsidy on each block consists of amounts paid to miners and amounts paid to other participants(founders or funding stream receivers), it also specifies the receiver of these rewards. + +At any time in the blockchain history specific rules apply to the coinbase transaction. This validation rules and calculations can change at Network Upgrades. + +# Motivation +[motivation]: #motivation + +All incoming blocks must be validated with the protocol rules, there is no way to avoid this logic to be present in any Zcash protocol compatible implementation such as Zebra. + +The amount of rules, calculations, parameters, etc needed to implement the whole Block Subsidy can be overwhelming as each little piece comes together to make a whole. Zebra is in a position where we know all the rules up to the second halving so the implementation can and will be different from `zcashd` but at the end of the day all coinbase transactions will need to be validated as the protocol describes. + +This document motivation is to have a clear roadmap about what is needed, the big picture of all components and how they interact together so we can separate a very big task into smaller pieces that we believe will make the implementation easier and better. + +# Definitions +[definitions]: #definitions + +- **founders reward**: The portion of the block reward that goes into a pre defined founder address. +- **funding streams**: The portion of the block reward that goes into a pre defined funding stream address. +- **miner subsidy**: The portion of the block reward that goes into the miner of the block. +- **coinbase transaction**: The first transaction in a block where block subsidy is done. +- **NU**: Network Upgrade. + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +In Zebra the consensus related code lives in the `zebra-consensus` crate. It is natural to add the block subsidy code here. The following module is suggested to be created by this design: + +- `zebra-consensus/src/block/subsidy/subsidy.rs` + +Inside `zebra-consensus/src/block/subsidy/` the following submodules will be created: + +- `general.rs`: General block reward functions and utilities. +- `founders_reward.rs`: Specific functions related to funders reward. +- `funding_streams.rs`: Specific functions for funding streams. + +In addition to calculations the block subsidy requires constants defined in the protocol. The implementation will also create additional constants, all of them will live at: + +- `zebra-consensus/src/parameters/subsidy.rs` + +Checking functions for blocks are implemented at `zebra-consensus/src/block/check.rs` and they are called at `zebra-consensus/src/block.rs`. This follows the already existing structure for block validation in Zebra. + +It is important to note that the Genesis block, BeforeOverwinter, and Overwinter blocks are verified by the CheckpointVerifier so they are not considered in this design. The following table will show what periods are included and what is not in this proposal: + +| Height | Miner | Founder reward | Funding streams | Shielded Coinbase | +|----------------------------------------|:--------:|:--------------:|:---------------:|:------------------| +| ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | +| ~Slow Start Shift..Slow Start Interval~| ~80%~ | ~20%~ | ~0%~ | ~No~ | +| ~Slow Start Interval..Overwinter~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | +| Overwinter..Sapling | 80% | 20% | 0% | No | +| Sapling..Blossom | 80% | 20% | 0% | No | +| Blossom..Heartwood | 80% | 20% | 0% | No | +| Heartwood..Canopy | 80% | 20% | 0% | Yes | +| Canopy..Second Halving | 80% | 0% | 20% | Yes | +| ~Second Halving..~ | ~100%~ | ~0%~ | ~0%~ | ~Yes~ | + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +Given the module structure proposed above all the block subsidy calculations from the protocol must be implemented. The final goal is to do checks for each incoming block and make sure they pass the consensus rules. + +To do the calculations and checks the following constants and functions need to be introduced: + +## Constants + +- `SLOW_START_INTERVAL` +- `SLOW_START_SHIFT` +- `MAX_BLOCK_SUBSIDY` +- `PRE_BLOSSOM_POW_TARGET_SPACING` +- `POST_BLOSSOM_POW_TARGET_SPACING` +- `BLOSSOM_POW_TARGET_SPACING_RATIO` +- `PRE_BLOSSOM_HALVING_INTERVAL` +- `POST_BLOSSOM_HALVING_INTERVAL` +- `FOUNDERS_FRACTION_DIVISOR` +- `FOUNDER_ADDRESS_CHANGE_INTERVAL` +- `FOUNDERS_REWARD_ADDRESSES_MAINNET` +- `FOUNDERS_REWARD_ADDRESSES_TESTNET` + +### Funding streams parameter constants + +The design suggests to implement the parameters needed for funding streams as: + +``` +/// Funding Streams +// Todo: There is probably a better way to do this ... +pub mod fs { + + /// The funding stream receivers + pub enum Receiver { + /// Electric Coin Company + ECC, + /// ZCash Foundation + ZF, + /// Major Grants + MG, + } + + /// For the Mainnet + pub mod mainnet { + /// Denominator + pub const DENOMINATOR: u32 = 100; + /// Start height + pub const START_HEIGHT: u32 = 1046400; + /// End height + pub const END_HEIGHT: u32 = 2726400; + + use super::Receiver; + /// Numerator based on receiver + pub fn numerator(receiver: Receiver) -> u32 { + match receiver { + Receiver::ECC => 7, + Receiver::ZF => 5, + Receiver::MG => 8, + } + } + } + /// For the Testnet + pub mod testnet { + /// Denominator + pub const DENOMINATOR: u32 = 100; + /// Start height + pub const START_HEIGHT: u32 = 1028500; + /// End height + pub const END_HEIGHT: u32 = 2796000; + + use super::Receiver; + /// Numerator based on receiver + pub fn numerator(receiver: Receiver) -> u32 { + match receiver { + Receiver::ECC => 7, + Receiver::ZF => 5, + Receiver::MG => 8, + } + } + } +} +``` + +## General subsidy + +The block subsidy and miner reward among other utility functions are inside the general subsidy category. + +- `block_subsidy(Height, Network) -> Result, Error>` - Total block subsidy. +- `miner_subsidy(Height, Network) -> Result, Error>` - Miner portion. +- `transaction_fees(&Block) -> Result, Error>` - Sum of all the transaction fees. +- `coinbase_sum_outputs(&Transaction) -> Result, Error>` - Sum of all output values in the coinbase transaction. +- `find_output_with_amount(&Transaction, Amount) -> Vec` - Outputs where value equal to Amount. + +## Founders reward + +Only functions specific to calculation of founders reward. + +- `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block or 0. +- `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block, address is a `String` because it can be a transparent or sapling address(After Heartwood/ZIP-213). + +## Funding streams + +Only functions specific to the calculation of funding streams. + +- `funding_stream(height, newtork) -> Result, Error>` - Funding stream portion for this block or 0. +- `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. The same as founders reward the returned address is a `String`. + +## Consensus rules + +All consensus rules for block subsidy are validated in a function inside `zebra-consensus/src/block/check.rs`: + +`subsidy_is_correct(Network, &Block) -> Result<(), BlockError>` + +The following consensus rules must be applied to `subsidy_is_correct()`: + +### 1 - Founders reward: + +*[Pre-Canopy] A coinbase transaction at `height` **MUST** include at least one output that pays exactly `FoundersReward(height)` zatoshi with a standard P2SH script of the form `OP_HASH160 FounderRedeemScriptHash (height) OP_EQUAL` as its scriptPubKey.* https://zips.z.cash/protocol/protocol.pdf#foundersreward + +We make use of the founders reward functions here. We get the amount of the reward with `founders_reward(height, network)` and we get the addresses for the reward at height with `founders_reward_address(height, network)`. Next we cab get a list of outputs that match the amount with `find_output_with_amount()` and with it we check if it matches the address. + +### 2 - Funding stream: + +*[Canopy onward] The coinbase transaction at `height` **MUST** contain at least one output per funding stream `fs` active at +height, that pays `fs.Value(height)` zatoshi in the prescribed way to the stream’s recipient address represented by `fs.AddressList` of `fs.AddressIndex(height)`.* https://zips.z.cash/protocol/protocol.pdf#fundingstreams + +We make use of the funding streams functions here, similar to founders reward . We get the amount using `funding_stream(height, network)` and then the address with `funding_stream_address(height, network)`. The validation is again the same as with founders reward, we need to look for an output that pays the amount to the address. The same utility function `find_output_with_amount()` can be used here. + +### 3 - Miner subsidy: + +*The transaction fees are the sum of each transactions inputs, minus its outputs, for all non-coinbase transactions in a block the sum of the coinbase transaction outputs must be less than or equal to the block subsidy plus transaction fees (because miners can destroy coins)* https://github.com/ZcashFoundation/zebra/pull/1051#issuecomment-700325653 + +So the rule is the following before Canopy: + +`coinbase_sum_outputs() <= miner_subsidy() + founders_reward() + transaction_fees()` + +and after Canopy: + +`coinbase_sum_outputs() <= miner_subsidy() + funding_stream() + transaction_fees()` + +### 4 - Shielded coinbase: + +*Zip-213 - Shielded Coinbase* https://zips.z.cash/zip-0213#specification + +Pending From 52bd951bcd8b58d28af5f8babbda0ef305de4407 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 7 Oct 2020 14:41:05 -0300 Subject: [PATCH 02/62] update funding stream constants --- book/src/dev/rfcs/xxxx-block-subsidy.md | 86 +++++++++++-------------- 1 file changed, 37 insertions(+), 49 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 786a4114a5d..8b6ee11454f 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -88,59 +88,47 @@ To do the calculations and checks the following constants and functions need to The design suggests to implement the parameters needed for funding streams as: ``` -/// Funding Streams -// Todo: There is probably a better way to do this ... -pub mod fs { - - /// The funding stream receivers - pub enum Receiver { - /// Electric Coin Company - ECC, - /// ZCash Foundation - ZF, - /// Major Grants - MG, - } +/// The funding stream receiver categories +pub enum FundingStreamsReceivers { + /// Electric Coin Company + ECC, + /// ZCash Foundation + ZF, + /// Major Grants + MG, +} +/// The numerator for each funding stream receiving category +/// as described in [protocol specification §7.9.1][7.9.1]. +/// +/// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams +const FUNDINGSTREAMS_RECEIVERS_NUMERATORS: &[(i32, FundingStreamsReceivers)] = &[ + (7, FundingStreamsReceivers::ECC), + (5, FundingStreamsReceivers::ZF), + (8, FundingStreamsReceivers::MG), +]; + +/// Denominator as described in [protocol specification §7.9.1][7.9.1]. +/// +/// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams +pub const FUNDINGSTREAM_DENOMINATOR: i32 = 100; + +/// Height intervals for funding streams on each network. +pub enum FundingStreamsHeightIntervals { /// For the Mainnet - pub mod mainnet { - /// Denominator - pub const DENOMINATOR: u32 = 100; - /// Start height - pub const START_HEIGHT: u32 = 1046400; - /// End height - pub const END_HEIGHT: u32 = 2726400; - - use super::Receiver; - /// Numerator based on receiver - pub fn numerator(receiver: Receiver) -> u32 { - match receiver { - Receiver::ECC => 7, - Receiver::ZF => 5, - Receiver::MG => 8, - } - } - } + Mainnet, /// For the Testnet - pub mod testnet { - /// Denominator - pub const DENOMINATOR: u32 = 100; - /// Start height - pub const START_HEIGHT: u32 = 1028500; - /// End height - pub const END_HEIGHT: u32 = 2796000; - - use super::Receiver; - /// Numerator based on receiver - pub fn numerator(receiver: Receiver) -> u32 { - match receiver { - Receiver::ECC => 7, - Receiver::ZF => 5, - Receiver::MG => 8, - } - } - } + Testnet, } + +/// Start and end Heights for funding streams +/// as described in [protocol specification §7.9.1][7.9.1]. +/// +/// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams +const FUNDINGSTREAMS_HEIGHT_INTERVALS: &[(Height, Height, FundingStreamsHeightIntervals)] = &[ + (Height(1_046_400), Height(2_726_400), FundingStreamsHeightIntervals::Mainnet), + (Height(1_028_500), Height(2_796_000), FundingStreamsHeightIntervals::Testnet), +]; ``` ## General subsidy From f68f1275f191b19a90d398d7a04cbccbe6f74a65 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 7 Oct 2020 15:52:25 -0300 Subject: [PATCH 03/62] Update xxxx-block-subsidy.md --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 8b6ee11454f..fc6dc0f95a2 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -167,14 +167,14 @@ The following consensus rules must be applied to `subsidy_is_correct()`: *[Pre-Canopy] A coinbase transaction at `height` **MUST** include at least one output that pays exactly `FoundersReward(height)` zatoshi with a standard P2SH script of the form `OP_HASH160 FounderRedeemScriptHash (height) OP_EQUAL` as its scriptPubKey.* https://zips.z.cash/protocol/protocol.pdf#foundersreward -We make use of the founders reward functions here. We get the amount of the reward with `founders_reward(height, network)` and we get the addresses for the reward at height with `founders_reward_address(height, network)`. Next we cab get a list of outputs that match the amount with `find_output_with_amount()` and with it we check if it matches the address. +We make use of the founders reward functions here. We get the amount of the reward with `founders_reward(height, network)` and the address for the reward at height with `founders_reward_address(height, network)`. Next we get a list of outputs that match the amount with the utility function `find_output_with_amount()`. Finally with this list, we check if any of the output scripts addresses matches our computed address. ### 2 - Funding stream: *[Canopy onward] The coinbase transaction at `height` **MUST** contain at least one output per funding stream `fs` active at height, that pays `fs.Value(height)` zatoshi in the prescribed way to the stream’s recipient address represented by `fs.AddressList` of `fs.AddressIndex(height)`.* https://zips.z.cash/protocol/protocol.pdf#fundingstreams -We make use of the funding streams functions here, similar to founders reward . We get the amount using `funding_stream(height, network)` and then the address with `funding_stream_address(height, network)`. The validation is again the same as with founders reward, we need to look for an output that pays the amount to the address. The same utility function `find_output_with_amount()` can be used here. +We make use of the funding streams functions here, similar to founders reward . We get the amount of the reward using `funding_stream(height, network)` and then the address with `funding_stream_address(height, network)`. Next we get a list of outputs that match the amount with the utility function `find_output_with_amount()`. Finally with this list, we check if any of the output scripts matches the address we have computed. ### 3 - Miner subsidy: From 8b06235e14bfd296f1674cb35aee8450bf1b6346 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 08:41:28 -0300 Subject: [PATCH 04/62] Apply suggestions from code review Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 37 ++++++++++++------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index fc6dc0f95a2..5bfcae64b50 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -31,7 +31,7 @@ This document motivation is to have a clear roadmap about what is needed, the bi # Guide-level explanation [guide-level-explanation]: #guide-level-explanation -In Zebra the consensus related code lives in the `zebra-consensus` crate. It is natural to add the block subsidy code here. The following module is suggested to be created by this design: +In Zebra the consensus related code lives in the `zebra-consensus` crate. The block subsidy checks are implemented in `zebra-consensus`, in the following module: - `zebra-consensus/src/block/subsidy/subsidy.rs` @@ -80,8 +80,8 @@ To do the calculations and checks the following constants and functions need to - `POST_BLOSSOM_HALVING_INTERVAL` - `FOUNDERS_FRACTION_DIVISOR` - `FOUNDER_ADDRESS_CHANGE_INTERVAL` -- `FOUNDERS_REWARD_ADDRESSES_MAINNET` -- `FOUNDERS_REWARD_ADDRESSES_TESTNET` +- `FOUNDER_ADDRESSES_MAINNET` +- `FOUNDER_ADDRESSES_TESTNET` ### Funding streams parameter constants @@ -89,29 +89,27 @@ The design suggests to implement the parameters needed for funding streams as: ``` /// The funding stream receiver categories -pub enum FundingStreamsReceivers { - /// Electric Coin Company - ECC, - /// ZCash Foundation - ZF, - /// Major Grants - MG, +#[allow(missing_docs)] +pub enum FundingStreamReceiver { + ElectricCoinCompany, + ZcashFoundation, + MajorGrants, } /// The numerator for each funding stream receiving category /// as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -const FUNDINGSTREAMS_RECEIVERS_NUMERATORS: &[(i32, FundingStreamsReceivers)] = &[ - (7, FundingStreamsReceivers::ECC), - (5, FundingStreamsReceivers::ZF), - (8, FundingStreamsReceivers::MG), +const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(u64, FundingStreamReceiver)] = &[ + (7, FundingStreamReceiver::ElectricCoinCompany), + (5, FundingStreamReceiver::ZcashFoundation), + (8, FundingStreamReceiver::MajorGrants), ]; /// Denominator as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -pub const FUNDINGSTREAM_DENOMINATOR: i32 = 100; +pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100; /// Height intervals for funding streams on each network. pub enum FundingStreamsHeightIntervals { @@ -125,11 +123,10 @@ pub enum FundingStreamsHeightIntervals { /// as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -const FUNDINGSTREAMS_HEIGHT_INTERVALS: &[(Height, Height, FundingStreamsHeightIntervals)] = &[ - (Height(1_046_400), Height(2_726_400), FundingStreamsHeightIntervals::Mainnet), - (Height(1_028_500), Height(2_796_000), FundingStreamsHeightIntervals::Testnet), +const FUNDING_STREAM_HEIGHT_INTERVALS: &[(Height, Height, Network)] = &[ + (Height(1_046_400), Height(2_726_400), Network::Mainnet), + (Height(1_028_500), Height(2_796_000), Network::Testnet), ]; -``` ## General subsidy @@ -146,7 +143,7 @@ The block subsidy and miner reward among other utility functions are inside the Only functions specific to calculation of founders reward. - `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block or 0. -- `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block, address is a `String` because it can be a transparent or sapling address(After Heartwood/ZIP-213). +- `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block. All specified founders reward addresses are transparent `PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) ## Funding streams From ab88d50b902722e4952939c3f042bd67d82ee5cb Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 09:44:01 -0300 Subject: [PATCH 05/62] add reference in miner subsidy --- book/src/dev/rfcs/xxxx-block-subsidy.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 5bfcae64b50..c46389b33ef 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -127,6 +127,7 @@ const FUNDING_STREAM_HEIGHT_INTERVALS: &[(Height, Height, Network)] = &[ (Height(1_046_400), Height(2_726_400), Network::Mainnet), (Height(1_028_500), Height(2_796_000), Network::Testnet), ]; +``` ## General subsidy @@ -175,7 +176,7 @@ We make use of the funding streams functions here, similar to founders reward . ### 3 - Miner subsidy: -*The transaction fees are the sum of each transactions inputs, minus its outputs, for all non-coinbase transactions in a block the sum of the coinbase transaction outputs must be less than or equal to the block subsidy plus transaction fees (because miners can destroy coins)* https://github.com/ZcashFoundation/zebra/pull/1051#issuecomment-700325653 +*The total amount of transparent outputs from a coinbase transaction, minus the amount of the `valueBalance` field if present, **MUST NOT** be greater than the amount of miner subsidy plus the total amount of transaction fees paid by transactions in this block.* https://zips.z.cash/protocol/canopy.pdf#txnencodingandconsensus So the rule is the following before Canopy: From 2ace6902459e2d93dd41b5b02def4a821b60bc19 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 10:07:03 -0300 Subject: [PATCH 06/62] fix table --- book/src/dev/rfcs/xxxx-block-subsidy.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index c46389b33ef..9cf96cfd5fd 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -49,17 +49,17 @@ Checking functions for blocks are implemented at `zebra-consensus/src/block/chec It is important to note that the Genesis block, BeforeOverwinter, and Overwinter blocks are verified by the CheckpointVerifier so they are not considered in this design. The following table will show what periods are included and what is not in this proposal: -| Height | Miner | Founder reward | Funding streams | Shielded Coinbase | -|----------------------------------------|:--------:|:--------------:|:---------------:|:------------------| -| ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | -| ~Slow Start Shift..Slow Start Interval~| ~80%~ | ~20%~ | ~0%~ | ~No~ | -| ~Slow Start Interval..Overwinter~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | -| Overwinter..Sapling | 80% | 20% | 0% | No | -| Sapling..Blossom | 80% | 20% | 0% | No | -| Blossom..Heartwood | 80% | 20% | 0% | No | -| Heartwood..Canopy | 80% | 20% | 0% | Yes | -| Canopy..Second Halving | 80% | 0% | 20% | Yes | -| ~Second Halving..~ | ~100%~ | ~0%~ | ~0%~ | ~Yes~ | +| Height | Miner | Founder reward | Funding streams | Shielded Coinbase | Target Spacing | +|----------------------------------------|----------|----------------|-----------------|-------------------|----------------| +| ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | ~**None**~ | +| ~Slow Start Shift..Slow Start Interval~| ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| ~Slow Start Interval..Overwinter~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| Overwinter..Sapling | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| Sapling..Blossom | 80% | 20% | 0% | No | 150 seconds | +| Blossom..Heartwood | 80% | 20% | 0% | No | 75 seconds | +| Heartwood..Canopy | 80% | 20% | 0% | Yes | 75 seconds | +| Canopy..Second Halving | 80% | 0% | 20% | Yes | 75 seconds | +| Second Halving.. | 100% | 0% | 0% | Yes | 75 seconds | # Reference-level explanation [reference-level-explanation]: #reference-level-explanation From e9661d3153b92c7d343cae42b7e861c78e5c7be4 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 10:09:49 -0300 Subject: [PATCH 07/62] Update xxxx-block-subsidy.md --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 9cf96cfd5fd..46e145d1bfa 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -47,14 +47,14 @@ In addition to calculations the block subsidy requires constants defined in the Checking functions for blocks are implemented at `zebra-consensus/src/block/check.rs` and they are called at `zebra-consensus/src/block.rs`. This follows the already existing structure for block validation in Zebra. -It is important to note that the Genesis block, BeforeOverwinter, and Overwinter blocks are verified by the CheckpointVerifier so they are not considered in this design. The following table will show what periods are included and what is not in this proposal: +It is important to note that the Genesis block, BeforeOverwinter, and Overwinter blocks up to Sapling are verified by the CheckpointVerifier so they are not considered in this design. The following table will show what periods are included and what is not in this proposal: | Height | Miner | Founder reward | Funding streams | Shielded Coinbase | Target Spacing | |----------------------------------------|----------|----------------|-----------------|-------------------|----------------| | ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | ~**None**~ | | ~Slow Start Shift..Slow Start Interval~| ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | ~Slow Start Interval..Overwinter~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | -| Overwinter..Sapling | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| ~Overwinter..Sapling~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | Sapling..Blossom | 80% | 20% | 0% | No | 150 seconds | | Blossom..Heartwood | 80% | 20% | 0% | No | 75 seconds | | Heartwood..Canopy | 80% | 20% | 0% | Yes | 75 seconds | From 518e146a9f650b42ebf9666d4131bcefdbade73c Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 10:16:17 -0300 Subject: [PATCH 08/62] remove FundingStreamsHeightIntervals --- book/src/dev/rfcs/xxxx-block-subsidy.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 46e145d1bfa..e9abc9bd9e9 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -111,14 +111,6 @@ const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(u64, FundingStreamReceiver)] = &[ /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100; -/// Height intervals for funding streams on each network. -pub enum FundingStreamsHeightIntervals { - /// For the Mainnet - Mainnet, - /// For the Testnet - Testnet, -} - /// Start and end Heights for funding streams /// as described in [protocol specification §7.9.1][7.9.1]. /// From bd57900d4889d71edf4137e9a3c5f13c09e4eab5 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 10:24:37 -0300 Subject: [PATCH 09/62] remove `or 0` from function descriptions. It is clear from the signature that the function will return `Error` on any failure(including input errors, for example a wrong height). Describing this will force us to write it for all functions that returns an error so better remove it. --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index e9abc9bd9e9..bec323c083b 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -135,14 +135,14 @@ The block subsidy and miner reward among other utility functions are inside the Only functions specific to calculation of founders reward. -- `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block or 0. +- `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block. - `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block. All specified founders reward addresses are transparent `PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) ## Funding streams Only functions specific to the calculation of funding streams. -- `funding_stream(height, newtork) -> Result, Error>` - Funding stream portion for this block or 0. +- `funding_stream(height, newtork) -> Result, Error>` - Funding stream portion for this block. - `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. The same as founders reward the returned address is a `String`. ## Consensus rules From c76d06464d207fb0f81558d71f0449997dea3583 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 11:04:43 -0300 Subject: [PATCH 10/62] add links to subsidy categories --- book/src/dev/rfcs/xxxx-block-subsidy.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index bec323c083b..af5f384c09a 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -125,6 +125,10 @@ const FUNDING_STREAM_HEIGHT_INTERVALS: &[(Height, Height, Network)] = &[ The block subsidy and miner reward among other utility functions are inside the general subsidy category. +https://zips.z.cash/protocol/canopy.pdf#subsidyconcepts + +https://zips.z.cash/protocol/canopy.pdf#subsidies + - `block_subsidy(Height, Network) -> Result, Error>` - Total block subsidy. - `miner_subsidy(Height, Network) -> Result, Error>` - Miner portion. - `transaction_fees(&Block) -> Result, Error>` - Sum of all the transaction fees. @@ -135,6 +139,8 @@ The block subsidy and miner reward among other utility functions are inside the Only functions specific to calculation of founders reward. +https://zips.z.cash/protocol/canopy.pdf#foundersreward + - `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block. - `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block. All specified founders reward addresses are transparent `PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) @@ -142,6 +148,12 @@ Only functions specific to calculation of founders reward. Only functions specific to the calculation of funding streams. +https://zips.z.cash/protocol/canopy.pdf#fundingstreams + +https://zips.z.cash/zip-0207 + +https://zips.z.cash/zip-0214 + - `funding_stream(height, newtork) -> Result, Error>` - Funding stream portion for this block. - `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. The same as founders reward the returned address is a `String`. From 90e5f36688e3b819e427ef2d1cf9b7e94f6a05de Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 11:29:39 -0300 Subject: [PATCH 11/62] fix design in Funding streams parameter constants --- book/src/dev/rfcs/xxxx-block-subsidy.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index af5f384c09a..8bad6e6ddb6 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -101,9 +101,9 @@ pub enum FundingStreamReceiver { /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(u64, FundingStreamReceiver)] = &[ - (7, FundingStreamReceiver::ElectricCoinCompany), - (5, FundingStreamReceiver::ZcashFoundation), - (8, FundingStreamReceiver::MajorGrants), + (FundingStreamReceiver::ElectricCoinCompany, 7), + (FundingStreamReceiver::ZcashFoundation, 5), + (FundingStreamReceiver::MajorGrants, 8), ]; /// Denominator as described in [protocol specification §7.9.1][7.9.1]. @@ -111,13 +111,19 @@ const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(u64, FundingStreamReceiver)] = &[ /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100; +#[allow(missing_docs)] +pub enum FundingStreamRange { + StartHeight, + EndHeight, +} + /// Start and end Heights for funding streams /// as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -const FUNDING_STREAM_HEIGHT_INTERVALS: &[(Height, Height, Network)] = &[ - (Height(1_046_400), Height(2_726_400), Network::Mainnet), - (Height(1_028_500), Height(2_796_000), Network::Testnet), +const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Height, Height)] = &[ + (Network::Mainnet, Height(1_046_400), Height(2_726_400)), + (Network::Testnet, Height(1_028_500), Height(2_796_000)), ]; ``` From 92219a5e4776699ec11ce7158e6e5524d1433c89 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 11:33:00 -0300 Subject: [PATCH 12/62] fix order in FUNDING_STREAM_RECEIVER_NUMERATORS --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 8bad6e6ddb6..52080df80e1 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -100,7 +100,7 @@ pub enum FundingStreamReceiver { /// as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(u64, FundingStreamReceiver)] = &[ +const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(FundingStreamReceiver, u64)] = &[ (FundingStreamReceiver::ElectricCoinCompany, 7), (FundingStreamReceiver::ZcashFoundation, 5), (FundingStreamReceiver::MajorGrants, 8), From 135ea12865a670d6433c1c026e249efb96606b3f Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 15:23:57 -0300 Subject: [PATCH 13/62] return `PayToScriptHash` in `funding_stream_address` --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 52080df80e1..864f1a80c35 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -66,7 +66,7 @@ It is important to note that the Genesis block, BeforeOverwinter, and Overwinter Given the module structure proposed above all the block subsidy calculations from the protocol must be implemented. The final goal is to do checks for each incoming block and make sure they pass the consensus rules. -To do the calculations and checks the following constants and functions need to be introduced: +To do the calculations and checks the following constants, types and functions need to be introduced: ## Constants @@ -148,7 +148,7 @@ Only functions specific to calculation of founders reward. https://zips.z.cash/protocol/canopy.pdf#foundersreward - `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block. -- `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block. All specified founders reward addresses are transparent `PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) +- `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block. All specified founders reward addresses are transparent `zebra_chain::transparent:Address::PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) ## Funding streams @@ -161,7 +161,7 @@ https://zips.z.cash/zip-0207 https://zips.z.cash/zip-0214 - `funding_stream(height, newtork) -> Result, Error>` - Funding stream portion for this block. -- `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. The same as founders reward the returned address is a `String`. +- `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. All specified funding streams addresses are transparent `zebra_chain::transparent:Address::PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) ## Consensus rules From 3d6c3923b4ede0734d47fb71da15a818071e364a Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 16:12:26 -0300 Subject: [PATCH 14/62] fix definitions --- book/src/dev/rfcs/xxxx-block-subsidy.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 864f1a80c35..ab28f673b6a 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -26,7 +26,20 @@ This document motivation is to have a clear roadmap about what is needed, the bi - **funding streams**: The portion of the block reward that goes into a pre defined funding stream address. - **miner subsidy**: The portion of the block reward that goes into the miner of the block. - **coinbase transaction**: The first transaction in a block where block subsidy is done. -- **NU**: Network Upgrade. +- **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. +- **miner fees**: The [transparent value pool](#transparent-value-pool-calculation) for all the transactions in a block. + +### Transparent value pool calculation + +There is a "transparent value pool" inside each transaction, containing "funds in motion" (distinct from the actual transparent value pool of UTXOs, being "funds at rest"). Balance of that pool works as follows: + +- `tx.vin` adds to the pool. +- `tx.vout` subtracts from the pool. +- `vpub_new` values from `tx.vJoinSplit` add to the pool. +- `vpub_old` values from `tx.vJoinSplit` subtract from the pool. +- `valueBalance` adds to the pool. It itself is equal to `sum(SaplingSpends) - sum(SaplingOutputs)`, so it has the same functional effect as for transparent and Sprout. + +The balance rule is that this pool must have non-negative value, and its net value is the fee. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation From 2b51780d42782b77f4ece8d31945013d044b6fc5 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 16:40:49 -0300 Subject: [PATCH 15/62] change summary --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index ab28f673b6a..e336ebca2ee 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -6,9 +6,8 @@ # Summary [summary]: #summary -Block subsidy is the calculation and validation of rules defined in the Zcash protocol that apply to the coinbase transaction of all incoming blocks. The calculation of block subsidy on each block consists of amounts paid to miners and amounts paid to other participants(founders or funding stream receivers), it also specifies the receiver of these rewards. -At any time in the blockchain history specific rules apply to the coinbase transaction. This validation rules and calculations can change at Network Upgrades. +Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/blob/main/book/src/dev/rfcs/0002-parallel-verification.md#definitions) in the `zebra-consensus` crate, this is done for all incoming blocks. Inside each block the coinbase transaction is special, it holds the subsidy rewards that are paid to different participants(miners, founders, stream receivers). This RFC describes how to implement the needed calculations and verification for block subsidy and miner fees. # Motivation [motivation]: #motivation @@ -25,6 +24,7 @@ This document motivation is to have a clear roadmap about what is needed, the bi - **founders reward**: The portion of the block reward that goes into a pre defined founder address. - **funding streams**: The portion of the block reward that goes into a pre defined funding stream address. - **miner subsidy**: The portion of the block reward that goes into the miner of the block. +- **block subsidy**: Miner subsidy plus founders reward or funding stream if any of the 2 are active. - **coinbase transaction**: The first transaction in a block where block subsidy is done. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. - **miner fees**: The [transparent value pool](#transparent-value-pool-calculation) for all the transactions in a block. From a4580ae2940d680727104b25b7e2d2c4adeba7fc Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 16:52:31 -0300 Subject: [PATCH 16/62] change motivation --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index e336ebca2ee..942b0780ae4 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -12,11 +12,9 @@ Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/b # Motivation [motivation]: #motivation -All incoming blocks must be validated with the protocol rules, there is no way to avoid this logic to be present in any Zcash protocol compatible implementation such as Zebra. +All incoming blocks must be validated with the protocol specifications, there is no way to avoid this logic to be present in any Zcash protocol compatible implementation such as Zebra. -The amount of rules, calculations, parameters, etc needed to implement the whole Block Subsidy can be overwhelming as each little piece comes together to make a whole. Zebra is in a position where we know all the rules up to the second halving so the implementation can and will be different from `zcashd` but at the end of the day all coinbase transactions will need to be validated as the protocol describes. - -This document motivation is to have a clear roadmap about what is needed, the big picture of all components and how they interact together so we can separate a very big task into smaller pieces that we believe will make the implementation easier and better. +Block subsidy and miner fees are part of the protocol, the semantic verification of them apply to the coinbase transaction and they must be verified in Zebra. # Definitions [definitions]: #definitions From 2732d0757c81436087ba4ca3180b809406322409 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 17:46:52 -0300 Subject: [PATCH 17/62] change consensus rules intro --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 942b0780ae4..4ce0e49b6b0 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -176,11 +176,11 @@ https://zips.z.cash/zip-0214 ## Consensus rules -All consensus rules for block subsidy are validated in a function inside `zebra-consensus/src/block/check.rs`: +`zebra-consensus/src/block.rs` will call the following function implemented inside `zebra-consensus/src/block/check.rs`: `subsidy_is_correct(Network, &Block) -> Result<(), BlockError>` -The following consensus rules must be applied to `subsidy_is_correct()`: +`subsidy_is_correct()` will call individual functions(also implemented in `zebra-consensus/src/block/check.rs`) to verify the following consensus rules: ### 1 - Founders reward: From f06ebbf34a5b910e4d40ace4fd3e300361c25960 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 17:57:42 -0300 Subject: [PATCH 18/62] add types to constants --- book/src/dev/rfcs/xxxx-block-subsidy.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 4ce0e49b6b0..8b36a3845a1 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -81,18 +81,18 @@ To do the calculations and checks the following constants, types and functions n ## Constants -- `SLOW_START_INTERVAL` -- `SLOW_START_SHIFT` -- `MAX_BLOCK_SUBSIDY` -- `PRE_BLOSSOM_POW_TARGET_SPACING` -- `POST_BLOSSOM_POW_TARGET_SPACING` -- `BLOSSOM_POW_TARGET_SPACING_RATIO` -- `PRE_BLOSSOM_HALVING_INTERVAL` -- `POST_BLOSSOM_HALVING_INTERVAL` -- `FOUNDERS_FRACTION_DIVISOR` -- `FOUNDER_ADDRESS_CHANGE_INTERVAL` -- `FOUNDER_ADDRESSES_MAINNET` -- `FOUNDER_ADDRESSES_TESTNET` +- `SLOW_START_INTERVAL: Height` +- `SLOW_START_SHIFT: Height` +- `MAX_BLOCK_SUBSIDY: u64` +- `PRE_BLOSSOM_POW_TARGET_SPACING: Duration` +- `POST_BLOSSOM_POW_TARGET_SPACING: Duration` +- `BLOSSOM_POW_TARGET_SPACING_RATIO: u64` +- `PRE_BLOSSOM_HALVING_INTERVAL: Height` +- `POST_BLOSSOM_HALVING_INTERVAL: Height` +- `FOUNDERS_FRACTION_DIVISOR: u64` +- `FOUNDER_ADDRESS_CHANGE_INTERVAL: u64` +- `FOUNDER_ADDRESSES_MAINNET: [&'static str; 48]` +- `FOUNDER_ADDRESSES_TESTNET: [&'static str; 48]` ### Funding streams parameter constants From c2f2a53138dabf68631f670cdb0a268d0827a26d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 18:10:11 -0300 Subject: [PATCH 19/62] change `transaction_fees()` to `miner_fees()` --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 8b36a3845a1..2a5200b5bb8 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -148,7 +148,7 @@ https://zips.z.cash/protocol/canopy.pdf#subsidies - `block_subsidy(Height, Network) -> Result, Error>` - Total block subsidy. - `miner_subsidy(Height, Network) -> Result, Error>` - Miner portion. -- `transaction_fees(&Block) -> Result, Error>` - Sum of all the transaction fees. +- `miner_fees(&Block) -> Result, Error>` - Total block fees calculated as [Transparent value pool calculation](#transparent-value-pool-calculation) that belongs to the miner. - `coinbase_sum_outputs(&Transaction) -> Result, Error>` - Sum of all output values in the coinbase transaction. - `find_output_with_amount(&Transaction, Amount) -> Vec` - Outputs where value equal to Amount. From 8de943ebb446f7c34e9bcace97ae2a900bd34689 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 18:43:05 -0300 Subject: [PATCH 20/62] add shielded coinbase --- book/src/dev/rfcs/xxxx-block-subsidy.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 2a5200b5bb8..b5df2604e57 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -151,6 +151,7 @@ https://zips.z.cash/protocol/canopy.pdf#subsidies - `miner_fees(&Block) -> Result, Error>` - Total block fees calculated as [Transparent value pool calculation](#transparent-value-pool-calculation) that belongs to the miner. - `coinbase_sum_outputs(&Transaction) -> Result, Error>` - Sum of all output values in the coinbase transaction. - `find_output_with_amount(&Transaction, Amount) -> Vec` - Outputs where value equal to Amount. +- `shielded_coinbase(Height, Network, &Transaction) -> Result<(), Error>` - Validate shielded coinbase rules. ## Founders reward @@ -209,6 +210,14 @@ and after Canopy: ### 4 - Shielded coinbase: +*[Pre-Heartwood] A coinbase transaction MUST NOT have any JoinSplit descriptions, Spend descriptions, or Output descriptions.* + +*[Heartwood onward] A coinbase transaction MUST NOT have any JoinSplit descriptions or Spend descriptions.* + +*[Heartwood onward] The consensus rules applied to `valueBalance`, `vShieldedOutput`, and `bindingSig` in non-coinbase transactions MUST also be applied to coinbase transactions.* + +All this rules are implemented inside `shielded_coinbase()`. + *Zip-213 - Shielded Coinbase* https://zips.z.cash/zip-0213#specification -Pending + From b84bf0baf668a6ee6591781ba9331662b6082de1 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 8 Oct 2020 18:44:33 -0300 Subject: [PATCH 21/62] move shielded coinbase link --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index b5df2604e57..d8bc037617b 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -216,8 +216,6 @@ and after Canopy: *[Heartwood onward] The consensus rules applied to `valueBalance`, `vShieldedOutput`, and `bindingSig` in non-coinbase transactions MUST also be applied to coinbase transactions.* -All this rules are implemented inside `shielded_coinbase()`. - -*Zip-213 - Shielded Coinbase* https://zips.z.cash/zip-0213#specification - +https://zips.z.cash/zip-0213#specification +This rules are implemented inside `shielded_coinbase()`. From ad80a6711837e1be222d92696c449a599c36fe03 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Fri, 9 Oct 2020 08:20:00 -0300 Subject: [PATCH 22/62] change return type of `funding_stream_address` --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index d8bc037617b..249edf0473c 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -173,7 +173,7 @@ https://zips.z.cash/zip-0207 https://zips.z.cash/zip-0214 - `funding_stream(height, newtork) -> Result, Error>` - Funding stream portion for this block. -- `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. All specified funding streams addresses are transparent `zebra_chain::transparent:Address::PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) +- `funding_stream_address(height, network) -> Result` - Address of the funding stream receiver at this block. The funding streams addresses can be transparent `zebra_chain::transparent:Address::PayToScriptHash` or `zebra_chain::sapling:Address` addresses. ## Consensus rules From e5083b2dd76cdec1f889919f73b81bfbdadee293 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 12 Oct 2020 10:26:07 -0300 Subject: [PATCH 23/62] Apply suggestions from code review Co-authored-by: teor Co-authored-by: Daira Hopwood --- book/src/dev/rfcs/xxxx-block-subsidy.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 249edf0473c..474c41f3309 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -7,7 +7,7 @@ [summary]: #summary -Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/blob/main/book/src/dev/rfcs/0002-parallel-verification.md#definitions) in the `zebra-consensus` crate, this is done for all incoming blocks. Inside each block the coinbase transaction is special, it holds the subsidy rewards that are paid to different participants(miners, founders, stream receivers). This RFC describes how to implement the needed calculations and verification for block subsidy and miner fees. +Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/blob/main/book/src/dev/rfcs/0002-parallel-verification.md#definitions) in the `zebra-consensus` crate, this is done for all incoming blocks. Inside each block the coinbase transaction is special, it holds the subsidy rewards that are paid to different participants(miners, founders, funding stream receivers). This RFC describes how to implement the needed calculations and verification for block subsidy and miner fees. # Motivation [motivation]: #motivation @@ -23,9 +23,9 @@ Block subsidy and miner fees are part of the protocol, the semantic verification - **funding streams**: The portion of the block reward that goes into a pre defined funding stream address. - **miner subsidy**: The portion of the block reward that goes into the miner of the block. - **block subsidy**: Miner subsidy plus founders reward or funding stream if any of the 2 are active. -- **coinbase transaction**: The first transaction in a block where block subsidy is done. +- **coinbase transaction**: The first transaction in a block; this is the transaction that handles block subsidy. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. -- **miner fees**: The [transparent value pool](#transparent-value-pool-calculation) for all the transactions in a block. +- **miner fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) amounts, for all the transactions in a block. ### Transparent value pool calculation @@ -37,7 +37,7 @@ There is a "transparent value pool" inside each transaction, containing "funds i - `vpub_old` values from `tx.vJoinSplit` subtract from the pool. - `valueBalance` adds to the pool. It itself is equal to `sum(SaplingSpends) - sum(SaplingOutputs)`, so it has the same functional effect as for transparent and Sprout. -The balance rule is that this pool must have non-negative value, and its net value is the fee. +The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -58,7 +58,7 @@ In addition to calculations the block subsidy requires constants defined in the Checking functions for blocks are implemented at `zebra-consensus/src/block/check.rs` and they are called at `zebra-consensus/src/block.rs`. This follows the already existing structure for block validation in Zebra. -It is important to note that the Genesis block, BeforeOverwinter, and Overwinter blocks up to Sapling are verified by the CheckpointVerifier so they are not considered in this design. The following table will show what periods are included and what is not in this proposal: +It is important to note that all blocks before Sapling are verified by the CheckpointVerifier, so they are not considered in this design. The following table will show what periods are included and what is not in this proposal: | Height | Miner | Founder reward | Funding streams | Shielded Coinbase | Target Spacing | |----------------------------------------|----------|----------------|-----------------|-------------------|----------------| From 421f1ea40e591c829e100eea38a6f4eeba98d514 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 12 Oct 2020 16:11:17 -0300 Subject: [PATCH 24/62] fix table intervals --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 474c41f3309..895dd27672f 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -63,7 +63,7 @@ It is important to note that all blocks before Sapling are verified by the Check | Height | Miner | Founder reward | Funding streams | Shielded Coinbase | Target Spacing | |----------------------------------------|----------|----------------|-----------------|-------------------|----------------| | ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | ~**None**~ | -| ~Slow Start Shift..Slow Start Interval~| ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| ~Genesis..Slow Start Interval~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | ~Slow Start Interval..Overwinter~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | ~Overwinter..Sapling~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | Sapling..Blossom | 80% | 20% | 0% | No | 150 seconds | From 589cef37e1886e898b74ff153ac3dd38e4bce86d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 12 Oct 2020 16:17:31 -0300 Subject: [PATCH 25/62] Use Range for FUNDING_STREAM_HEIGHT_RANGES --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 895dd27672f..fe490698993 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -132,9 +132,9 @@ pub enum FundingStreamRange { /// as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Height, Height)] = &[ - (Network::Mainnet, Height(1_046_400), Height(2_726_400)), - (Network::Testnet, Height(1_028_500), Height(2_796_000)), +const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Range)] = &[ + (Network::Mainnet, Height(1_046_400)..Height(2_726_400)), + (Network::Testnet, Height(1_028_500)..Height(2_796_000)), ]; ``` From 134bc32d59e609a669b46ddbe7d068a2915a5ece Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 12 Oct 2020 17:36:26 -0300 Subject: [PATCH 26/62] improve transparent value pool section --- book/src/dev/rfcs/xxxx-block-subsidy.md | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index fe490698993..ce66fbd5e41 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -31,11 +31,25 @@ Block subsidy and miner fees are part of the protocol, the semantic verification There is a "transparent value pool" inside each transaction, containing "funds in motion" (distinct from the actual transparent value pool of UTXOs, being "funds at rest"). Balance of that pool works as follows: -- `tx.vin` adds to the pool. -- `tx.vout` subtracts from the pool. -- `vpub_new` values from `tx.vJoinSplit` add to the pool. -- `vpub_old` values from `tx.vJoinSplit` subtract from the pool. -- `valueBalance` adds to the pool. It itself is equal to `sum(SaplingSpends) - sum(SaplingOutputs)`, so it has the same functional effect as for transparent and Sprout. +Transparent: + +- `tx_in` adds to the pool. +- `tx_out` subtracts from the pool. + +https://zips.z.cash/protocol/canopy.pdf#txnencodingandconsensus + +Sprout: + +- `vpub_new` values from `vJoinSplit` of the transaction add to the pool. +- `vpub_old` values from `vJoinSplit` of the transaction subtract from the pool. + +https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus + +Sapling: + +- `valueBalance` adds to the pool. It itself is equal to `sum(SaplingSpends) - sum(SaplingOutputs)`, so it has the same functional effect as for transparent and Sprout. + +https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. From 9ef7dec7a0f73d20fa8a83d05f7d784dc87cc18a Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 13 Oct 2020 08:46:12 -0300 Subject: [PATCH 27/62] Apply suggestions from code review Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index ce66fbd5e41..1dad9c69893 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -77,9 +77,7 @@ It is important to note that all blocks before Sapling are verified by the Check | Height | Miner | Founder reward | Funding streams | Shielded Coinbase | Target Spacing | |----------------------------------------|----------|----------------|-----------------|-------------------|----------------| | ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | ~**None**~ | -| ~Genesis..Slow Start Interval~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | -| ~Slow Start Interval..Overwinter~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | -| ~Overwinter..Sapling~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| ~(Genesis + 1)..Sapling~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | Sapling..Blossom | 80% | 20% | 0% | No | 150 seconds | | Blossom..Heartwood | 80% | 20% | 0% | No | 75 seconds | | Heartwood..Canopy | 80% | 20% | 0% | Yes | 75 seconds | @@ -146,7 +144,7 @@ pub enum FundingStreamRange { /// as described in [protocol specification §7.9.1][7.9.1]. /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Range)] = &[ +const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Range<_>)] = &[ (Network::Mainnet, Height(1_046_400)..Height(2_726_400)), (Network::Testnet, Height(1_028_500)..Height(2_796_000)), ]; From 37fb20b4a79f1c79a16d671830836e99e75ebf2d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 13 Oct 2020 10:36:35 -0300 Subject: [PATCH 28/62] add a test plan section --- book/src/dev/rfcs/xxxx-block-subsidy.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 1dad9c69893..b60f3ef0578 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -231,3 +231,17 @@ and after Canopy: https://zips.z.cash/zip-0213#specification This rules are implemented inside `shielded_coinbase()`. + +## Test Plan + +For each network(Mainnet, Testnet), calculation of subsidy amounts need a `Height` as input and will output different amounts according to it. + +- Test all subsidy amount functions(`block_subsidy()`, `miner_subsidy()`, `founders_reward()` and `funding_stream()`) against all network upgrade events of each network and make sure they return the expected amounts according to known outputs. + +For each network, the address of the Test validation functions(subsidy_is_correct()​) against all the blocks zebra haves available in the test vectors collection for both networks(`zebra_test::vectors::MAINNET_BLOCKS` and `zebra_test::vectors::TESTNET_BLOCKS`), all blocks should pass validation.reward receiver on each block will depend on the `Height`. + +- Test all subsidy address functions(`founders_reward_address()` and `funding_stream_address()`) against all network upgrade events of each network and make sure they return the expected addresses. + +Validation tests will test the consensus rules using real blocks from `zebra-test` crate. For both networks, blocks for all network upgrades were added to the crate in [#1096](https://github.com/ZcashFoundation/zebra/pull/1096). Blocks containing shielded coinbase were also introduced at [#1116](https://github.com/ZcashFoundation/zebra/pull/1116) + +- Test validation functions(`subsidy_is_correct()`) against all the blocks zebra haves available in the test vectors collection for both networks(`zebra_test::vectors::MAINNET_BLOCKS` and `zebra_test::vectors::TESTNET_BLOCKS`), all blocks should pass validation. From a8d32c52810082d3d0205dbb64bfd7c9b1831ce2 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 13 Oct 2020 10:39:16 -0300 Subject: [PATCH 29/62] fix extra paste --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index b60f3ef0578..b897b8853ac 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -238,7 +238,7 @@ For each network(Mainnet, Testnet), calculation of subsidy amounts need a `Heigh - Test all subsidy amount functions(`block_subsidy()`, `miner_subsidy()`, `founders_reward()` and `funding_stream()`) against all network upgrade events of each network and make sure they return the expected amounts according to known outputs. -For each network, the address of the Test validation functions(subsidy_is_correct()​) against all the blocks zebra haves available in the test vectors collection for both networks(`zebra_test::vectors::MAINNET_BLOCKS` and `zebra_test::vectors::TESTNET_BLOCKS`), all blocks should pass validation.reward receiver on each block will depend on the `Height`. +For each network, the address of the reward receiver on each block will depend on the `Height`. - Test all subsidy address functions(`founders_reward_address()` and `funding_stream_address()`) against all network upgrade events of each network and make sure they return the expected addresses. From d33027daf45115350c5d8be63bc750d3a6a15912 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 13 Oct 2020 10:50:55 -0300 Subject: [PATCH 30/62] rename `subsidy_is_correct` to `subsidy_is_valid` --- book/src/dev/rfcs/xxxx-block-subsidy.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index b897b8853ac..7f168abf414 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -77,7 +77,7 @@ It is important to note that all blocks before Sapling are verified by the Check | Height | Miner | Founder reward | Funding streams | Shielded Coinbase | Target Spacing | |----------------------------------------|----------|----------------|-----------------|-------------------|----------------| | ~Genesis~ | ~**0%**~ | ~**0%**~ | ~**0%**~ | ~**No**~ | ~**None**~ | -| ~(Genesis + 1)..Sapling~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | +| ~(Genesis + 1)..Sapling~ | ~80%~ | ~20%~ | ~0%~ | ~No~ | ~150 seconds~ | | Sapling..Blossom | 80% | 20% | 0% | No | 150 seconds | | Blossom..Heartwood | 80% | 20% | 0% | No | 75 seconds | | Heartwood..Canopy | 80% | 20% | 0% | Yes | 75 seconds | @@ -191,9 +191,9 @@ https://zips.z.cash/zip-0214 `zebra-consensus/src/block.rs` will call the following function implemented inside `zebra-consensus/src/block/check.rs`: -`subsidy_is_correct(Network, &Block) -> Result<(), BlockError>` +`subsidy_is_valid(Network, &Block) -> Result<(), BlockError>` -`subsidy_is_correct()` will call individual functions(also implemented in `zebra-consensus/src/block/check.rs`) to verify the following consensus rules: +`subsidy_is_valid()` will call individual functions(also implemented in `zebra-consensus/src/block/check.rs`) to verify the following consensus rules: ### 1 - Founders reward: @@ -244,4 +244,4 @@ For each network, the address of the reward receiver on each block will depend o Validation tests will test the consensus rules using real blocks from `zebra-test` crate. For both networks, blocks for all network upgrades were added to the crate in [#1096](https://github.com/ZcashFoundation/zebra/pull/1096). Blocks containing shielded coinbase were also introduced at [#1116](https://github.com/ZcashFoundation/zebra/pull/1116) -- Test validation functions(`subsidy_is_correct()`) against all the blocks zebra haves available in the test vectors collection for both networks(`zebra_test::vectors::MAINNET_BLOCKS` and `zebra_test::vectors::TESTNET_BLOCKS`), all blocks should pass validation. +- Test validation functions(`subsidy_is_valid()`) against all the blocks zebra haves available in the test vectors collection for both networks(`zebra_test::vectors::MAINNET_BLOCKS` and `zebra_test::vectors::TESTNET_BLOCKS`), all blocks should pass validation. From 5cff70b25f6b5550d475ba85dfe69b9bfe094187 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 13 Oct 2020 15:46:04 -0300 Subject: [PATCH 31/62] add funding streams address constants --- book/src/dev/rfcs/xxxx-block-subsidy.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 7f168abf414..6a139dd2355 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -150,6 +150,19 @@ const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Range<_>)] = &[ ]; ``` +Each `FundingStreamReceiver` for the mainnet must have 48 payment addresses associated with and 51 for the testnet. + +https://zips.z.cash/zip-0214#mainnet-recipient-addresses + +The following constants are needed: + +- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` +- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` +- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` +- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` +- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` +- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` + ## General subsidy The block subsidy and miner reward among other utility functions are inside the general subsidy category. From bb933dd84363bda005b853fde3872be9d017ad49 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 13 Oct 2020 18:15:54 -0300 Subject: [PATCH 32/62] fix funding stream addresses --- book/src/dev/rfcs/xxxx-block-subsidy.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 6a139dd2355..a765235c22f 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -157,11 +157,11 @@ https://zips.z.cash/zip-0214#mainnet-recipient-addresses The following constants are needed: - `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` -- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` -- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` -- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` -- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` +- `FUNDING_STREAM_ZF_ADDRESSES_MAINNET: [&'static str; 48]` +- `FUNDING_STREAM_MG_ADDRESSES_MAINNET: [&'static str; 48]` - `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` +- `FUNDING_STREAM_ZF_ADDRESSES_TESTNET: [&'static str; 51]` +- `FUNDING_STREAM_MG_ADDRESSES_TESTNET: [&'static str; 51]` ## General subsidy From 6c97019dca834c91b2388256ef2c66f01c71769d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 14 Oct 2020 09:19:05 -0300 Subject: [PATCH 33/62] add errors --- book/src/dev/rfcs/xxxx-block-subsidy.md | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index a765235c22f..7d99ea6a8bc 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -245,6 +245,38 @@ https://zips.z.cash/zip-0213#specification This rules are implemented inside `shielded_coinbase()`. +### Validation errors + +A `SubsidyError` type will be created to handle validation of the above consensus rules: + +``` +pub enum SubsidyError { + #[error("not a coinbase transaction")] + NoCoinbase, + + #[error("founders reward amount not found")] + FoundersRewardAmountNotFound, + + #[error("founders reward address not found")] + FoundersRewardAddressNotFound, + + #[error("founding stream amount not found")] + FundingStreamAmountNotFound, + + #[error("founding stream address not found")] + FundingStreamAddressNotFound, + + #[error("the sum of outputs is greater than calculated subsidies and transaction fees.")] + MinerSubsidyRuleBroken, + + #[error("invalid shielded descriptions found.")] + ShieldedDescriptionsInvalid, + + #[error("broken rule in shielded transaction inside coinbase.")] + ShieldedRuleBroken, +} +``` + ## Test Plan For each network(Mainnet, Testnet), calculation of subsidy amounts need a `Height` as input and will output different amounts according to it. @@ -258,3 +290,7 @@ For each network, the address of the reward receiver on each block will depend o Validation tests will test the consensus rules using real blocks from `zebra-test` crate. For both networks, blocks for all network upgrades were added to the crate in [#1096](https://github.com/ZcashFoundation/zebra/pull/1096). Blocks containing shielded coinbase were also introduced at [#1116](https://github.com/ZcashFoundation/zebra/pull/1116) - Test validation functions(`subsidy_is_valid()`) against all the blocks zebra haves available in the test vectors collection for both networks(`zebra_test::vectors::MAINNET_BLOCKS` and `zebra_test::vectors::TESTNET_BLOCKS`), all blocks should pass validation. + +The validation errors at `SubsidyError` must be tested at least once. + +- Create tests to trigger each error from `SubsidyError`. From 6304a813a0c50c915bca07472a710d2228e81349 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 15 Oct 2020 09:52:06 -0300 Subject: [PATCH 34/62] remove ending dot for error descriptions Co-authored-by: Jane Lusby --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 7d99ea6a8bc..c6d9f95399d 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -266,13 +266,13 @@ pub enum SubsidyError { #[error("founding stream address not found")] FundingStreamAddressNotFound, - #[error("the sum of outputs is greater than calculated subsidies and transaction fees.")] + #[error("the sum of outputs is greater than calculated subsidies and transaction fees")] MinerSubsidyRuleBroken, - #[error("invalid shielded descriptions found.")] + #[error("invalid shielded descriptions found")] ShieldedDescriptionsInvalid, - #[error("broken rule in shielded transaction inside coinbase.")] + #[error("broken rule in shielded transaction inside coinbase")] ShieldedRuleBroken, } ``` From 5ee8efcb4c36f7468dfe8625b0edc80d58f6a4ca Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 20 Oct 2020 11:43:24 -0300 Subject: [PATCH 35/62] modify founders reward --- book/src/dev/rfcs/xxxx-block-subsidy.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index c6d9f95399d..4ffe2038b5b 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -102,9 +102,9 @@ To do the calculations and checks the following constants, types and functions n - `PRE_BLOSSOM_HALVING_INTERVAL: Height` - `POST_BLOSSOM_HALVING_INTERVAL: Height` - `FOUNDERS_FRACTION_DIVISOR: u64` -- `FOUNDER_ADDRESS_CHANGE_INTERVAL: u64` -- `FOUNDER_ADDRESSES_MAINNET: [&'static str; 48]` -- `FOUNDER_ADDRESSES_TESTNET: [&'static str; 48]` +- `FOUNDERS_ADDRESS_COUNT: u32` +- `FOUNDER_ADDRESSES_MAINNET: [&str; 48]` +- `FOUNDER_ADDRESSES_TESTNET: [&str; 48]` ### Funding streams parameter constants @@ -156,12 +156,12 @@ https://zips.z.cash/zip-0214#mainnet-recipient-addresses The following constants are needed: -- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&'static str; 48]` -- `FUNDING_STREAM_ZF_ADDRESSES_MAINNET: [&'static str; 48]` -- `FUNDING_STREAM_MG_ADDRESSES_MAINNET: [&'static str; 48]` -- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&'static str; 51]` -- `FUNDING_STREAM_ZF_ADDRESSES_TESTNET: [&'static str; 51]` -- `FUNDING_STREAM_MG_ADDRESSES_TESTNET: [&'static str; 51]` +- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&str; 48]` +- `FUNDING_STREAM_ZF_ADDRESSES_MAINNET: [&str; 48]` +- `FUNDING_STREAM_MG_ADDRESSES_MAINNET: [&str; 48]` +- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&str; 51]` +- `FUNDING_STREAM_ZF_ADDRESSES_TESTNET: [&str; 51]` +- `FUNDING_STREAM_MG_ADDRESSES_TESTNET: [&str; 51]` ## General subsidy @@ -185,7 +185,9 @@ Only functions specific to calculation of founders reward. https://zips.z.cash/protocol/canopy.pdf#foundersreward - `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block. +- `founders_address_change_interval() -> Height` - Calculates the founders reward change interval. `FounderAddressChangeInterval` in the protocol specs. - `founders_reward_address(Height, Network) -> Result` - Address of the receiver founder at this block. All specified founders reward addresses are transparent `zebra_chain::transparent:Address::PayToScriptHash` addresses. (Even after the shielded coinbase changes in ZIP-213, introduced in Heartwood.) +- `find_output_with_address(&Transaction, Address)` - Outputs where `lock_script` equal to `Address`. ## Funding streams From 2c99a7f557aaa13800a63fc689a78295fda4b408 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 22 Oct 2020 21:38:58 -0300 Subject: [PATCH 36/62] Apply suggestions from code review Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 4ffe2038b5b..25d558f6498 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -278,6 +278,16 @@ pub enum SubsidyError { ShieldedRuleBroken, } ``` +## Implementation Plan + +1. Founders Reward Amounts +2. Founders Reward Addresses +3. Funding Streams Amounts (defer Shielded Coinbase) +4. Funding Streams Addresses +5. Miner Subsidy Amounts (defer Shielded Coinbase) +6. Shielded Coinbase for Funding Streams and Miner Subsidy + +Each stage should have code, unit tests, block test vector tests, and property tests, before moving on to the next stage. (A stage can be implemented in multiple PRs.) ## Test Plan @@ -296,3 +306,6 @@ Validation tests will test the consensus rules using real blocks from `zebra-tes The validation errors at `SubsidyError` must be tested at least once. - Create tests to trigger each error from `SubsidyError`. + +- Create a property test for each consensus rule, which makes sure that the rule is satisfied by arbitrary (randomised) blocks and transactions + - Create or update `Arbitrary` trait implementations for blocks and transactions, as needed From 617b3fec256bf54359da07856508bede8744177d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 27 Oct 2020 17:58:58 -0300 Subject: [PATCH 37/62] change ECC to BP --- book/src/dev/rfcs/xxxx-block-subsidy.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 25d558f6498..438e2e3ecc3 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -114,7 +114,7 @@ The design suggests to implement the parameters needed for funding streams as: /// The funding stream receiver categories #[allow(missing_docs)] pub enum FundingStreamReceiver { - ElectricCoinCompany, + BootstrapProject, ZcashFoundation, MajorGrants, } @@ -124,7 +124,7 @@ pub enum FundingStreamReceiver { /// /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(FundingStreamReceiver, u64)] = &[ - (FundingStreamReceiver::ElectricCoinCompany, 7), + (FundingStreamReceiver::BootstrapProject, 7), (FundingStreamReceiver::ZcashFoundation, 5), (FundingStreamReceiver::MajorGrants, 8), ]; @@ -156,10 +156,10 @@ https://zips.z.cash/zip-0214#mainnet-recipient-addresses The following constants are needed: -- `FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&str; 48]` +- `FUNDING_STREAM_BP_ADDRESSES_MAINNET: [&str; 48]` - `FUNDING_STREAM_ZF_ADDRESSES_MAINNET: [&str; 48]` - `FUNDING_STREAM_MG_ADDRESSES_MAINNET: [&str; 48]` -- `FUNDING_STREAM_ECC_ADDRESSES_TESTNET: [&str; 51]` +- `FUNDING_STREAM_BP_ADDRESSES_TESTNET: [&str; 51]` - `FUNDING_STREAM_ZF_ADDRESSES_TESTNET: [&str; 51]` - `FUNDING_STREAM_MG_ADDRESSES_TESTNET: [&str; 51]` From a30af1be60ac7b66e51d0136ed20d10e5d392553 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 5 Nov 2020 12:40:34 -0300 Subject: [PATCH 38/62] add note about state needed for transparent pool --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 438e2e3ecc3..47300548e5f 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -53,6 +53,8 @@ https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. +**Note:** To compute the transparent value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC and they will not be described. + # Guide-level explanation [guide-level-explanation]: #guide-level-explanation From 648e3f43659bbfc3489ba96494b8a5c28fb39d5c Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 10 Nov 2020 08:09:51 -0300 Subject: [PATCH 39/62] Apply suggestions from code review Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 42 +++++++------------------ 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 47300548e5f..0105e2c3a44 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -53,7 +53,7 @@ https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. -**Note:** To compute the transparent value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC and they will not be described. +**Note:** To compute the transparent value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC. They will be documented in a separate contextual validation RFC. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -89,7 +89,7 @@ It is important to note that all blocks before Sapling are verified by the Check # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -Given the module structure proposed above all the block subsidy calculations from the protocol must be implemented. The final goal is to do checks for each incoming block and make sure they pass the consensus rules. +Given the module structure proposed above, the block subsidy calculations from the protocol must be implemented. The final goal is to do semantic validation for each incoming block and make sure they pass the consensus rules. To do the calculations and checks the following constants, types and functions need to be introduced: @@ -114,7 +114,6 @@ The design suggests to implement the parameters needed for funding streams as: ``` /// The funding stream receiver categories -#[allow(missing_docs)] pub enum FundingStreamReceiver { BootstrapProject, ZcashFoundation, @@ -136,11 +135,6 @@ const FUNDING_STREAM_RECEIVER_NUMERATORS: &[(FundingStreamReceiver, u64)] = &[ /// [7.9.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100; -#[allow(missing_docs)] -pub enum FundingStreamRange { - StartHeight, - EndHeight, -} /// Start and end Heights for funding streams /// as described in [protocol specification §7.9.1][7.9.1]. @@ -167,7 +161,7 @@ The following constants are needed: ## General subsidy -The block subsidy and miner reward among other utility functions are inside the general subsidy category. +The block subsidy and other utility functions are inside the general subsidy category. https://zips.z.cash/protocol/canopy.pdf#subsidyconcepts @@ -175,8 +169,6 @@ https://zips.z.cash/protocol/canopy.pdf#subsidies - `block_subsidy(Height, Network) -> Result, Error>` - Total block subsidy. - `miner_subsidy(Height, Network) -> Result, Error>` - Miner portion. -- `miner_fees(&Block) -> Result, Error>` - Total block fees calculated as [Transparent value pool calculation](#transparent-value-pool-calculation) that belongs to the miner. -- `coinbase_sum_outputs(&Transaction) -> Result, Error>` - Sum of all output values in the coinbase transaction. - `find_output_with_amount(&Transaction, Amount) -> Vec` - Outputs where value equal to Amount. - `shielded_coinbase(Height, Network, &Transaction) -> Result<(), Error>` - Validate shielded coinbase rules. @@ -225,18 +217,6 @@ height, that pays `fs.Value(height)` zatoshi in the prescribed way to the stream We make use of the funding streams functions here, similar to founders reward . We get the amount of the reward using `funding_stream(height, network)` and then the address with `funding_stream_address(height, network)`. Next we get a list of outputs that match the amount with the utility function `find_output_with_amount()`. Finally with this list, we check if any of the output scripts matches the address we have computed. -### 3 - Miner subsidy: - -*The total amount of transparent outputs from a coinbase transaction, minus the amount of the `valueBalance` field if present, **MUST NOT** be greater than the amount of miner subsidy plus the total amount of transaction fees paid by transactions in this block.* https://zips.z.cash/protocol/canopy.pdf#txnencodingandconsensus - -So the rule is the following before Canopy: - -`coinbase_sum_outputs() <= miner_subsidy() + founders_reward() + transaction_fees()` - -and after Canopy: - -`coinbase_sum_outputs() <= miner_subsidy() + funding_stream() + transaction_fees()` - ### 4 - Shielded coinbase: *[Pre-Heartwood] A coinbase transaction MUST NOT have any JoinSplit descriptions, Spend descriptions, or Output descriptions.* @@ -264,15 +244,12 @@ pub enum SubsidyError { #[error("founders reward address not found")] FoundersRewardAddressNotFound, - #[error("founding stream amount not found")] + #[error("funding stream amount not found")] FundingStreamAmountNotFound, - #[error("founding stream address not found")] + #[error("funding stream address not found")] FundingStreamAddressNotFound, - #[error("the sum of outputs is greater than calculated subsidies and transaction fees")] - MinerSubsidyRuleBroken, - #[error("invalid shielded descriptions found")] ShieldedDescriptionsInvalid, @@ -286,8 +263,11 @@ pub enum SubsidyError { 2. Founders Reward Addresses 3. Funding Streams Amounts (defer Shielded Coinbase) 4. Funding Streams Addresses -5. Miner Subsidy Amounts (defer Shielded Coinbase) -6. Shielded Coinbase for Funding Streams and Miner Subsidy +5. Shielded Coinbase for Funding Streams + +The following contextual validation checks are out of scope for this RFC: +* Miner Subsidy Amounts +* Shielded Coinbase for Miner Subsidy Each stage should have code, unit tests, block test vector tests, and property tests, before moving on to the next stage. (A stage can be implemented in multiple PRs.) @@ -295,7 +275,7 @@ Each stage should have code, unit tests, block test vector tests, and property t For each network(Mainnet, Testnet), calculation of subsidy amounts need a `Height` as input and will output different amounts according to it. -- Test all subsidy amount functions(`block_subsidy()`, `miner_subsidy()`, `founders_reward()` and `funding_stream()`) against all network upgrade events of each network and make sure they return the expected amounts according to known outputs. +- Test all subsidy amount functions(`block_subsidy()`, `founders_reward()` and `funding_stream()`) against all network upgrade events of each network and make sure they return the expected amounts according to known outputs. For each network, the address of the reward receiver on each block will depend on the `Height`. From 60eda9c1e783deee3ffc1198e335c73121b69ee1 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 10 Nov 2020 08:24:37 -0300 Subject: [PATCH 40/62] split constants --- book/src/dev/rfcs/xxxx-block-subsidy.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 0105e2c3a44..1043cdf875d 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -95,6 +95,8 @@ To do the calculations and checks the following constants, types and functions n ## Constants +### General + - `SLOW_START_INTERVAL: Height` - `SLOW_START_SHIFT: Height` - `MAX_BLOCK_SUBSIDY: u64` @@ -103,12 +105,15 @@ To do the calculations and checks the following constants, types and functions n - `BLOSSOM_POW_TARGET_SPACING_RATIO: u64` - `PRE_BLOSSOM_HALVING_INTERVAL: Height` - `POST_BLOSSOM_HALVING_INTERVAL: Height` + +### Founders Rewards + - `FOUNDERS_FRACTION_DIVISOR: u64` - `FOUNDERS_ADDRESS_COUNT: u32` - `FOUNDER_ADDRESSES_MAINNET: [&str; 48]` - `FOUNDER_ADDRESSES_TESTNET: [&str; 48]` -### Funding streams parameter constants +### Funding streams The design suggests to implement the parameters needed for funding streams as: From 978005e20f58c822eff39613e9288ff3a3840c1d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 10 Nov 2020 09:51:07 -0300 Subject: [PATCH 41/62] Update book/src/dev/rfcs/xxxx-block-subsidy.md Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 1043cdf875d..b061c827d6b 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -222,7 +222,7 @@ height, that pays `fs.Value(height)` zatoshi in the prescribed way to the stream We make use of the funding streams functions here, similar to founders reward . We get the amount of the reward using `funding_stream(height, network)` and then the address with `funding_stream_address(height, network)`. Next we get a list of outputs that match the amount with the utility function `find_output_with_amount()`. Finally with this list, we check if any of the output scripts matches the address we have computed. -### 4 - Shielded coinbase: +### 3 - Shielded coinbase: *[Pre-Heartwood] A coinbase transaction MUST NOT have any JoinSplit descriptions, Spend descriptions, or Output descriptions.* From 5eb45fc312899c2de710b445bdd22a04192991af Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 10 Nov 2020 12:49:22 -0300 Subject: [PATCH 42/62] Update book/src/dev/rfcs/xxxx-block-subsidy.md Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index b061c827d6b..afc171207a3 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -100,8 +100,6 @@ To do the calculations and checks the following constants, types and functions n - `SLOW_START_INTERVAL: Height` - `SLOW_START_SHIFT: Height` - `MAX_BLOCK_SUBSIDY: u64` -- `PRE_BLOSSOM_POW_TARGET_SPACING: Duration` -- `POST_BLOSSOM_POW_TARGET_SPACING: Duration` - `BLOSSOM_POW_TARGET_SPACING_RATIO: u64` - `PRE_BLOSSOM_HALVING_INTERVAL: Height` - `POST_BLOSSOM_HALVING_INTERVAL: Height` From 357406a45e5e6d9a01e568a3762203474b7fc5f3 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 09:40:02 +1000 Subject: [PATCH 43/62] Tweak block subsidy RFC wording Co-authored-by: Jane Lusby --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index afc171207a3..aa65e99da8d 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -12,7 +12,7 @@ Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/b # Motivation [motivation]: #motivation -All incoming blocks must be validated with the protocol specifications, there is no way to avoid this logic to be present in any Zcash protocol compatible implementation such as Zebra. +All incoming blocks must be validated with the protocol specifications, there is no way to avoid including this logic in any Zcash protocol compatible implementation such as Zebra. Block subsidy and miner fees are part of the protocol, the semantic verification of them apply to the coinbase transaction and they must be verified in Zebra. From d3a3930bcc8136bbe8c441f025b4d736b0161515 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 10:05:29 +1000 Subject: [PATCH 44/62] Spacing --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index aa65e99da8d..9a1d0af2905 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -7,7 +7,7 @@ [summary]: #summary -Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/blob/main/book/src/dev/rfcs/0002-parallel-verification.md#definitions) in the `zebra-consensus` crate, this is done for all incoming blocks. Inside each block the coinbase transaction is special, it holds the subsidy rewards that are paid to different participants(miners, founders, funding stream receivers). This RFC describes how to implement the needed calculations and verification for block subsidy and miner fees. +Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/blob/main/book/src/dev/rfcs/0002-parallel-verification.md#definitions) in the `zebra-consensus` crate, this is done for all incoming blocks. Inside each block the coinbase transaction is special, it holds the subsidy rewards that are paid to different participants (miners, founders, funding stream receivers). This RFC describes how to implement the needed calculations and verification for block subsidy and miner fees. # Motivation [motivation]: #motivation From 574a259867065722710b004ba631095556974b3f Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 10:07:24 +1000 Subject: [PATCH 45/62] Clarify transaction fees definition --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 9a1d0af2905..20f9c097a73 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -25,7 +25,7 @@ Block subsidy and miner fees are part of the protocol, the semantic verification - **block subsidy**: Miner subsidy plus founders reward or funding stream if any of the 2 are active. - **coinbase transaction**: The first transaction in a block; this is the transaction that handles block subsidy. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. -- **miner fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) amounts, for all the transactions in a block. +- **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded valueBalance amounts, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. ### Transparent value pool calculation From 9ae33210558064c25ee74c3fdd28ad8d1f1698c0 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 10:09:03 +1000 Subject: [PATCH 46/62] Use consistent fee terminology --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 20f9c097a73..2e4b7a7d414 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -27,7 +27,7 @@ Block subsidy and miner fees are part of the protocol, the semantic verification - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. - **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded valueBalance amounts, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. -### Transparent value pool calculation +### Transaction fees calculation There is a "transparent value pool" inside each transaction, containing "funds in motion" (distinct from the actual transparent value pool of UTXOs, being "funds at rest"). Balance of that pool works as follows: From 4df5d82dbd8198f9f793e738de30501cef79fd01 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 10:10:38 +1000 Subject: [PATCH 47/62] Clarify transparent value pool --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 2e4b7a7d414..095c7379eb5 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -29,7 +29,7 @@ Block subsidy and miner fees are part of the protocol, the semantic verification ### Transaction fees calculation -There is a "transparent value pool" inside each transaction, containing "funds in motion" (distinct from the actual transparent value pool of UTXOs, being "funds at rest"). Balance of that pool works as follows: +There is a value pool inside each transaction, containing "funds in motion" (distinct from the actual value pools of transparent and shielded UTXOs, being "funds at rest"). Balance of that pool works as follows: Transparent: From ccd9118f73ad3df456d560b5dcc78b1842d43120 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 10:14:05 +1000 Subject: [PATCH 48/62] Revise implementation plan based on latest priorities --- book/src/dev/rfcs/xxxx-block-subsidy.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 095c7379eb5..86a8c94ab45 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -262,15 +262,19 @@ pub enum SubsidyError { ``` ## Implementation Plan -1. Founders Reward Amounts -2. Founders Reward Addresses -3. Funding Streams Amounts (defer Shielded Coinbase) -4. Funding Streams Addresses -5. Shielded Coinbase for Funding Streams +Required: +1. Funding Streams Amounts (defer Shielded Coinbase) +2. Funding Streams Addresses +3. Shielded Coinbase for Funding Streams +4. Miner Subsidy Amounts +5. Shielded Coinbase for Miner Subsidy + +Optional - might be replaced by a Canopy checkpoint: +A. Founders Reward Amounts +B. Founders Reward Addresses The following contextual validation checks are out of scope for this RFC: -* Miner Subsidy Amounts -* Shielded Coinbase for Miner Subsidy +* Transaction Fees Each stage should have code, unit tests, block test vector tests, and property tests, before moving on to the next stage. (A stage can be implemented in multiple PRs.) From b0741062a0c1378bfc4d76457f954759ec31050e Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 22 Feb 2021 10:16:56 +1000 Subject: [PATCH 49/62] Change tests based on new priorities --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 86a8c94ab45..9741e482ad4 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -282,11 +282,13 @@ Each stage should have code, unit tests, block test vector tests, and property t For each network(Mainnet, Testnet), calculation of subsidy amounts need a `Height` as input and will output different amounts according to it. -- Test all subsidy amount functions(`block_subsidy()`, `founders_reward()` and `funding_stream()`) against all network upgrade events of each network and make sure they return the expected amounts according to known outputs. +- Test all subsidy amount functions(`block_subsidy()`, `miner_subsidy()` and `funding_stream()`) against all network upgrade events of each network and make sure they return the expected amounts according to known outputs. For each network, the address of the reward receiver on each block will depend on the `Height`. -- Test all subsidy address functions(`founders_reward_address()` and `funding_stream_address()`) against all network upgrade events of each network and make sure they return the expected addresses. +- Test the subsidy address function (`funding_stream_address()`) against all network upgrade events of each network and make sure they return the expected addresses. + +- Note: the founders reward tests are a low priority. Validation tests will test the consensus rules using real blocks from `zebra-test` crate. For both networks, blocks for all network upgrades were added to the crate in [#1096](https://github.com/ZcashFoundation/zebra/pull/1096). Blocks containing shielded coinbase were also introduced at [#1116](https://github.com/ZcashFoundation/zebra/pull/1116) From 531de21dd1f02c54a09c9dc0f7895490473b12ec Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 23 Feb 2021 06:30:55 +1000 Subject: [PATCH 50/62] Fix markdown Co-authored-by: Alfredo Garcia --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 9741e482ad4..5678b1488b6 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -270,8 +270,8 @@ Required: 5. Shielded Coinbase for Miner Subsidy Optional - might be replaced by a Canopy checkpoint: -A. Founders Reward Amounts -B. Founders Reward Addresses +1. Founders Reward Amounts +2. Founders Reward Addresses The following contextual validation checks are out of scope for this RFC: * Transaction Fees From 07634b4c9436b839e271009eb673459cb4740552 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 23 Feb 2021 06:31:34 +1000 Subject: [PATCH 51/62] Fix value pool description --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 5678b1488b6..334aad87eb4 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -53,7 +53,7 @@ https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. -**Note:** To compute the transparent value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC. They will be documented in a separate contextual validation RFC. +**Note:** To compute the value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC. They will be documented in a separate contextual validation RFC. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation From 55c67a0e22eb603e1f8f172a74e2bf3df165542c Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 16:54:47 -0300 Subject: [PATCH 52/62] update some definitions --- book/src/dev/rfcs/xxxx-block-subsidy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 334aad87eb4..47636b1a213 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -19,11 +19,11 @@ Block subsidy and miner fees are part of the protocol, the semantic verification # Definitions [definitions]: #definitions -- **founders reward**: The portion of the block reward that goes into a pre defined founder address. -- **funding streams**: The portion of the block reward that goes into a pre defined funding stream address. -- **miner subsidy**: The portion of the block reward that goes into the miner of the block. - **block subsidy**: Miner subsidy plus founders reward or funding stream if any of the 2 are active. - **coinbase transaction**: The first transaction in a block; this is the transaction that handles block subsidy. +- **founders reward**: The portion of the block subsidy that goes into a pre defined founder address in a single output. +- **funding streams**: The portion of the block subsidy that goes into one or more pre defined funding stream addresses. Payment is done with one output for each active funding stream of the block. +- **miner subsidy**: The portion of the block subsidy that goes into the miner of the block. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. - **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded valueBalance amounts, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. From 60f1d8ba97ea1970b494e6b8c15166f769815c96 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 17:15:51 -0300 Subject: [PATCH 53/62] change block and miner subsidy definitions --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 47636b1a213..421b4e28e3d 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -19,11 +19,11 @@ Block subsidy and miner fees are part of the protocol, the semantic verification # Definitions [definitions]: #definitions -- **block subsidy**: Miner subsidy plus founders reward or funding stream if any of the 2 are active. +- **block subsidy**: Value created from mining composed of miner subsidy plus founders reward or funding stream if any of the 2 are active ([Subsidy Concepts](https://zips.z.cash/protocol/protocol.pdf#subsidyconcepts)). - **coinbase transaction**: The first transaction in a block; this is the transaction that handles block subsidy. - **founders reward**: The portion of the block subsidy that goes into a pre defined founder address in a single output. - **funding streams**: The portion of the block subsidy that goes into one or more pre defined funding stream addresses. Payment is done with one output for each active funding stream of the block. -- **miner subsidy**: The portion of the block subsidy that goes into the miner of the block. +- **miner subsidy**: The portion of the block subsidy that goes into the miner of the block, excluding fees. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. - **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded valueBalance amounts, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. From 6e4489265a9ce812f4451e1069ebbc78c0a75366 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 17:53:12 -0300 Subject: [PATCH 54/62] fee pool definitions, fix all links to protocol --- book/src/dev/rfcs/xxxx-block-subsidy.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 421b4e28e3d..eb216676a88 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -25,31 +25,31 @@ Block subsidy and miner fees are part of the protocol, the semantic verification - **funding streams**: The portion of the block subsidy that goes into one or more pre defined funding stream addresses. Payment is done with one output for each active funding stream of the block. - **miner subsidy**: The portion of the block subsidy that goes into the miner of the block, excluding fees. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. -- **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded valueBalance amounts, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. +- **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded values, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. ### Transaction fees calculation -There is a value pool inside each transaction, containing "funds in motion" (distinct from the actual value pools of transparent and shielded UTXOs, being "funds at rest"). Balance of that pool works as follows: +There is a value pool inside each block called "[chain value pool balance](https://zips.z.cash/zip-0209#terminology)". Balance of that pool works as follows: Transparent: - `tx_in` adds to the pool. - `tx_out` subtracts from the pool. -https://zips.z.cash/protocol/canopy.pdf#txnencodingandconsensus +https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus Sprout: - `vpub_new` values from `vJoinSplit` of the transaction add to the pool. - `vpub_old` values from `vJoinSplit` of the transaction subtract from the pool. -https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus +https://zips.z.cash/protocol/protocol.pdf#joinsplitencodingandconsensus Sapling: - `valueBalance` adds to the pool. It itself is equal to `sum(SaplingSpends) - sum(SaplingOutputs)`, so it has the same functional effect as for transparent and Sprout. -https://zips.z.cash/protocol/canopy.pdf#joinsplitencodingandconsensus +https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. @@ -166,9 +166,9 @@ The following constants are needed: The block subsidy and other utility functions are inside the general subsidy category. -https://zips.z.cash/protocol/canopy.pdf#subsidyconcepts +https://zips.z.cash/protocol/protocol.pdf#subsidyconcepts -https://zips.z.cash/protocol/canopy.pdf#subsidies +https://zips.z.cash/protocol/protocol.pdf#subsidies - `block_subsidy(Height, Network) -> Result, Error>` - Total block subsidy. - `miner_subsidy(Height, Network) -> Result, Error>` - Miner portion. @@ -179,7 +179,7 @@ https://zips.z.cash/protocol/canopy.pdf#subsidies Only functions specific to calculation of founders reward. -https://zips.z.cash/protocol/canopy.pdf#foundersreward +https://zips.z.cash/protocol/protocol.pdf#foundersreward - `founders_reward(Height, Network) -> Result, Error>` - Founders reward portion for this block. - `founders_address_change_interval() -> Height` - Calculates the founders reward change interval. `FounderAddressChangeInterval` in the protocol specs. @@ -190,7 +190,7 @@ https://zips.z.cash/protocol/canopy.pdf#foundersreward Only functions specific to the calculation of funding streams. -https://zips.z.cash/protocol/canopy.pdf#fundingstreams +https://zips.z.cash/protocol/protocol.pdf#fundingstreams https://zips.z.cash/zip-0207 From ce81d5b240ed68ffd3b5a7c7ca0a0a5e696b2535 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 18:01:28 -0300 Subject: [PATCH 55/62] add reference to zip209 --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index eb216676a88..7fa1a2cfe63 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -51,7 +51,7 @@ Sapling: https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus -The balance rule is that this pool must have non-negative value, and its net value is the miner fee for the transaction. +The balance rule is that this pool must have non-negative value(See [ZIP 209](https://zips.z.cash/zip-0209)), and its net value is the miner fee for the transaction. **Note:** To compute the value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC. They will be documented in a separate contextual validation RFC. From 29bd28ef880319aac93436d5f36ed4da1d38f603 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 18:34:20 -0300 Subject: [PATCH 56/62] add note for MG stream number of addresses --- book/src/dev/rfcs/xxxx-block-subsidy.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 7fa1a2cfe63..e737fb2ca2f 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -149,7 +149,7 @@ const FUNDING_STREAM_HEIGHT_RANGES: &[(Network, Range<_>)] = &[ ]; ``` -Each `FundingStreamReceiver` for the mainnet must have 48 payment addresses associated with and 51 for the testnet. +Each `FundingStreamReceiver` for the mainnet must have 48 payment addresses associated with and 51 for the testnet.* https://zips.z.cash/zip-0214#mainnet-recipient-addresses @@ -162,6 +162,8 @@ The following constants are needed: - `FUNDING_STREAM_ZF_ADDRESSES_TESTNET: [&str; 51]` - `FUNDING_STREAM_MG_ADDRESSES_TESTNET: [&str; 51]` +\* The MG stream is subject to change. [ZIP 1014](https://zips.z.cash/zip-1014#direct-grant-option) and [ZIP 214](https://zips.z.cash/zip-0214) explicitly permit splitting the stream to allow for direct grant recipients that could change the number of addresses. This are not considered in this spec. + ## General subsidy The block subsidy and other utility functions are inside the general subsidy category. From 8f91397ee73a96bd583be5b61ff8925ed8b5e086 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 19:44:31 -0300 Subject: [PATCH 57/62] Be explicit in miner subsidy definition Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index e737fb2ca2f..4409c6ae338 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -23,7 +23,7 @@ Block subsidy and miner fees are part of the protocol, the semantic verification - **coinbase transaction**: The first transaction in a block; this is the transaction that handles block subsidy. - **founders reward**: The portion of the block subsidy that goes into a pre defined founder address in a single output. - **funding streams**: The portion of the block subsidy that goes into one or more pre defined funding stream addresses. Payment is done with one output for each active funding stream of the block. -- **miner subsidy**: The portion of the block subsidy that goes into the miner of the block, excluding fees. +- **miner subsidy**: The portion of the block subsidy that goes into the miner of the block, excluding fees. The miner may split this amount into any number of outputs, to any addresses, including extra outputs to founders rewards and funding stream addresses. - **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. - **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded values, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. From fc893e243bb67581c98bf796ced452dcb5940113 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 19:45:43 -0300 Subject: [PATCH 58/62] be more clear in NU definition Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 4409c6ae338..855620bf91a 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -24,7 +24,7 @@ Block subsidy and miner fees are part of the protocol, the semantic verification - **founders reward**: The portion of the block subsidy that goes into a pre defined founder address in a single output. - **funding streams**: The portion of the block subsidy that goes into one or more pre defined funding stream addresses. Payment is done with one output for each active funding stream of the block. - **miner subsidy**: The portion of the block subsidy that goes into the miner of the block, excluding fees. The miner may split this amount into any number of outputs, to any addresses, including extra outputs to founders rewards and funding stream addresses. -- **network upgrade**: An intentional consensus rule change undertaken by the community in order to improve the network. +- **network upgrade**: A rule change that creates a new consensus rule branch. Up-to-date nodes follow the new branch created by the network upgrade. - **transaction fees**: The sum of the extra [transparent value pool](#transparent-value-pool-calculation) and shielded values, for all the transactions in a block. This amount can be spent by the miner in the coinbase transaction. ### Transaction fees calculation From 62b3344f4d8605aad03133b8c0fa94cfb622d4a7 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 25 Feb 2021 20:39:31 -0300 Subject: [PATCH 59/62] Add extra checks Co-authored-by: teor --- book/src/dev/rfcs/xxxx-block-subsidy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index 855620bf91a..eb0ea57d71d 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -51,7 +51,7 @@ Sapling: https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus -The balance rule is that this pool must have non-negative value(See [ZIP 209](https://zips.z.cash/zip-0209)), and its net value is the miner fee for the transaction. +The balance rule is that this pool must have non-negative value (see [ZIP 209](https://zips.z.cash/zip-0209)), and its net value is the miner fee for the transaction. Non-negative transparent and block value pool balances are implied by the other consensus rules. Zebra should check or assert that these balances are non-negative, so invalid blocks don't pass verification. (And so that we guard against implementation bugs.) **Note:** To compute the value pool we need blockchain state. The `tx_in` is always a reference to a previous transaction output, this is different from Sprout and Sapling pools where everything we need is in the same transaction. The details about how this is going to be implemented are outside of the scope of this RFC. They will be documented in a separate contextual validation RFC. From dda122ccc744b1c2b68f35650bd649dc6e2abdea Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 30 Mar 2021 16:16:33 +1000 Subject: [PATCH 60/62] Mark as draft and update ticket and PR links --- book/src/dev/rfcs/xxxx-block-subsidy.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/xxxx-block-subsidy.md index eb0ea57d71d..866bb15b8e9 100644 --- a/book/src/dev/rfcs/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/xxxx-block-subsidy.md @@ -1,12 +1,17 @@ - Feature Name: Block subsidy - Start Date: 2020-10-05 -- Design PR: [ZcashFoundation/zebra#0000](https://github.com/ZcashFoundation/zebra/pull/0000) -- Zebra Issue: [ZcashFoundation/zebra#0000](https://github.com/ZcashFoundation/zebra/issues/0000) +- Design PR: [ZcashFoundation/zebra#1129](https://github.com/ZcashFoundation/zebra/pull/1129) +- Zebra Issue: [ZcashFoundation/zebra#338](https://github.com/ZcashFoundation/zebra/issues/338) + +# Draft + +Note: This is a draft Zebra RFC. See +[ZcashFoundation/zebra#338](https://github.com/ZcashFoundation/zebra/issues/338) +for more details. # Summary [summary]: #summary - Zebra manages [semantic verification](https://github.com/ZcashFoundation/zebra/blob/main/book/src/dev/rfcs/0002-parallel-verification.md#definitions) in the `zebra-consensus` crate, this is done for all incoming blocks. Inside each block the coinbase transaction is special, it holds the subsidy rewards that are paid to different participants (miners, founders, funding stream receivers). This RFC describes how to implement the needed calculations and verification for block subsidy and miner fees. # Motivation From fe59379533a0a64e21bfe30819abc32adaf88f13 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 30 Mar 2021 16:16:45 +1000 Subject: [PATCH 61/62] Rename book/src/dev/rfcs/xxxx-block-subsidy.md to book/src/dev/rfcs/drafts/xxxx-block-subsidy.md --- book/src/dev/rfcs/{ => drafts}/xxxx-block-subsidy.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename book/src/dev/rfcs/{ => drafts}/xxxx-block-subsidy.md (100%) diff --git a/book/src/dev/rfcs/xxxx-block-subsidy.md b/book/src/dev/rfcs/drafts/xxxx-block-subsidy.md similarity index 100% rename from book/src/dev/rfcs/xxxx-block-subsidy.md rename to book/src/dev/rfcs/drafts/xxxx-block-subsidy.md From eae0dabefd192dc55284209e0e1d2fe4ddf05adb Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 30 Mar 2021 16:24:03 +1000 Subject: [PATCH 62/62] Add some TODOs from outstanding comments --- book/src/dev/rfcs/drafts/xxxx-block-subsidy.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/book/src/dev/rfcs/drafts/xxxx-block-subsidy.md b/book/src/dev/rfcs/drafts/xxxx-block-subsidy.md index 866bb15b8e9..3819ba6a20e 100644 --- a/book/src/dev/rfcs/drafts/xxxx-block-subsidy.md +++ b/book/src/dev/rfcs/drafts/xxxx-block-subsidy.md @@ -123,7 +123,7 @@ The design suggests to implement the parameters needed for funding streams as: ``` /// The funding stream receiver categories pub enum FundingStreamReceiver { - BootstrapProject, + BootstrapProject, // TODO: it might be clearer to call this ECC, no-one uses the legal name ZcashFoundation, MajorGrants, } @@ -169,6 +169,8 @@ The following constants are needed: \* The MG stream is subject to change. [ZIP 1014](https://zips.z.cash/zip-1014#direct-grant-option) and [ZIP 214](https://zips.z.cash/zip-0214) explicitly permit splitting the stream to allow for direct grant recipients that could change the number of addresses. This are not considered in this spec. +TODO: describe how we would handle this sort of change. For example: add an enum to `FUNDING_STREAM_HEIGHT_RANGES` for each different stream split. + ## General subsidy The block subsidy and other utility functions are inside the general subsidy category.