docs: Transaction consensus rules: Header rules (#3456)
* refactor transaction header consensus rules * add a note * readd some docs Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
fa071562fd
commit
30ebab626a
|
|
@ -102,13 +102,13 @@ impl Block {
|
||||||
/// Check if the `network_upgrade` fields from each transaction in the block matches
|
/// Check if the `network_upgrade` fields from each transaction in the block matches
|
||||||
/// the network upgrade calculated from the `network` and block height.
|
/// the network upgrade calculated from the `network` and block height.
|
||||||
///
|
///
|
||||||
/// # Consensus rule:
|
/// # Consensus
|
||||||
///
|
///
|
||||||
/// The nConsensusBranchId field MUST match the consensus branch ID used for
|
/// > [NU5 onward] The nConsensusBranchId field MUST match the consensus branch ID used
|
||||||
/// SIGHASH transaction hashes, as specified in [ZIP-244] ([7.1]).
|
/// > for SIGHASH transaction hashes, as specified in [ZIP-244].
|
||||||
///
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/protocol.pdf#txnconsensus>
|
||||||
/// [ZIP-244]: https://zips.z.cash/zip-0244
|
/// [ZIP-244]: https://zips.z.cash/zip-0244
|
||||||
/// [7.1]: https://zips.z.cash/protocol/nu5.pdf#txnencodingandconsensus
|
|
||||||
pub fn check_transaction_network_upgrade_consistency(
|
pub fn check_transaction_network_upgrade_consistency(
|
||||||
&self,
|
&self,
|
||||||
network: Network,
|
network: Network,
|
||||||
|
|
|
||||||
|
|
@ -544,10 +544,38 @@ impl ZcashDeserialize for Transaction {
|
||||||
(header & LOW_31_BITS, header >> 31 != 0)
|
(header & LOW_31_BITS, header >> 31 != 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Consensus rules:
|
// # Consensus
|
||||||
|
//
|
||||||
|
// The next rules apply for different transaction versions as follows:
|
||||||
|
//
|
||||||
|
// [Pre-Overwinter]: Transactions version 1 and 2.
|
||||||
|
// [Overwinter onward]: Transactions version 3 and above.
|
||||||
|
// [Overwinter only, pre-Sapling]: Transactions version 3.
|
||||||
|
// [Sapling to Canopy inclusive, pre-NU5]: Transactions version 4.
|
||||||
|
// [NU5 onward]: Transactions version 4 and above.
|
||||||
|
//
|
||||||
// > The transaction version number MUST be greater than or equal to 1.
|
// > The transaction version number MUST be greater than or equal to 1.
|
||||||
// >
|
//
|
||||||
// > The overwintered flag MUST NOT be set for version 1 and 2 transactions.
|
// > [Pre-Overwinter] The fOverwintered fag MUST NOT be set.
|
||||||
|
//
|
||||||
|
// > [Overwinter onward] The version group ID MUST be recognized.
|
||||||
|
//
|
||||||
|
// > [Overwinter onward] The fOverwintered flag MUST be set.
|
||||||
|
//
|
||||||
|
// > [Overwinter only, pre-Sapling] The transaction version number MUST be 3,
|
||||||
|
// > and the version group ID MUST be 0x03C48270.
|
||||||
|
//
|
||||||
|
// > [Sapling to Canopy inclusive, pre-NU5] The transaction version number MUST be 4,
|
||||||
|
// > and the version group ID MUST be 0x892F2085.
|
||||||
|
//
|
||||||
|
// > [NU5 onward] The transaction version number MUST be 4 or 5.
|
||||||
|
// > If the transaction version number is 4 then the version group ID MUST be 0x892F2085.
|
||||||
|
// > If the transaction version number is 5 then the version group ID MUST be 0x26A7270A.
|
||||||
|
//
|
||||||
|
// Note: Zebra checkpoints until Canopy blocks, this means only transactions versions
|
||||||
|
// 4 and 5 get fully verified. This satisfies "The transaction version number MUST be 4"
|
||||||
|
// and "The transaction version number MUST be 4 or 5" from the last two rules above.
|
||||||
|
// This is done in the zebra-consensus crate, in the transactions checks.
|
||||||
//
|
//
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
||||||
match (version, overwintered) {
|
match (version, overwintered) {
|
||||||
|
|
@ -568,10 +596,6 @@ impl ZcashDeserialize for Transaction {
|
||||||
}
|
}
|
||||||
(3, true) => {
|
(3, true) => {
|
||||||
let id = limited_reader.read_u32::<LittleEndian>()?;
|
let id = limited_reader.read_u32::<LittleEndian>()?;
|
||||||
// Consensus rule:
|
|
||||||
// > [Overwinter only, pre-Sapling] The transaction version number MUST be 3, and the version group ID MUST be 0x03C48270.
|
|
||||||
//
|
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
|
||||||
if id != OVERWINTER_VERSION_GROUP_ID {
|
if id != OVERWINTER_VERSION_GROUP_ID {
|
||||||
return Err(SerializationError::Parse(
|
return Err(SerializationError::Parse(
|
||||||
"expected OVERWINTER_VERSION_GROUP_ID",
|
"expected OVERWINTER_VERSION_GROUP_ID",
|
||||||
|
|
@ -589,13 +613,6 @@ impl ZcashDeserialize for Transaction {
|
||||||
}
|
}
|
||||||
(4, true) => {
|
(4, true) => {
|
||||||
let id = limited_reader.read_u32::<LittleEndian>()?;
|
let id = limited_reader.read_u32::<LittleEndian>()?;
|
||||||
// Consensus rules:
|
|
||||||
// > [Sapling to Canopy inclusive, pre-NU5] The transaction version number MUST be 4, and the version group ID MUST be 0x892F2085.
|
|
||||||
// >
|
|
||||||
// > [NU5 onward] The transaction version number MUST be 4 or 5.
|
|
||||||
// > If the transaction version number is 4 then the version group ID MUST be 0x892F2085.
|
|
||||||
//
|
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
|
||||||
if id != SAPLING_VERSION_GROUP_ID {
|
if id != SAPLING_VERSION_GROUP_ID {
|
||||||
return Err(SerializationError::Parse(
|
return Err(SerializationError::Parse(
|
||||||
"expected SAPLING_VERSION_GROUP_ID",
|
"expected SAPLING_VERSION_GROUP_ID",
|
||||||
|
|
@ -666,13 +683,6 @@ impl ZcashDeserialize for Transaction {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(5, true) => {
|
(5, true) => {
|
||||||
// header
|
|
||||||
//
|
|
||||||
// Consensus rule:
|
|
||||||
// > [NU5 onward] The transaction version number MUST be 4 or 5. ...
|
|
||||||
// > If the transaction version number is 5 then the version group ID MUST be 0x26A7270A.
|
|
||||||
//
|
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
|
||||||
let id = limited_reader.read_u32::<LittleEndian>()?;
|
let id = limited_reader.read_u32::<LittleEndian>()?;
|
||||||
if id != TX_V5_VERSION_GROUP_ID {
|
if id != TX_V5_VERSION_GROUP_ID {
|
||||||
return Err(SerializationError::Parse("expected TX_V5_VERSION_GROUP_ID"));
|
return Err(SerializationError::Parse("expected TX_V5_VERSION_GROUP_ID"));
|
||||||
|
|
|
||||||
|
|
@ -231,8 +231,6 @@ pub fn time_is_valid_at(
|
||||||
///
|
///
|
||||||
/// # Consensus rules:
|
/// # Consensus rules:
|
||||||
///
|
///
|
||||||
/// - The nConsensusBranchId field MUST match the consensus branch ID used for
|
|
||||||
/// SIGHASH transaction hashes, as specified in [ZIP-244] ([7.1]).
|
|
||||||
/// - A SHA-256d hash in internal byte order. The merkle root is derived from the
|
/// - A SHA-256d hash in internal byte order. The merkle root is derived from the
|
||||||
/// hashes of all transactions included in this block, ensuring that none of
|
/// hashes of all transactions included in this block, ensuring that none of
|
||||||
/// those transactions can be modified without modifying the header. [7.6]
|
/// those transactions can be modified without modifying the header. [7.6]
|
||||||
|
|
|
||||||
|
|
@ -544,12 +544,19 @@ where
|
||||||
match network_upgrade {
|
match network_upgrade {
|
||||||
// Supports V4 transactions
|
// Supports V4 transactions
|
||||||
//
|
//
|
||||||
// Consensus rules:
|
// # Consensus
|
||||||
// > [Sapling to Canopy inclusive, pre-NU5] The transaction version number MUST be 4, ...
|
//
|
||||||
// >
|
// > [Sapling to Canopy inclusive, pre-NU5] The transaction version number MUST be 4,
|
||||||
|
// > and the version group ID MUST be 0x892F2085.
|
||||||
|
//
|
||||||
// > [NU5 onward] The transaction version number MUST be 4 or 5.
|
// > [NU5 onward] The transaction version number MUST be 4 or 5.
|
||||||
|
// > If the transaction version number is 4 then the version group ID MUST be 0x892F2085.
|
||||||
|
// > If the transaction version number is 5 then the version group ID MUST be 0x26A7270A.
|
||||||
//
|
//
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
||||||
|
//
|
||||||
|
// Note: Here we verify the transaction version number of the above two rules, the group
|
||||||
|
// id is checked in zebra-chain crate, in the transaction serialize.
|
||||||
NetworkUpgrade::Sapling
|
NetworkUpgrade::Sapling
|
||||||
| NetworkUpgrade::Blossom
|
| NetworkUpgrade::Blossom
|
||||||
| NetworkUpgrade::Heartwood
|
| NetworkUpgrade::Heartwood
|
||||||
|
|
@ -633,10 +640,16 @@ where
|
||||||
match network_upgrade {
|
match network_upgrade {
|
||||||
// Supports V5 transactions
|
// Supports V5 transactions
|
||||||
//
|
//
|
||||||
// Consensus rules:
|
// # Consensus
|
||||||
|
//
|
||||||
// > [NU5 onward] The transaction version number MUST be 4 or 5.
|
// > [NU5 onward] The transaction version number MUST be 4 or 5.
|
||||||
|
// > If the transaction version number is 4 then the version group ID MUST be 0x892F2085.
|
||||||
|
// > If the transaction version number is 5 then the version group ID MUST be 0x26A7270A.
|
||||||
//
|
//
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
||||||
|
//
|
||||||
|
// Note: Here we verify the transaction version number of the above rule, the group
|
||||||
|
// id is checked in zebra-chain crate, in the transaction serialize.
|
||||||
NetworkUpgrade::Nu5 => Ok(()),
|
NetworkUpgrade::Nu5 => Ok(()),
|
||||||
|
|
||||||
// Does not support V5 transactions
|
// Does not support V5 transactions
|
||||||
|
|
|
||||||
|
|
@ -319,8 +319,12 @@ pub fn coinbase_expiry_height(
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
// Consensus rule: [Overwinter to Canopy inclusive, pre-NU5] nExpiryHeight
|
// # Consensus
|
||||||
// MUST be less than or equal to 499999999.
|
//
|
||||||
|
// > [Overwinter to Canopy inclusive, pre-NU5] `nExpiryHeight` MUST be less than
|
||||||
|
// > or equal to 499999999.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
||||||
validate_expiry_height_max(expiry_height, true, block_height, coinbase)
|
validate_expiry_height_max(expiry_height, true, block_height, coinbase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -338,6 +342,19 @@ pub fn non_coinbase_expiry_height(
|
||||||
if transaction.is_overwintered() {
|
if transaction.is_overwintered() {
|
||||||
let expiry_height = transaction.expiry_height();
|
let expiry_height = transaction.expiry_height();
|
||||||
|
|
||||||
|
// # Consensus
|
||||||
|
//
|
||||||
|
// > [Overwinter to Canopy inclusive, pre-NU5] nExpiryHeight MUST be
|
||||||
|
// > less than or equal to 499999999.
|
||||||
|
//
|
||||||
|
// > [NU5 onward] nExpiryHeight MUST be less than or equal to 499999999
|
||||||
|
// > for non-coinbase transactions.
|
||||||
|
//
|
||||||
|
// > [Overwinter onward] If a transaction is not a coinbase transaction and its
|
||||||
|
// > nExpiryHeight field is nonzero, then it MUST NOT be mined at a block height
|
||||||
|
// > greater than its nExpiryHeight.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
|
||||||
validate_expiry_height_max(expiry_height, false, block_height, transaction)?;
|
validate_expiry_height_max(expiry_height, false, block_height, transaction)?;
|
||||||
validate_expiry_height_mined(expiry_height, block_height, transaction)?;
|
validate_expiry_height_mined(expiry_height, block_height, transaction)?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue