fix(doc): Fix various doc warnings, part 1 (#4514)
* Fix the syntax of links in comments * Fix a mistake in the docs Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Remove unnecessary angle brackets from a link * Revert the changes for links that serve as references * Revert "Revert the changes for links that serve as references" This reverts commit8b091aa9fa
. * Remove `<` `>` from links that serve as references This reverts commit046ef25620
. * Don't use `<` `>` in normal comments * Don't use `<` `>` for normal comments * Revert changes for comments starting with `//` * Fix some warnings produced by `cargo doc` * Fix some rustdoc warnings * Fix some warnings * Refactor some changes Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
This commit is contained in:
parent
6f08abde7a
commit
b8b35f8da9
|
@ -111,6 +111,7 @@ impl Block {
|
||||||
/// > for SIGHASH transaction hashes, as specified in [ZIP-244].
|
/// > for SIGHASH transaction hashes, as specified in [ZIP-244].
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/protocol.pdf#txnconsensus>
|
/// <https://zips.z.cash/protocol/protocol.pdf#txnconsensus>
|
||||||
|
///
|
||||||
/// [ZIP-244]: https://zips.z.cash/zip-0244
|
/// [ZIP-244]: https://zips.z.cash/zip-0244
|
||||||
pub fn check_transaction_network_upgrade_consistency(
|
pub fn check_transaction_network_upgrade_consistency(
|
||||||
&self,
|
&self,
|
||||||
|
@ -154,7 +155,7 @@ impl Block {
|
||||||
|
|
||||||
/// Count how many Sapling transactions exist in a block,
|
/// Count how many Sapling transactions exist in a block,
|
||||||
/// i.e. transactions "where either of vSpendsSapling or vOutputsSapling is non-empty"
|
/// i.e. transactions "where either of vSpendsSapling or vOutputsSapling is non-empty"
|
||||||
/// (https://zips.z.cash/zip-0221#tree-node-specification).
|
/// <https://zips.z.cash/zip-0221#tree-node-specification>.
|
||||||
pub fn sapling_transactions_count(&self) -> u64 {
|
pub fn sapling_transactions_count(&self) -> u64 {
|
||||||
self.transactions
|
self.transactions
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -166,7 +167,7 @@ impl Block {
|
||||||
|
|
||||||
/// Count how many Orchard transactions exist in a block,
|
/// Count how many Orchard transactions exist in a block,
|
||||||
/// i.e. transactions "where vActionsOrchard is non-empty."
|
/// i.e. transactions "where vActionsOrchard is non-empty."
|
||||||
/// (https://zips.z.cash/zip-0221#tree-node-specification).
|
/// <https://zips.z.cash/zip-0221#tree-node-specification>.
|
||||||
pub fn orchard_transactions_count(&self) -> u64 {
|
pub fn orchard_transactions_count(&self) -> u64 {
|
||||||
self.transactions
|
self.transactions
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -187,7 +188,7 @@ impl Block {
|
||||||
///
|
///
|
||||||
/// <https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions>
|
/// <https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions>
|
||||||
///
|
///
|
||||||
/// `utxos` must contain the [`Utxo`]s of every input in this block,
|
/// `utxos` must contain the [`transparent::Utxo`]s of every input in this block,
|
||||||
/// including UTXOs created by earlier transactions in this block.
|
/// including UTXOs created by earlier transactions in this block.
|
||||||
/// (It can also contain unrelated UTXOs, which are ignored.)
|
/// (It can also contain unrelated UTXOs, which are ignored.)
|
||||||
///
|
///
|
||||||
|
|
|
@ -314,7 +314,7 @@ impl Arbitrary for LedgerState {
|
||||||
/// Generate an arbitrary [`LedgerState`].
|
/// Generate an arbitrary [`LedgerState`].
|
||||||
///
|
///
|
||||||
/// The default strategy arbitrarily skips some coinbase transactions, and
|
/// The default strategy arbitrarily skips some coinbase transactions, and
|
||||||
/// has an arbitrary start height. To override, use a specific [`LegderState`]
|
/// has an arbitrary start height. To override, use a specific [`LedgerState`]
|
||||||
/// strategy method.
|
/// strategy method.
|
||||||
fn arbitrary_with(ledger_override: Self::Parameters) -> Self::Strategy {
|
fn arbitrary_with(ledger_override: Self::Parameters) -> Self::Strategy {
|
||||||
(
|
(
|
||||||
|
@ -545,7 +545,7 @@ impl Block {
|
||||||
|
|
||||||
/// Fix `transaction` so it obeys more consensus rules.
|
/// Fix `transaction` so it obeys more consensus rules.
|
||||||
///
|
///
|
||||||
/// Spends [`OutPoint`]s from `utxos`, and adds newly created outputs.
|
/// Spends [`transparent::OutPoint`]s from `utxos`, and adds newly created outputs.
|
||||||
///
|
///
|
||||||
/// If the transaction can't be fixed, returns `None`.
|
/// If the transaction can't be fixed, returns `None`.
|
||||||
pub fn fix_generated_transaction<F, T, E>(
|
pub fn fix_generated_transaction<F, T, E>(
|
||||||
|
@ -625,7 +625,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a valid [`OutPoint`] in `utxos` to spend in `transaction`.
|
/// Find a valid [`transparent::OutPoint`] in `utxos` to spend in `transaction`.
|
||||||
///
|
///
|
||||||
/// Modifies `transaction` and updates `spend_restriction` if needed.
|
/// Modifies `transaction` and updates `spend_restriction` if needed.
|
||||||
///
|
///
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub enum Commitment {
|
||||||
/// need to verify the chain history root from `Canopy + 1 block` onwards,
|
/// need to verify the chain history root from `Canopy + 1 block` onwards,
|
||||||
/// using a new history tree based on the `Canopy` activation block.
|
/// using a new history tree based on the `Canopy` activation block.
|
||||||
///
|
///
|
||||||
/// NU5 and later upgrades use the [`ChainHistoryBlockTxAuthCommitment`]
|
/// NU5 and later upgrades use the [`Commitment::ChainHistoryBlockTxAuthCommitment`]
|
||||||
/// variant.
|
/// variant.
|
||||||
///
|
///
|
||||||
/// TODO: this field is verified during contextual verification
|
/// TODO: this field is verified during contextual verification
|
||||||
|
@ -85,7 +85,7 @@ pub enum Commitment {
|
||||||
/// This commitment supports the FlyClient protocol and non-malleable
|
/// This commitment supports the FlyClient protocol and non-malleable
|
||||||
/// transaction IDs. See ZIP-221 and ZIP-244 for details.
|
/// transaction IDs. See ZIP-221 and ZIP-244 for details.
|
||||||
///
|
///
|
||||||
/// See also the [`ChainHistoryRoot`] variant.
|
/// See also the [`Commitment::ChainHistoryRoot`] variant.
|
||||||
///
|
///
|
||||||
/// TODO: this field is verified during contextual verification
|
/// TODO: this field is verified during contextual verification
|
||||||
ChainHistoryBlockTxAuthCommitment(ChainHistoryBlockTxAuthCommitmentHash),
|
ChainHistoryBlockTxAuthCommitment(ChainHistoryBlockTxAuthCommitmentHash),
|
||||||
|
|
|
@ -53,9 +53,9 @@ pub struct Header {
|
||||||
/// Zcash blocks contain different kinds of commitments to their contents,
|
/// Zcash blocks contain different kinds of commitments to their contents,
|
||||||
/// depending on the network and height.
|
/// depending on the network and height.
|
||||||
///
|
///
|
||||||
/// The interpretation of this field has been changed multiple times, without
|
/// The interpretation of this field has been changed multiple times,
|
||||||
/// incrementing the block [`version`]. Therefore, this field cannot be
|
/// without incrementing the block [`version`](Self::version). Therefore,
|
||||||
/// parsed without the network and height. Use
|
/// this field cannot be parsed without the network and height. Use
|
||||||
/// [`Block::commitment`](super::Block::commitment) to get the parsed
|
/// [`Block::commitment`](super::Block::commitment) to get the parsed
|
||||||
/// [`Commitment`](super::Commitment).
|
/// [`Commitment`](super::Commitment).
|
||||||
pub commitment_bytes: [u8; 32],
|
pub commitment_bytes: [u8; 32],
|
||||||
|
|
|
@ -47,7 +47,7 @@ use crate::transaction::{self, Transaction};
|
||||||
/// > 1 2 3 4 5 6 1 2 3 4 5 6 5 6
|
/// > 1 2 3 4 5 6 1 2 3 4 5 6 5 6
|
||||||
/// > ```
|
/// > ```
|
||||||
/// >
|
/// >
|
||||||
/// > for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
|
/// > for transaction lists \[1,2,3,4,5,6\] and \[1,2,3,4,5,6,5,6\] (where 5 and
|
||||||
/// > 6 are repeated) result in the same root hash A (because the hash of both
|
/// > 6 are repeated) result in the same root hash A (because the hash of both
|
||||||
/// > of (F) and (F,F) is C).
|
/// > of (F) and (F,F) is C).
|
||||||
/// >
|
/// >
|
||||||
|
|
|
@ -54,7 +54,7 @@ enum InnerHistoryTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// History tree (Merkle mountain range) structure that contains information about
|
/// History tree (Merkle mountain range) structure that contains information about
|
||||||
/// the block history, as specified in [ZIP-221][https://zips.z.cash/zip-0221].
|
/// the block history, as specified in [ZIP-221](https://zips.z.cash/zip-0221).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NonEmptyHistoryTree {
|
pub struct NonEmptyHistoryTree {
|
||||||
network: Network,
|
network: Network,
|
||||||
|
@ -75,8 +75,8 @@ pub struct NonEmptyHistoryTree {
|
||||||
impl NonEmptyHistoryTree {
|
impl NonEmptyHistoryTree {
|
||||||
/// Recreate a [`HistoryTree`] from previously saved data.
|
/// Recreate a [`HistoryTree`] from previously saved data.
|
||||||
///
|
///
|
||||||
/// The parameters must come from the values of [HistoryTree::size],
|
/// The parameters must come from the values of [`NonEmptyHistoryTree::size`],
|
||||||
/// [HistoryTree::peaks] and [HistoryTree::current_height] of a HistoryTree.
|
/// [`NonEmptyHistoryTree::peaks`] and [`NonEmptyHistoryTree::current_height`] of a HistoryTree.
|
||||||
pub fn from_cache(
|
pub fn from_cache(
|
||||||
network: Network,
|
network: Network,
|
||||||
size: u32,
|
size: u32,
|
||||||
|
|
|
@ -91,12 +91,12 @@ impl ZcashDeserialize for Action {
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concreteorchardkeyagreement
|
// https://zips.z.cash/protocol/protocol.pdf#concreteorchardkeyagreement
|
||||||
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
||||||
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
||||||
// Type is `Sym.C`, i.e. `𝔹^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
// Type is `Sym.C`, i.e. `𝔹^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
// See [`note::EncryptedNote::zcash_deserialize`].
|
// See [`note::EncryptedNote::zcash_deserialize`].
|
||||||
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
||||||
// Type is `Sym.C`, i.e. `𝔹^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
// Type is `Sym.C`, i.e. `𝔹^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
||||||
|
|
|
@ -42,7 +42,7 @@ where
|
||||||
pub struct CommitmentRandomness(pallas::Scalar);
|
pub struct CommitmentRandomness(pallas::Scalar);
|
||||||
|
|
||||||
impl From<SeedRandomness> for CommitmentRandomness {
|
impl From<SeedRandomness> for CommitmentRandomness {
|
||||||
/// rcm = ToScalar^Orchard((PRF^expand_rseed ([5]))
|
/// rcm = ToScalar^Orchard((PRF^expand_rseed (\[5\]))
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
|
||||||
fn from(rseed: SeedRandomness) -> Self {
|
fn from(rseed: SeedRandomness) -> Self {
|
||||||
|
|
|
@ -253,7 +253,7 @@ impl From<SpendingKey> for SpendAuthorizingKey {
|
||||||
/// Invokes Blake2b-512 as _PRF^expand_, t=6, to derive a
|
/// Invokes Blake2b-512 as _PRF^expand_, t=6, to derive a
|
||||||
/// `SpendAuthorizingKey` from a `SpendingKey`.
|
/// `SpendAuthorizingKey` from a `SpendingKey`.
|
||||||
///
|
///
|
||||||
/// ask := ToScalar^Orchard(PRF^expand(sk, [6]))
|
/// ask := ToScalar^Orchard(PRF^expand(sk, \[6\]))
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
|
||||||
|
@ -380,7 +380,7 @@ impl From<[u8; 32]> for NullifierDerivingKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SpendingKey> for NullifierDerivingKey {
|
impl From<SpendingKey> for NullifierDerivingKey {
|
||||||
/// nk = ToBase^Orchard(PRF^expand_sk ([7]))
|
/// nk = ToBase^Orchard(PRF^expand_sk (\[7\]))
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
||||||
fn from(sk: SpendingKey) -> Self {
|
fn from(sk: SpendingKey) -> Self {
|
||||||
|
@ -429,7 +429,7 @@ impl fmt::Debug for IvkCommitRandomness {
|
||||||
impl Eq for IvkCommitRandomness {}
|
impl Eq for IvkCommitRandomness {}
|
||||||
|
|
||||||
impl From<SpendingKey> for IvkCommitRandomness {
|
impl From<SpendingKey> for IvkCommitRandomness {
|
||||||
/// rivk = ToScalar^Orchard(PRF^expand_sk ([8]))
|
/// rivk = ToScalar^Orchard(PRF^expand_sk (\[8\]))
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
||||||
fn from(sk: SpendingKey) -> Self {
|
fn from(sk: SpendingKey) -> Self {
|
||||||
|
@ -962,7 +962,7 @@ impl From<(IncomingViewingKey, Diversifier)> for TransmissionKey {
|
||||||
/// This includes _KA^Orchard.DerivePublic(ivk, G_d)_, which is just a
|
/// This includes _KA^Orchard.DerivePublic(ivk, G_d)_, which is just a
|
||||||
/// scalar mult _\[ivk\]G_d_.
|
/// scalar mult _\[ivk\]G_d_.
|
||||||
///
|
///
|
||||||
/// KA^Orchard.DerivePublic(sk, B) := [sk] B
|
/// KA^Orchard.DerivePublic(sk, B) := \[sk\] B
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
|
||||||
|
|
|
@ -83,7 +83,7 @@ impl From<Psi> for [u8; 32] {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SeedRandomness> for Psi {
|
impl From<SeedRandomness> for Psi {
|
||||||
/// rcm = ToScalar^Orchard((PRF^expand_rseed ([9]))
|
/// rcm = ToScalar^Orchard((PRF^expand_rseed (\[9\]))
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
|
||||||
fn from(rseed: SeedRandomness) -> Self {
|
fn from(rseed: SeedRandomness) -> Self {
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn poseidon_hash(_x: pallas::Base, _y: pallas::Base) -> pallas::Base {
|
||||||
/// PRF^nfOrchard: F_𝑞P × F_𝑞P → F_𝑞P
|
/// PRF^nfOrchard: F_𝑞P × F_𝑞P → F_𝑞P
|
||||||
///
|
///
|
||||||
/// Instantiated using the PoseidonHash hash function defined in [§5.4.1.10
|
/// Instantiated using the PoseidonHash hash function defined in [§5.4.1.10
|
||||||
/// ‘PoseidonHash Function’][poseidon]:
|
/// ‘PoseidonHash Function’][poseidonhash]:
|
||||||
///
|
///
|
||||||
/// PRF^nfOrchard(nk*, ρ*) := PoseidonHash(nk*, ρ*)
|
/// PRF^nfOrchard(nk*, ρ*) := PoseidonHash(nk*, ρ*)
|
||||||
///
|
///
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl AuthorizedAction {
|
||||||
/// Actions are 5 * 32 + 580 + 80 bytes so the total size of each Action is 820 bytes.
|
/// Actions are 5 * 32 + 580 + 80 bytes so the total size of each Action is 820 bytes.
|
||||||
/// [7.5 Action Description Encoding and Consensus][ps]
|
/// [7.5 Action Description Encoding and Consensus][ps]
|
||||||
///
|
///
|
||||||
/// [ps] <https://zips.z.cash/protocol/nu5.pdf#actionencodingandconsensus>
|
/// [ps]: <https://zips.z.cash/protocol/nu5.pdf#actionencodingandconsensus>
|
||||||
pub const ACTION_SIZE: u64 = 5 * 32 + 580 + 80;
|
pub const ACTION_SIZE: u64 = 5 * 32 + 580 + 80;
|
||||||
|
|
||||||
/// The size of a single Signature<SpendAuth>
|
/// The size of a single Signature<SpendAuth>
|
||||||
|
@ -170,7 +170,7 @@ pub const ACTION_SIZE: u64 = 5 * 32 + 580 + 80;
|
||||||
/// Each Signature is 64 bytes.
|
/// Each Signature is 64 bytes.
|
||||||
/// [7.1 Transaction Encoding and Consensus][ps]
|
/// [7.1 Transaction Encoding and Consensus][ps]
|
||||||
///
|
///
|
||||||
/// [ps] <https://zips.z.cash/protocol/nu5.pdf#actionencodingandconsensus>
|
/// [ps]: <https://zips.z.cash/protocol/nu5.pdf#actionencodingandconsensus>
|
||||||
pub const SPEND_AUTH_SIG_SIZE: u64 = 64;
|
pub const SPEND_AUTH_SIG_SIZE: u64 = 64;
|
||||||
|
|
||||||
/// The size of a single AuthorizedAction
|
/// The size of a single AuthorizedAction
|
||||||
|
|
|
@ -106,7 +106,7 @@ fn incomplete_addition(
|
||||||
/// the Sinsemilla hash for the Orchard incremental Merkle tree (§ 5.4.1.3
|
/// the Sinsemilla hash for the Orchard incremental Merkle tree (§ 5.4.1.3
|
||||||
/// ‘MerkleCRH^Orchard Hash Function’).
|
/// ‘MerkleCRH^Orchard Hash Function’).
|
||||||
///
|
///
|
||||||
/// SinsemillaHashToPoint(𝐷: B^Y^[N] , 𝑀 : B ^[{0 .. 𝑘·𝑐}] ) → P ∪ {⊥}
|
/// SinsemillaHashToPoint(𝐷: B^Y^\[N\] , 𝑀 : B ^[{0 .. 𝑘·𝑐}] ) → P ∪ {⊥}
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillahash>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillahash>
|
||||||
///
|
///
|
||||||
|
@ -147,7 +147,7 @@ pub fn sinsemilla_hash_to_point(D: &[u8], M: &BitVec<u8, Lsb0>) -> Option<pallas
|
||||||
/// PedersenHash) is to make efcient use of the lookups available in recent
|
/// PedersenHash) is to make efcient use of the lookups available in recent
|
||||||
/// proof systems including Halo 2."
|
/// proof systems including Halo 2."
|
||||||
///
|
///
|
||||||
/// SinsemillaHash: B^Y^[N] × B[{0 .. 𝑘·𝑐}] → P_𝑥 ∪ {⊥}
|
/// SinsemillaHash: B^Y^\[N\] × B[{0 .. 𝑘·𝑐}] → P_𝑥 ∪ {⊥}
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillahash>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillahash>
|
||||||
///
|
///
|
||||||
|
@ -165,7 +165,7 @@ pub fn sinsemilla_hash(D: &[u8], M: &BitVec<u8, Lsb0>) -> Option<pallas::Base> {
|
||||||
/// hash, and adding a randomized point on the Pallas curve (with complete
|
/// hash, and adding a randomized point on the Pallas curve (with complete
|
||||||
/// addition, vs incomplete addition as used in [`sinsemilla_hash_to_point`]).
|
/// addition, vs incomplete addition as used in [`sinsemilla_hash_to_point`]).
|
||||||
///
|
///
|
||||||
/// SinsemillaCommit_r(D, M) := SinsemillaHashToPoint(D || "-M", M) + [r]GroupHash^P(D || "-r", "")
|
/// SinsemillaCommit_r(D, M) := SinsemillaHashToPoint(D || "-M", M) + \[r\]GroupHash^P(D || "-r", "")
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit>
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
|
|
@ -287,8 +287,9 @@ pub struct NoteCommitmentTree {
|
||||||
/// serialized with the tree). This is particularly important since we decided
|
/// serialized with the tree). This is particularly important since we decided
|
||||||
/// to instantiate the trees from the genesis block, for simplicity.
|
/// to instantiate the trees from the genesis block, for simplicity.
|
||||||
///
|
///
|
||||||
/// We use a [`RwLock`] for this cache, because it is only written once per tree update.
|
/// We use a [`RwLock`](std::sync::RwLock) for this cache, because it is
|
||||||
/// Each tree has its own cached root, a new lock is created for each clone.
|
/// only written once per tree update. Each tree has its own cached root, a
|
||||||
|
/// new lock is created for each clone.
|
||||||
cached_root: std::sync::RwLock<Option<Root>>,
|
cached_root: std::sync::RwLock<Option<Root>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use proptest::prelude::*;
|
||||||
use super::NetworkUpgrade;
|
use super::NetworkUpgrade;
|
||||||
|
|
||||||
impl NetworkUpgrade {
|
impl NetworkUpgrade {
|
||||||
/// Generates network upgrades with [`BranchId`]s
|
/// Generates network upgrades.
|
||||||
pub fn branch_id_strategy() -> BoxedStrategy<NetworkUpgrade> {
|
pub fn branch_id_strategy() -> BoxedStrategy<NetworkUpgrade> {
|
||||||
prop_oneof![
|
prop_oneof![
|
||||||
Just(NetworkUpgrade::Overwinter),
|
Just(NetworkUpgrade::Overwinter),
|
||||||
|
|
|
@ -305,7 +305,8 @@ impl NetworkUpgrade {
|
||||||
/// Returns `true` if `height` is the activation height of any network upgrade
|
/// Returns `true` if `height` is the activation height of any network upgrade
|
||||||
/// on `network`.
|
/// on `network`.
|
||||||
///
|
///
|
||||||
/// Use [`activation_height`] to get the specific network upgrade.
|
/// Use [`NetworkUpgrade::activation_height`] to get the specific network
|
||||||
|
/// upgrade.
|
||||||
pub fn is_activation_height(network: Network, height: block::Height) -> bool {
|
pub fn is_activation_height(network: Network, height: block::Height) -> bool {
|
||||||
NetworkUpgrade::activation_list(network).contains_key(&height)
|
NetworkUpgrade::activation_list(network).contains_key(&height)
|
||||||
}
|
}
|
||||||
|
@ -331,8 +332,8 @@ impl NetworkUpgrade {
|
||||||
|
|
||||||
/// Returns the target block spacing for the network upgrade.
|
/// Returns the target block spacing for the network upgrade.
|
||||||
///
|
///
|
||||||
/// Based on `PRE_BLOSSOM_POW_TARGET_SPACING` and
|
/// Based on [`PRE_BLOSSOM_POW_TARGET_SPACING`] and
|
||||||
/// `POST_BLOSSOM_POW_TARGET_SPACING` from the Zcash specification.
|
/// [`POST_BLOSSOM_POW_TARGET_SPACING`] from the Zcash specification.
|
||||||
pub fn target_spacing(&self) -> Duration {
|
pub fn target_spacing(&self) -> Duration {
|
||||||
let spacing_seconds = match self {
|
let spacing_seconds = match self {
|
||||||
Genesis | BeforeOverwinter | Overwinter | Sapling => PRE_BLOSSOM_POW_TARGET_SPACING,
|
Genesis | BeforeOverwinter | Overwinter | Sapling => PRE_BLOSSOM_POW_TARGET_SPACING,
|
||||||
|
@ -344,7 +345,7 @@ impl NetworkUpgrade {
|
||||||
|
|
||||||
/// Returns the target block spacing for `network` and `height`.
|
/// Returns the target block spacing for `network` and `height`.
|
||||||
///
|
///
|
||||||
/// See [`target_spacing()`] for details.
|
/// See [`NetworkUpgrade::target_spacing`] for details.
|
||||||
pub fn target_spacing_for_height(network: Network, height: block::Height) -> Duration {
|
pub fn target_spacing_for_height(network: Network, height: block::Height) -> Duration {
|
||||||
NetworkUpgrade::current(network, height).target_spacing()
|
NetworkUpgrade::current(network, height).target_spacing()
|
||||||
}
|
}
|
||||||
|
@ -425,7 +426,7 @@ impl NetworkUpgrade {
|
||||||
|
|
||||||
/// Returns the averaging window timespan for `network` and `height`.
|
/// Returns the averaging window timespan for `network` and `height`.
|
||||||
///
|
///
|
||||||
/// See [`averaging_window_timespan()`] for details.
|
/// See [`NetworkUpgrade::averaging_window_timespan`] for details.
|
||||||
pub fn averaging_window_timespan_for_height(
|
pub fn averaging_window_timespan_for_height(
|
||||||
network: Network,
|
network: Network,
|
||||||
height: block::Height,
|
height: block::Height,
|
||||||
|
|
|
@ -132,11 +132,10 @@ impl<'msg, M: AsRef<[u8]>> From<(VerificationKeyBytes<Binding>, Signature<Bindin
|
||||||
impl Item {
|
impl Item {
|
||||||
/// Perform non-batched verification of this `Item`.
|
/// Perform non-batched verification of this `Item`.
|
||||||
///
|
///
|
||||||
/// This is useful (in combination with `Item::clone`) for implementing fallback
|
/// This is useful (in combination with `Item::clone`) for implementing
|
||||||
/// logic when batch verification fails. In contrast to
|
/// fallback logic when batch verification fails. In contrast to
|
||||||
/// [`VerificationKey::verify`](crate::VerificationKey::verify), which requires
|
/// [`VerificationKey::verify`], which requires borrowing the message data,
|
||||||
/// borrowing the message data, the `Item` type is unlinked from the lifetime of
|
/// the `Item` type is unlinked from the lifetime of the message.
|
||||||
/// the message.
|
|
||||||
pub fn verify_single(self) -> Result<(), Error> {
|
pub fn verify_single(self) -> Result<(), Error> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
Inner::Binding { vk_bytes, sig, c } => VerificationKey::<Binding>::try_from(vk_bytes)
|
Inner::Binding { vk_bytes, sig, c } => VerificationKey::<Binding>::try_from(vk_bytes)
|
||||||
|
|
|
@ -312,11 +312,11 @@ impl TryFrom<ValueCommitment> for NotSmallOrderValueCommitment {
|
||||||
///
|
///
|
||||||
/// # Consensus
|
/// # Consensus
|
||||||
///
|
///
|
||||||
/// > cv and rk [MUST NOT be of small order][1], i.e. [h_J]cv MUST NOT be 𝒪_J
|
/// > cv and rk [MUST NOT be of small order][1], i.e. \[h_J\]cv MUST NOT be 𝒪_J
|
||||||
/// > and [h_J]rk MUST NOT be 𝒪_J.
|
/// > and \[h_J\]rk MUST NOT be 𝒪_J.
|
||||||
///
|
///
|
||||||
/// > cv and epk [MUST NOT be of small order][2], i.e. [h_J]cv MUST NOT be 𝒪_J
|
/// > cv and epk [MUST NOT be of small order][2], i.e. \[h_J\]cv MUST NOT be 𝒪_J
|
||||||
/// > and [ℎ_J]epk MUST NOT be 𝒪_J.
|
/// > and \[ℎ_J\]epk MUST NOT be 𝒪_J.
|
||||||
///
|
///
|
||||||
/// [1]: https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
/// [1]: https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
||||||
/// [2]: https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
/// [2]: https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
||||||
|
|
|
@ -104,7 +104,7 @@ pub fn pedersen_hash(domain: [u8; 8], M: &BitVec<u8, Lsb0>) -> jubjub::Fq {
|
||||||
/// commitment tree. It takes as input a Pedersen commitment P, and hashes it
|
/// commitment tree. It takes as input a Pedersen commitment P, and hashes it
|
||||||
/// with another input x.
|
/// with another input x.
|
||||||
///
|
///
|
||||||
/// MixingPedersenHash(P, x) := P + [x]FindGroupHash^J^(r)("Zcash_J_", "")
|
/// MixingPedersenHash(P, x) := P + \[x\]FindGroupHash^J^(r)("Zcash_J_", "")
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/protocol.pdf#concretemixinghash>
|
/// <https://zips.z.cash/protocol/protocol.pdf#concretemixinghash>
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -118,7 +118,7 @@ pub fn mixing_pedersen_hash(P: jubjub::ExtendedPoint, x: jubjub::Fr) -> jubjub::
|
||||||
/// construction, and adding a randomized point on the Jubjub curve.
|
/// construction, and adding a randomized point on the Jubjub curve.
|
||||||
///
|
///
|
||||||
/// WindowedPedersenCommit_r (s) := \
|
/// WindowedPedersenCommit_r (s) := \
|
||||||
/// PedersenHashToPoint("Zcash_PH", s) + [r]FindGroupHash^J^(r)("Zcash_PH", "r")
|
/// PedersenHashToPoint("Zcash_PH", s) + \[r\]FindGroupHash^J^(r)("Zcash_PH", "r")
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit>
|
/// <https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit>
|
||||||
pub fn windowed_pedersen_commitment(r: jubjub::Fr, s: &BitVec<u8, Lsb0>) -> jubjub::ExtendedPoint {
|
pub fn windowed_pedersen_commitment(r: jubjub::Fr, s: &BitVec<u8, Lsb0>) -> jubjub::ExtendedPoint {
|
||||||
|
|
|
@ -1055,7 +1055,7 @@ impl TryFrom<[u8; 32]> for EphemeralPublicKey {
|
||||||
/// # Consensus
|
/// # Consensus
|
||||||
///
|
///
|
||||||
/// > Check that a Output description's cv and epk are not of small order,
|
/// > Check that a Output description's cv and epk are not of small order,
|
||||||
/// > i.e. [h_J]cv MUST NOT be 𝒪_J and [h_J]epk MUST NOT be 𝒪_J.
|
/// > i.e. \[h_J\]cv MUST NOT be 𝒪_J and \[h_J\]epk MUST NOT be 𝒪_J.
|
||||||
///
|
///
|
||||||
/// [1]: https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
/// [1]: https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
||||||
fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
|
fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
|
||||||
|
@ -1106,7 +1106,7 @@ impl TryFrom<redjubjub::VerificationKey<SpendAuth>> for ValidatingKey {
|
||||||
/// # Consensus
|
/// # Consensus
|
||||||
///
|
///
|
||||||
/// > Check that a Spend description's cv and rk are not of small order,
|
/// > Check that a Spend description's cv and rk are not of small order,
|
||||||
/// > i.e. [h_J]cv MUST NOT be 𝒪_J and [h_J]rk MUST NOT be 𝒪_J.
|
/// > i.e. \[h_J\]cv MUST NOT be 𝒪_J and \[h_J\]rk MUST NOT be 𝒪_J.
|
||||||
///
|
///
|
||||||
/// [1]: https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
/// [1]: https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
||||||
fn try_from(key: redjubjub::VerificationKey<SpendAuth>) -> Result<Self, Self::Error> {
|
fn try_from(key: redjubjub::VerificationKey<SpendAuth>) -> Result<Self, Self::Error> {
|
||||||
|
|
|
@ -158,12 +158,12 @@ impl ZcashDeserialize for OutputInTransactionV4 {
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
||||||
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
||||||
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
||||||
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
// Type is `Sym.C`, i.e. `B^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
// See [`note::EncryptedNote::zcash_deserialize`].
|
// See [`note::EncryptedNote::zcash_deserialize`].
|
||||||
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
||||||
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays.
|
// Type is `Sym.C`, i.e. `B^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays.
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
||||||
|
@ -221,12 +221,12 @@ impl ZcashDeserialize for OutputPrefixInTransactionV5 {
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
||||||
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
||||||
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
||||||
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
// Type is `Sym.C`, i.e. `B^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
// See [`note::EncryptedNote::zcash_deserialize`].
|
// See [`note::EncryptedNote::zcash_deserialize`].
|
||||||
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
||||||
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays.
|
// Type is `Sym.C`, i.e. `B^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays.
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
||||||
|
@ -242,6 +242,7 @@ impl ZcashDeserialize for OutputPrefixInTransactionV5 {
|
||||||
pub(crate) const OUTPUT_PREFIX_SIZE: u64 = 32 + 32 + 32 + 580 + 80;
|
pub(crate) const OUTPUT_PREFIX_SIZE: u64 = 32 + 32 + 32 + 580 + 80;
|
||||||
/// An output contains: a 32 byte cv, a 32 byte cmu, a 32 byte ephemeral key
|
/// An output contains: a 32 byte cv, a 32 byte cmu, a 32 byte ephemeral key
|
||||||
/// a 580 byte encCiphertext, an 80 byte outCiphertext, and a 192 byte zkproof
|
/// a 580 byte encCiphertext, an 80 byte outCiphertext, and a 192 byte zkproof
|
||||||
|
///
|
||||||
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#outputencoding
|
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#outputencoding
|
||||||
pub(crate) const OUTPUT_SIZE: u64 = OUTPUT_PREFIX_SIZE + 192;
|
pub(crate) const OUTPUT_SIZE: u64 = OUTPUT_PREFIX_SIZE + 192;
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ where
|
||||||
/// transaction.
|
/// transaction.
|
||||||
///
|
///
|
||||||
/// Use the [`ShieldedData::outputs`] method to get an iterator over the
|
/// Use the [`ShieldedData::outputs`] method to get an iterator over the
|
||||||
/// [`Outputs`]s in this `TransferData`.
|
/// [`Output`]s in this `TransferData`.
|
||||||
maybe_outputs: Vec<Output>,
|
maybe_outputs: Vec<Output>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ where
|
||||||
/// At least one output, in the order they appear in the transaction.
|
/// At least one output, in the order they appear in the transaction.
|
||||||
///
|
///
|
||||||
/// Use the [`ShieldedData::outputs`] method to get an iterator over the
|
/// Use the [`ShieldedData::outputs`] method to get an iterator over the
|
||||||
/// [`Outputs`]s in this `TransferData`.
|
/// [`Output`]s in this `TransferData`.
|
||||||
outputs: AtLeastOne<Output>,
|
outputs: AtLeastOne<Output>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,8 +181,8 @@ impl ZcashDeserialize for Spend<PerSpendAnchor> {
|
||||||
/// <https://zips.z.cash/protocol/protocol.pdf#spendsandoutputs>
|
/// <https://zips.z.cash/protocol/protocol.pdf#spendsandoutputs>
|
||||||
///
|
///
|
||||||
/// This rule is also implemented in
|
/// This rule is also implemented in
|
||||||
/// [`zebra_state::service::check::anchor`] and
|
/// `zebra_state::service::check::anchors` and
|
||||||
/// [`zebra_chain::transaction::serialize`].
|
/// [`crate::transaction::serialize`].
|
||||||
///
|
///
|
||||||
/// The "anchor encoding for v4 transactions" is implemented here.
|
/// The "anchor encoding for v4 transactions" is implemented here.
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
|
|
@ -292,7 +292,7 @@ pub struct NoteCommitmentTree {
|
||||||
/// tree). This is particularly important since we decided to instantiate
|
/// tree). This is particularly important since we decided to instantiate
|
||||||
/// the trees from the genesis block, for simplicity.
|
/// the trees from the genesis block, for simplicity.
|
||||||
///
|
///
|
||||||
/// We use a [`RwLock`] for this cache, because it is only written once per
|
/// We use a [`RwLock`](std::sync::RwLock) for this cache, because it is only written once per
|
||||||
/// tree update. Each tree has its own cached root, a new lock is created
|
/// tree update. Each tree has its own cached root, a new lock is created
|
||||||
/// for each clone.
|
/// for each clone.
|
||||||
cached_root: std::sync::RwLock<Option<Root>>,
|
cached_root: std::sync::RwLock<Option<Root>>,
|
||||||
|
@ -376,7 +376,8 @@ impl NoteCommitmentTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for NoteCommitmentTree {
|
impl Clone for NoteCommitmentTree {
|
||||||
/// Clones the inner tree, and creates a new `RwLock` with the cloned root data.
|
/// Clones the inner tree, and creates a new [`RwLock`](std::sync::RwLock)
|
||||||
|
/// with the cloned root data.
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let cached_root = *self
|
let cached_root = *self
|
||||||
.cached_root
|
.cached_root
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl Arbitrary for DateTime32 {
|
||||||
///
|
///
|
||||||
/// Zebra uses these times internally, typically via [`Utc::now`].
|
/// Zebra uses these times internally, typically via [`Utc::now`].
|
||||||
///
|
///
|
||||||
/// Some parts of the Zcash network protocol ([`Version`] messages) also use times
|
/// Some parts of the Zcash network protocol (`Version` messages) also use times
|
||||||
/// with an 8-byte seconds value. Unlike this function, they have zero
|
/// with an 8-byte seconds value. Unlike this function, they have zero
|
||||||
/// nanoseconds values. (So they never have `chrono` leap seconds.)
|
/// nanoseconds values. (So they never have `chrono` leap seconds.)
|
||||||
pub fn datetime_full() -> impl Strategy<Value = chrono::DateTime<Utc>> {
|
pub fn datetime_full() -> impl Strategy<Value = chrono::DateTime<Utc>> {
|
||||||
|
@ -53,7 +53,7 @@ pub fn datetime_full() -> impl Strategy<Value = chrono::DateTime<Utc>> {
|
||||||
/// The nanoseconds value is always zero.
|
/// The nanoseconds value is always zero.
|
||||||
///
|
///
|
||||||
/// The Zcash protocol typically uses 4-byte seconds values, except for the
|
/// The Zcash protocol typically uses 4-byte seconds values, except for the
|
||||||
/// [`Version`] message.
|
/// `Version` message.
|
||||||
///
|
///
|
||||||
/// TODO: replace this strategy with `any::<DateTime32>()`.
|
/// TODO: replace this strategy with `any::<DateTime32>()`.
|
||||||
pub fn datetime_u32() -> impl Strategy<Value = chrono::DateTime<Utc>> {
|
pub fn datetime_u32() -> impl Strategy<Value = chrono::DateTime<Utc>> {
|
||||||
|
|
|
@ -104,7 +104,9 @@ impl<P: ZkSnarkProof> JoinSplit<P> {
|
||||||
///
|
///
|
||||||
/// <https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions>
|
/// <https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions>
|
||||||
///
|
///
|
||||||
/// See [`Transaction::sprout_value_balance`] for details.
|
/// See [`sprout_value_balance`][svb] for details.
|
||||||
|
///
|
||||||
|
/// [svb]: crate::transaction::Transaction::sprout_value_balance
|
||||||
pub fn value_balance(&self) -> Amount<NegativeAllowed> {
|
pub fn value_balance(&self) -> Amount<NegativeAllowed> {
|
||||||
let vpub_new = self
|
let vpub_new = self
|
||||||
.vpub_new
|
.vpub_new
|
||||||
|
@ -161,7 +163,7 @@ impl<P: ZkSnarkProof> ZcashDeserialize for JoinSplit<P> {
|
||||||
// The type is validated when validating the proof, see
|
// The type is validated when validating the proof, see
|
||||||
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
||||||
zkproof: P::zcash_deserialize(&mut reader)?,
|
zkproof: P::zcash_deserialize(&mut reader)?,
|
||||||
// Types are `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
// Types are `Sym.C`, i.e. `B^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
// 601 bytes in https://zips.z.cash/protocol/protocol.pdf#joinsplitencodingandconsensus
|
// 601 bytes in https://zips.z.cash/protocol/protocol.pdf#joinsplitencodingandconsensus
|
||||||
// See [`note::EncryptedNote::zcash_deserialize`].
|
// See [`note::EncryptedNote::zcash_deserialize`].
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub const ROOTS: [&str; 16] = [
|
||||||
|
|
||||||
/// Empty (unused) Sprout note commitment tree leaf node.
|
/// Empty (unused) Sprout note commitment tree leaf node.
|
||||||
///
|
///
|
||||||
/// Uncommitted^Sprout = [0]^(l^Sprout_Merkle).
|
/// Uncommitted^Sprout = \[0\]^(l^Sprout_Merkle).
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/protocol.pdf#constants>
|
/// <https://zips.z.cash/protocol/protocol.pdf#constants>
|
||||||
pub const EMPTY_LEAF: [u8; 32] = [0; 32];
|
pub const EMPTY_LEAF: [u8; 32] = [0; 32];
|
||||||
|
|
|
@ -230,8 +230,9 @@ pub struct NoteCommitmentTree {
|
||||||
/// the tree). This is particularly important since we decided to
|
/// the tree). This is particularly important since we decided to
|
||||||
/// instantiate the trees from the genesis block, for simplicity.
|
/// instantiate the trees from the genesis block, for simplicity.
|
||||||
///
|
///
|
||||||
/// We use a [`RwLock`] for this cache, because it is only written once per tree update.
|
/// We use a [`RwLock`](std::sync::RwLock) for this cache, because it is
|
||||||
/// Each tree has its own cached root, a new lock is created for each clone.
|
/// only written once per tree update. Each tree has its own cached root, a
|
||||||
|
/// new lock is created for each clone.
|
||||||
cached_root: std::sync::RwLock<Option<Root>>,
|
cached_root: std::sync::RwLock<Option<Root>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +293,7 @@ impl NoteCommitmentTree {
|
||||||
|
|
||||||
/// Returns an as-yet unused leaf node value of a Sprout note commitment tree.
|
/// Returns an as-yet unused leaf node value of a Sprout note commitment tree.
|
||||||
///
|
///
|
||||||
/// Uncommitted^Sprout = [0]^(l^[Sprout_Merkle]).
|
/// Uncommitted^Sprout = \[0\]^(l^[Sprout_Merkle]).
|
||||||
///
|
///
|
||||||
/// [Sprout_Merkle]: https://zips.z.cash/protocol/protocol.pdf#constants
|
/// [Sprout_Merkle]: https://zips.z.cash/protocol/protocol.pdf#constants
|
||||||
pub fn uncommitted() -> [u8; 32] {
|
pub fn uncommitted() -> [u8; 32] {
|
||||||
|
|
|
@ -230,7 +230,7 @@ impl Transaction {
|
||||||
|
|
||||||
/// Does this transaction have shielded inputs?
|
/// Does this transaction have shielded inputs?
|
||||||
///
|
///
|
||||||
/// See [`has_transparent_or_shielded_inputs`] for details.
|
/// See [`Self::has_transparent_or_shielded_inputs`] for details.
|
||||||
pub fn has_shielded_inputs(&self) -> bool {
|
pub fn has_shielded_inputs(&self) -> bool {
|
||||||
self.joinsplit_count() > 0
|
self.joinsplit_count() > 0
|
||||||
|| self.sapling_spends_per_anchor().count() > 0
|
|| self.sapling_spends_per_anchor().count() > 0
|
||||||
|
@ -248,7 +248,7 @@ impl Transaction {
|
||||||
|
|
||||||
/// Does this transaction have shielded outputs?
|
/// Does this transaction have shielded outputs?
|
||||||
///
|
///
|
||||||
/// See [`has_transparent_or_shielded_outputs`] for details.
|
/// See [`Self::has_transparent_or_shielded_outputs`] for details.
|
||||||
pub fn has_shielded_outputs(&self) -> bool {
|
pub fn has_shielded_outputs(&self) -> bool {
|
||||||
self.joinsplit_count() > 0
|
self.joinsplit_count() > 0
|
||||||
|| self.sapling_outputs().count() > 0
|
|| self.sapling_outputs().count() > 0
|
||||||
|
@ -1197,11 +1197,13 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a list of sprout value balances,
|
/// Return a list of sprout value balances,
|
||||||
/// the changes in the transaction value pool due to each sprout [`JoinSplit`].
|
/// the changes in the transaction value pool due to each sprout `JoinSplit`.
|
||||||
///
|
///
|
||||||
/// Each value balance is the sprout `vpub_new` field, minus the `vpub_old` field.
|
/// Each value balance is the sprout `vpub_new` field, minus the `vpub_old` field.
|
||||||
///
|
///
|
||||||
/// See `sprout_value_balance` for details.
|
/// See [`sprout_value_balance`][svb] for details.
|
||||||
|
///
|
||||||
|
/// [svb]: crate::transaction::Transaction::sprout_value_balance
|
||||||
fn sprout_joinsplit_value_balances(
|
fn sprout_joinsplit_value_balances(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = ValueBalance<NegativeAllowed>> + '_ {
|
) -> impl Iterator<Item = ValueBalance<NegativeAllowed>> + '_ {
|
||||||
|
@ -1238,7 +1240,7 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the sprout value balance,
|
/// Return the sprout value balance,
|
||||||
/// the change in the transaction value pool due to sprout [`JoinSplit`]s.
|
/// the change in the transaction value pool due to sprout `JoinSplit`s.
|
||||||
///
|
///
|
||||||
/// The sum of all sprout `vpub_new` fields, minus the sum of all `vpub_old` fields.
|
/// The sum of all sprout `vpub_new` fields, minus the sum of all `vpub_old` fields.
|
||||||
///
|
///
|
||||||
|
@ -1319,8 +1321,8 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the orchard value balance,
|
/// Return the orchard value balance, the change in the transaction value
|
||||||
/// the change in the transaction value pool due to orchard [`Action`]s.
|
/// pool due to [`orchard::Action`]s.
|
||||||
///
|
///
|
||||||
/// Returns the `valueBalanceOrchard` field in this transaction.
|
/// Returns the `valueBalanceOrchard` field in this transaction.
|
||||||
///
|
///
|
||||||
|
|
|
@ -278,7 +278,8 @@ impl Transaction {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If any spent [`Output`] is missing from `outpoints`.
|
/// If any spent [`transparent::Output`] is missing from
|
||||||
|
/// [`transparent::OutPoint`]s.
|
||||||
//
|
//
|
||||||
// TODO: take some extra arbitrary flags, which select between zero and non-zero
|
// TODO: take some extra arbitrary flags, which select between zero and non-zero
|
||||||
// remaining value in each chain value pool
|
// remaining value in each chain value pool
|
||||||
|
@ -420,7 +421,8 @@ impl Transaction {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If any spent [`Output`] is missing from `outpoints`.
|
/// If any spent [`transparent::Output`] is missing from
|
||||||
|
/// [`transparent::OutPoint`]s.
|
||||||
//
|
//
|
||||||
// TODO: split this method up, after we've implemented chain value balance adjustments
|
// TODO: split this method up, after we've implemented chain value balance adjustments
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,29 +1,32 @@
|
||||||
//! Transaction identifiers for Zcash.
|
//! Transaction identifiers for Zcash.
|
||||||
//!
|
//!
|
||||||
//! Zcash has two different transaction identifiers, with different widths:
|
//! Zcash has two different transaction identifiers, with different widths:
|
||||||
//! * [`Hash`]: a 32-byte transaction ID, which uniquely identifies mined transactions
|
//! * [`struct@Hash`]: a 32-byte transaction ID, which uniquely identifies mined transactions
|
||||||
//! (transactions that have been committed to the blockchain in blocks), and
|
//! (transactions that have been committed to the blockchain in blocks), and
|
||||||
//! * [`WtxId`]: a 64-byte witnessed transaction ID, which uniquely identifies unmined transactions
|
//! * [`WtxId`]: a 64-byte witnessed transaction ID, which uniquely identifies unmined transactions
|
||||||
//! (transactions that are sent by wallets or stored in node mempools).
|
//! (transactions that are sent by wallets or stored in node mempools).
|
||||||
//!
|
//!
|
||||||
//! Transaction version 5 uses both these unique identifiers:
|
//! Transaction version 5 uses both these unique identifiers:
|
||||||
//! * [`Hash`] uniquely identifies the effects of a v5 transaction (spends and outputs),
|
//! * [`struct@Hash`] uniquely identifies the effects of a v5 transaction (spends and outputs),
|
||||||
//! so it uniquely identifies the transaction's data after it has been mined into a block;
|
//! so it uniquely identifies the transaction's data after it has been mined into a block;
|
||||||
//! * [`WtxId`] uniquely identifies the effects and authorizing data of a v5 transaction
|
//! * [`WtxId`] uniquely identifies the effects and authorizing data of a v5 transaction
|
||||||
//! (signatures, proofs, and scripts), so it uniquely identifies the transaction's data
|
//! (signatures, proofs, and scripts), so it uniquely identifies the transaction's data
|
||||||
//! outside a block. (For example, transactions produced by Zcash wallets, or in node mempools.)
|
//! outside a block. (For example, transactions produced by Zcash wallets, or in node mempools.)
|
||||||
//!
|
//!
|
||||||
//! Transaction versions 1-4 are uniquely identified by legacy [`Hash`] transaction IDs,
|
//! Transaction versions 1-4 are uniquely identified by legacy [`struct@Hash`] transaction IDs,
|
||||||
//! whether they have been mined or not. So Zebra, and the Zcash network protocol,
|
//! whether they have been mined or not. So Zebra, and the Zcash network protocol,
|
||||||
//! don't use witnessed transaction IDs for them.
|
//! don't use witnessed transaction IDs for them.
|
||||||
//!
|
//!
|
||||||
//! There is no unique identifier that only covers the effects of a v1-4 transaction,
|
//! There is no unique identifier that only covers the effects of a v1-4 transaction,
|
||||||
//! so their legacy IDs are malleable, if submitted with different authorizing data.
|
//! so their legacy IDs are malleable, if submitted with different authorizing data.
|
||||||
//! So the same spends and outputs can have a completely different [`Hash`].
|
//! So the same spends and outputs can have a completely different [`struct@Hash`].
|
||||||
//!
|
//!
|
||||||
//! Zebra's [`UnminedTxId`] and [`UnminedTx`] enums provide the correct unique ID for
|
//! Zebra's [`UnminedTxId`][1] and [`UnminedTx`][1] enums provide the correct
|
||||||
//! unmined transactions. They can be used to handle transactions regardless of version,
|
//! unique ID for unmined transactions. They can be used to handle transactions
|
||||||
//! and get the [`WtxId`] or [`Hash`] when required.
|
//! regardless of version, and get the [`WtxId`] or [`struct@Hash`] when
|
||||||
|
//! required.
|
||||||
|
//!
|
||||||
|
//! [1]: crate::transaction::UnminedTx
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
convert::{TryFrom, TryInto},
|
convert::{TryFrom, TryInto},
|
||||||
|
|
|
@ -85,7 +85,9 @@ impl<P: ZkSnarkProof> JoinSplitData<P> {
|
||||||
///
|
///
|
||||||
/// <https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions>
|
/// <https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions>
|
||||||
///
|
///
|
||||||
/// See [`Transaction::sprout_value_balance`] for details.
|
/// See [`sprout_value_balance`][svb] for details.
|
||||||
|
///
|
||||||
|
/// [svb]: crate::transaction::Transaction::sprout_value_balance
|
||||||
pub fn value_balance(&self) -> Result<Amount<NegativeAllowed>, amount::Error> {
|
pub fn value_balance(&self) -> Result<Amount<NegativeAllowed>, amount::Error> {
|
||||||
self.joinsplit_value_balances().sum()
|
self.joinsplit_value_balances().sum()
|
||||||
}
|
}
|
||||||
|
@ -93,14 +95,16 @@ impl<P: ZkSnarkProof> JoinSplitData<P> {
|
||||||
/// Return a list of sprout value balances,
|
/// Return a list of sprout value balances,
|
||||||
/// the changes in the transaction value pool due to each sprout [`JoinSplit`].
|
/// the changes in the transaction value pool due to each sprout [`JoinSplit`].
|
||||||
///
|
///
|
||||||
/// See [`Transaction::sprout_value_balance`] for details.
|
/// See [`sprout_value_balance`][svb] for details.
|
||||||
|
///
|
||||||
|
/// [svb]: crate::transaction::Transaction::sprout_value_balance
|
||||||
pub fn joinsplit_value_balances(
|
pub fn joinsplit_value_balances(
|
||||||
&self,
|
&self,
|
||||||
) -> Box<dyn Iterator<Item = Amount<NegativeAllowed>> + '_> {
|
) -> Box<dyn Iterator<Item = Amount<NegativeAllowed>> + '_> {
|
||||||
Box::new(self.joinsplits().map(JoinSplit::value_balance))
|
Box::new(self.joinsplits().map(JoinSplit::value_balance))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collect the Sprout note commitments for this transaction, if it contains [`Output`]s,
|
/// Collect the Sprout note commitments for this transaction, if it contains `Output`s,
|
||||||
/// in the order they appear in the transaction.
|
/// in the order they appear in the transaction.
|
||||||
pub fn note_commitments(&self) -> impl Iterator<Item = &sprout::commitment::NoteCommitment> {
|
pub fn note_commitments(&self) -> impl Iterator<Item = &sprout::commitment::NoteCommitment> {
|
||||||
self.joinsplits()
|
self.joinsplits()
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
//! Unmined Zcash transaction identifiers and transactions.
|
//! Unmined Zcash transaction identifiers and transactions.
|
||||||
//!
|
//!
|
||||||
//! Transaction version 5 is uniquely identified by [`WtxId`] when unmined,
|
//! Transaction version 5 is uniquely identified by [`WtxId`] when unmined, and
|
||||||
//! and [`Hash`] in the blockchain. The effects of a v5 transaction (spends and outputs)
|
//! [`struct@Hash`] in the blockchain. The effects of a v5 transaction
|
||||||
//! are uniquely identified by the same [`Hash`] in both cases.
|
//! (spends and outputs) are uniquely identified by the same
|
||||||
|
//! [`struct@Hash`] in both cases.
|
||||||
//!
|
//!
|
||||||
//! Transaction versions 1-4 are uniquely identified by legacy [`Hash`] transaction IDs,
|
//! Transaction versions 1-4 are uniquely identified by legacy
|
||||||
//! whether they have been mined or not. So Zebra, and the Zcash network protocol,
|
//! [`struct@Hash`] transaction IDs, whether they have been mined or not.
|
||||||
//! don't use witnessed transaction IDs for them.
|
//! So Zebra, and the Zcash network protocol, don't use witnessed transaction
|
||||||
|
//! IDs for them.
|
||||||
//!
|
//!
|
||||||
//! Zebra's [`UnminedTxId`] and [`UnminedTx`] enums provide the correct unique ID for
|
//! Zebra's [`UnminedTxId`] and [`UnminedTx`] enums provide the correct unique
|
||||||
//! unmined transactions. They can be used to handle transactions regardless of version,
|
//! ID for unmined transactions. They can be used to handle transactions
|
||||||
//! and get the [`WtxId`] or [`Hash`] when required.
|
//! regardless of version, and get the [`WtxId`] or [`struct@Hash`] when
|
||||||
|
//! required.
|
||||||
|
|
||||||
use std::{fmt, sync::Arc};
|
use std::{fmt, sync::Arc};
|
||||||
|
|
||||||
|
@ -68,14 +71,14 @@ pub enum UnminedTxId {
|
||||||
///
|
///
|
||||||
/// Used to uniquely identify unmined version 1-4 transactions.
|
/// Used to uniquely identify unmined version 1-4 transactions.
|
||||||
/// (After v1-4 transactions are mined, they can be uniquely identified
|
/// (After v1-4 transactions are mined, they can be uniquely identified
|
||||||
/// using the same [`transaction::Hash`].)
|
/// using the same [`struct@Hash`].)
|
||||||
Legacy(Hash),
|
Legacy(Hash),
|
||||||
|
|
||||||
/// A witnessed unmined transaction identifier.
|
/// A witnessed unmined transaction identifier.
|
||||||
///
|
///
|
||||||
/// Used to uniquely identify unmined version 5 transactions.
|
/// Used to uniquely identify unmined version 5 transactions.
|
||||||
/// (After v5 transactions are mined, they can be uniquely identified
|
/// (After v5 transactions are mined, they can be uniquely identified
|
||||||
/// using only the [`transaction::Hash`] in their `WtxId.id`.)
|
/// using only the [`struct@Hash`] in their `WtxId.id`.)
|
||||||
///
|
///
|
||||||
/// For more details, see [`WtxId`].
|
/// For more details, see [`WtxId`].
|
||||||
Witnessed(WtxId),
|
Witnessed(WtxId),
|
||||||
|
@ -125,12 +128,13 @@ impl fmt::Display for UnminedTxId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnminedTxId {
|
impl UnminedTxId {
|
||||||
/// Create a new `UnminedTxId` using a v1-v4 legacy transaction ID.
|
/// Create a new [`UnminedTxId`] using a v1-v4 legacy transaction ID.
|
||||||
///
|
///
|
||||||
/// # Correctness
|
/// # Correctness
|
||||||
///
|
///
|
||||||
/// This method must only be used for v1-v4 transaction IDs.
|
/// This method must only be used for v1-v4 transaction IDs.
|
||||||
/// [`Hash`] does not uniquely identify unmined v5 transactions.
|
/// [`struct@Hash`] does not uniquely identify unmined v5
|
||||||
|
/// transactions.
|
||||||
pub fn from_legacy_id(legacy_tx_id: Hash) -> UnminedTxId {
|
pub fn from_legacy_id(legacy_tx_id: Hash) -> UnminedTxId {
|
||||||
Legacy(legacy_tx_id)
|
Legacy(legacy_tx_id)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +158,7 @@ impl UnminedTxId {
|
||||||
/// Returns a mutable reference to the unique ID
|
/// Returns a mutable reference to the unique ID
|
||||||
/// that will be used if this transaction gets mined into a block.
|
/// that will be used if this transaction gets mined into a block.
|
||||||
///
|
///
|
||||||
/// See [mined_id] for details.
|
/// See [`Self::mined_id`] for details.
|
||||||
#[cfg(any(test, feature = "proptest-impl"))]
|
#[cfg(any(test, feature = "proptest-impl"))]
|
||||||
pub fn mined_id_mut(&mut self) -> &mut Hash {
|
pub fn mined_id_mut(&mut self) -> &mut Hash {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -100,7 +100,8 @@ pub struct OutPoint {
|
||||||
///
|
///
|
||||||
/// # Correctness
|
/// # Correctness
|
||||||
///
|
///
|
||||||
/// Consensus-critical serialization uses [`ZcashSerialize`].
|
/// Consensus-critical serialization uses
|
||||||
|
/// [`ZcashSerialize`](crate::serialization::ZcashSerialize).
|
||||||
/// [`serde`]-based hex serialization must only be used for testing.
|
/// [`serde`]-based hex serialization must only be used for testing.
|
||||||
#[cfg_attr(any(test, feature = "proptest-impl"), serde(with = "hex"))]
|
#[cfg_attr(any(test, feature = "proptest-impl"), serde(with = "hex"))]
|
||||||
pub hash: transaction::Hash,
|
pub hash: transaction::Hash,
|
||||||
|
@ -111,7 +112,7 @@ pub struct OutPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutPoint {
|
impl OutPoint {
|
||||||
/// Returns a new OutPoint from an in-memory output `index`.
|
/// Returns a new [`OutPoint`] from an in-memory output `index`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
@ -197,8 +198,8 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If this is a `PrevOut` input, returns this input's outpoint.
|
/// If this is a [`Input::PrevOut`] input, returns this input's
|
||||||
/// Otherwise, returns `None`.
|
/// [`OutPoint`]. Otherwise, returns `None`.
|
||||||
pub fn outpoint(&self) -> Option<OutPoint> {
|
pub fn outpoint(&self) -> Option<OutPoint> {
|
||||||
if let Input::PrevOut { outpoint, .. } = self {
|
if let Input::PrevOut { outpoint, .. } = self {
|
||||||
Some(*outpoint)
|
Some(*outpoint)
|
||||||
|
@ -207,9 +208,9 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set this input's outpoint.
|
/// Set this input's [`OutPoint`].
|
||||||
///
|
///
|
||||||
/// Should only be called on `PrevOut` inputs.
|
/// Should only be called on [`Input::PrevOut`] inputs.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
@ -226,12 +227,12 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value spent by this input, by looking up its [`Outpoint`] in `outputs`.
|
/// Get the value spent by this input, by looking up its [`OutPoint`] in `outputs`.
|
||||||
/// See `value` for details.
|
/// See [`Self::value`] for details.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If the provided `Output`s don't have this input's `Outpoint`.
|
/// If the provided [`Output`]s don't have this input's [`OutPoint`].
|
||||||
pub(crate) fn value_from_outputs(
|
pub(crate) fn value_from_outputs(
|
||||||
&self,
|
&self,
|
||||||
outputs: &HashMap<OutPoint, Output>,
|
outputs: &HashMap<OutPoint, Output>,
|
||||||
|
@ -253,13 +254,14 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value spent by this input, by looking up its [`Outpoint`] in `utxos`.
|
/// Get the value spent by this input, by looking up its [`OutPoint`] in
|
||||||
|
/// [`Utxo`]s.
|
||||||
///
|
///
|
||||||
/// This amount is added to the transaction value pool by this input.
|
/// This amount is added to the transaction value pool by this input.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If the provided `Utxo`s don't have this input's `Outpoint`.
|
/// If the provided [`Utxo`]s don't have this input's [`OutPoint`].
|
||||||
pub fn value(&self, utxos: &HashMap<OutPoint, utxo::Utxo>) -> Amount<NonNegative> {
|
pub fn value(&self, utxos: &HashMap<OutPoint, utxo::Utxo>) -> Amount<NonNegative> {
|
||||||
if let Some(outpoint) = self.outpoint() {
|
if let Some(outpoint) = self.outpoint() {
|
||||||
// look up the specific Output and convert it to the expected format
|
// look up the specific Output and convert it to the expected format
|
||||||
|
@ -275,12 +277,14 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value spent by this input, by looking up its [`Outpoint`] in `ordered_utxos`.
|
/// Get the value spent by this input, by looking up its [`OutPoint`] in
|
||||||
/// See `value` for details.
|
/// [`OrderedUtxo`]s.
|
||||||
|
///
|
||||||
|
/// See [`Self::value`] for details.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If the provided `OrderedUtxo`s don't have this input's `Outpoint`.
|
/// If the provided [`OrderedUtxo`]s don't have this input's [`OutPoint`].
|
||||||
pub fn value_from_ordered_utxos(
|
pub fn value_from_ordered_utxos(
|
||||||
&self,
|
&self,
|
||||||
ordered_utxos: &HashMap<OutPoint, utxo::OrderedUtxo>,
|
ordered_utxos: &HashMap<OutPoint, utxo::OrderedUtxo>,
|
||||||
|
|
|
@ -111,6 +111,9 @@ impl OrderedUtxo {
|
||||||
/// A restriction that must be checked before spending a transparent output of a
|
/// A restriction that must be checked before spending a transparent output of a
|
||||||
/// coinbase transaction.
|
/// coinbase transaction.
|
||||||
///
|
///
|
||||||
|
/// TODO: fix the comment below because
|
||||||
|
/// [`CoinbaseSpendRestriction::check_spend`] doesn't exist.
|
||||||
|
///
|
||||||
/// See [`CoinbaseSpendRestriction::check_spend`] for the consensus rules.
|
/// See [`CoinbaseSpendRestriction::check_spend`] for the consensus rules.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
@ -138,7 +141,7 @@ pub fn utxos_from_ordered_utxos(
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute an index of [`Output`]s, given an index of [`Utxo`]s.
|
/// Compute an index of [`transparent::Output`]s, given an index of [`Utxo`]s.
|
||||||
pub fn outputs_from_utxos(
|
pub fn outputs_from_utxos(
|
||||||
utxos: HashMap<transparent::OutPoint, Utxo>,
|
utxos: HashMap<transparent::OutPoint, Utxo>,
|
||||||
) -> HashMap<transparent::OutPoint, transparent::Output> {
|
) -> HashMap<transparent::OutPoint, transparent::Output> {
|
||||||
|
|
|
@ -167,7 +167,7 @@ impl ValueBalance<NegativeAllowed> {
|
||||||
impl ValueBalance<NonNegative> {
|
impl ValueBalance<NonNegative> {
|
||||||
/// Returns the sum of this value balance, and the chain value pool changes in `block`.
|
/// Returns the sum of this value balance, and the chain value pool changes in `block`.
|
||||||
///
|
///
|
||||||
/// `utxos` must contain the [`Utxo`]s of every input in this block,
|
/// `utxos` must contain the [`transparent::Utxo`]s of every input in this block,
|
||||||
/// including UTXOs created by earlier transactions in this block.
|
/// including UTXOs created by earlier transactions in this block.
|
||||||
///
|
///
|
||||||
/// Note: the chain value pool has the opposite sign to the transaction
|
/// Note: the chain value pool has the opposite sign to the transaction
|
||||||
|
@ -221,7 +221,7 @@ impl ValueBalance<NonNegative> {
|
||||||
|
|
||||||
/// Returns the sum of this value balance, and the chain value pool changes in `transaction`.
|
/// Returns the sum of this value balance, and the chain value pool changes in `transaction`.
|
||||||
///
|
///
|
||||||
/// `outputs` must contain the [`Output`]s of every input in this transaction,
|
/// `outputs` must contain the [`transparent::Output`]s of every input in this transaction,
|
||||||
/// including UTXOs created by earlier transactions in its block.
|
/// including UTXOs created by earlier transactions in its block.
|
||||||
///
|
///
|
||||||
/// Note: the chain value pool has the opposite sign to the transaction
|
/// Note: the chain value pool has the opposite sign to the transaction
|
||||||
|
@ -263,7 +263,7 @@ impl ValueBalance<NonNegative> {
|
||||||
|
|
||||||
/// Returns the sum of this value balance, and the chain value pool change in `input`.
|
/// Returns the sum of this value balance, and the chain value pool change in `input`.
|
||||||
///
|
///
|
||||||
/// `outputs` must contain the [`Output`] spent by `input`,
|
/// `outputs` must contain the [`transparent::Output`] spent by `input`,
|
||||||
/// (including UTXOs created by earlier transactions in its block).
|
/// (including UTXOs created by earlier transactions in its block).
|
||||||
///
|
///
|
||||||
/// Note: the chain value pool has the opposite sign to the transaction
|
/// Note: the chain value pool has the opposite sign to the transaction
|
||||||
|
|
|
@ -56,8 +56,9 @@ pub struct AddressBook {
|
||||||
///
|
///
|
||||||
/// Some peers in this list might have open outbound or inbound connections.
|
/// Some peers in this list might have open outbound or inbound connections.
|
||||||
///
|
///
|
||||||
/// We reverse the comparison order, because the standard library ([`BTreeMap`])
|
/// We reverse the comparison order, because the standard library
|
||||||
/// sorts in ascending order, but [`OrderedMap`] sorts in descending order.
|
/// ([`BTreeMap`](std::collections::BTreeMap)) sorts in ascending order, but
|
||||||
|
/// [`OrderedMap`] sorts in descending order.
|
||||||
by_addr: OrderedMap<SocketAddr, MetaAddr, Reverse<MetaAddr>>,
|
by_addr: OrderedMap<SocketAddr, MetaAddr, Reverse<MetaAddr>>,
|
||||||
|
|
||||||
/// The maximum number of addresses in the address book.
|
/// The maximum number of addresses in the address book.
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub struct Config {
|
||||||
///
|
///
|
||||||
/// If a specific listener address is configured, Zebra will advertise
|
/// If a specific listener address is configured, Zebra will advertise
|
||||||
/// it to other nodes. But by default, Zebra uses an unspecified address
|
/// it to other nodes. But by default, Zebra uses an unspecified address
|
||||||
/// ("0.0.0.0" or "[::]"), which is not advertised to other nodes.
|
/// ("0.0.0.0" or "\[::\]"), which is not advertised to other nodes.
|
||||||
///
|
///
|
||||||
/// Zebra does not currently support:
|
/// Zebra does not currently support:
|
||||||
/// - [Advertising a different external IP address #1890](https://github.com/ZcashFoundation/zebra/issues/1890), or
|
/// - [Advertising a different external IP address #1890](https://github.com/ZcashFoundation/zebra/issues/1890), or
|
||||||
|
|
|
@ -110,8 +110,8 @@ pub const INVENTORY_ROTATION_INTERVAL: Duration = Duration::from_secs(53);
|
||||||
|
|
||||||
/// The default peer address crawler interval.
|
/// The default peer address crawler interval.
|
||||||
///
|
///
|
||||||
/// This should be at least [`HANDSHAKE_TIMEOUT`](constants::HANDSHAKE_TIMEOUT)
|
/// This should be at least [`HANDSHAKE_TIMEOUT`] lower than all other crawler
|
||||||
/// lower than all other crawler intervals.
|
/// intervals.
|
||||||
///
|
///
|
||||||
/// This makes the following sequence of events more likely:
|
/// This makes the following sequence of events more likely:
|
||||||
/// 1. a peer address crawl,
|
/// 1. a peer address crawl,
|
||||||
|
|
|
@ -16,7 +16,7 @@ mod tests;
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
/// The shared isolated [`TorClient`] instance.
|
/// The shared isolated [`TorClient`] instance.
|
||||||
///
|
///
|
||||||
/// TODO: turn this into a tower service that takes a hostname, and returns an `arti_client::DataStream`
|
/// TODO: turn this into a tower service that takes a hostname, and returns an [`arti_client::DataStream`]
|
||||||
/// (or a task that updates a watch channel when it's done?)
|
/// (or a task that updates a watch channel when it's done?)
|
||||||
pub static ref SHARED_TOR_CLIENT: Arc<Mutex<Option<TorClient<TokioRuntimeHandle>>>> =
|
pub static ref SHARED_TOR_CLIENT: Arc<Mutex<Option<TorClient<TokioRuntimeHandle>>>> =
|
||||||
Arc::new(Mutex::new(None));
|
Arc::new(Mutex::new(None));
|
||||||
|
|
|
@ -47,11 +47,13 @@
|
||||||
//!
|
//!
|
||||||
//! Inbound Zcash Listener Task:
|
//! Inbound Zcash Listener Task:
|
||||||
//! * accepts inbound connections on the listener port
|
//! * accepts inbound connections on the listener port
|
||||||
//! * initiates Zcash [`Handshake`]s, which creates [`Connection`] tasks for each inbound connection
|
//! * initiates Zcash [`peer::Handshake`]s, which creates [`peer::Connection`]
|
||||||
|
//! tasks for each inbound connection
|
||||||
//!
|
//!
|
||||||
//! Outbound Zcash Connector Service:
|
//! Outbound Zcash Connector Service:
|
||||||
//! * initiates outbound connections to peer addresses
|
//! * initiates outbound connections to peer addresses
|
||||||
//! * initiates Zcash [`Handshake`]s, which creates [`Connection`] tasks for each outbound connection
|
//! * initiates Zcash [`peer::Handshake`]s, which creates [`peer::Connection`]
|
||||||
|
//! tasks for each outbound connection
|
||||||
//!
|
//!
|
||||||
//! Zebra uses direct TCP connections to share blocks and mempool transactions with other peers.
|
//! Zebra uses direct TCP connections to share blocks and mempool transactions with other peers.
|
||||||
//!
|
//!
|
||||||
|
@ -65,16 +67,16 @@
|
||||||
//!
|
//!
|
||||||
//! [`peer::Client`] Service:
|
//! [`peer::Client`] Service:
|
||||||
//! * provides an interface for outbound requests to an individual peer
|
//! * provides an interface for outbound requests to an individual peer
|
||||||
//! * accepts [`Request`]s assigned to this peer by the [`PeerSet`]
|
//! * accepts [`Request`]s assigned to this peer by the `PeerSet`
|
||||||
//! * sends each request to the peer as Zcash [`Message`]
|
//! * sends each request to the peer as Zcash [`Message`][1]
|
||||||
//! * waits for the inbound response [`Message`] from the peer, and returns it as a [`Response`]
|
//! * waits for the inbound response [`Message`][1] from the peer, and returns it as a [`Response`]
|
||||||
//!
|
//!
|
||||||
//! [`peer::Connection`] Service:
|
//! [`peer::Connection`] Service:
|
||||||
//! * manages connection state: awaiting a request, or handling an inbound or outbound response
|
//! * manages connection state: awaiting a request, or handling an inbound or outbound response
|
||||||
//! * provides an interface for inbound requests from an individual peer
|
//! * provides an interface for inbound requests from an individual peer
|
||||||
//! * accepts inbound Zcash [`Message`]s from this peer
|
//! * accepts inbound Zcash [`Message`][1]s from this peer
|
||||||
//! * handles each message as a [`Request`] to the inbound service
|
//! * handles each message as a [`Request`] to the inbound service
|
||||||
//! * sends the [`Response`] to the peer as Zcash [`Message`]s
|
//! * sends the [`Response`] to the peer as Zcash [`Message`][1]s
|
||||||
//! * drops peer connections if the inbound request queue is overloaded
|
//! * drops peer connections if the inbound request queue is overloaded
|
||||||
//!
|
//!
|
||||||
//! Since the Zcash network protocol is bidirectional,
|
//! Since the Zcash network protocol is bidirectional,
|
||||||
|
@ -113,8 +115,10 @@
|
||||||
//! * adds seed peer addresses to the [`AddressBook`]
|
//! * adds seed peer addresses to the [`AddressBook`]
|
||||||
//!
|
//!
|
||||||
//! Peer Crawler Task:
|
//! Peer Crawler Task:
|
||||||
//! * discovers new peer addresses by sending [`Addr`] requests to connected peers
|
//! * discovers new peer addresses by sending `Addr` requests to connected peers
|
||||||
//! * initiates new outbound peer connections in response to application demand
|
//! * initiates new outbound peer connections in response to application demand
|
||||||
|
//!
|
||||||
|
//! [1]: protocol::external::Message
|
||||||
|
|
||||||
#![doc(html_favicon_url = "https://zfnd.org/wp-content/uploads/2022/03/zebra-favicon-128.png")]
|
#![doc(html_favicon_url = "https://zfnd.org/wp-content/uploads/2022/03/zebra-favicon-128.png")]
|
||||||
#![doc(html_logo_url = "https://zfnd.org/wp-content/uploads/2022/03/zebra-icon.png")]
|
#![doc(html_logo_url = "https://zfnd.org/wp-content/uploads/2022/03/zebra-icon.png")]
|
||||||
|
|
|
@ -34,8 +34,11 @@ pub(crate) mod tests;
|
||||||
///
|
///
|
||||||
/// Zebra also tracks how recently a peer has sent us messages, and derives peer
|
/// Zebra also tracks how recently a peer has sent us messages, and derives peer
|
||||||
/// liveness based on the current time. This derived state is tracked using
|
/// liveness based on the current time. This derived state is tracked using
|
||||||
/// [`AddressBook::maybe_connected_peers`] and
|
/// [`maybe_connected_peers`][mcp] and
|
||||||
/// [`AddressBook::reconnection_peers`].
|
/// [`reconnection_peers`][rp].
|
||||||
|
///
|
||||||
|
/// [mcp]: crate::AddressBook::maybe_connected_peers
|
||||||
|
/// [rp]: crate::AddressBook::reconnection_peers
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
|
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
|
||||||
pub enum PeerAddrState {
|
pub enum PeerAddrState {
|
||||||
|
@ -309,7 +312,7 @@ impl MetaAddr {
|
||||||
/// and the services must be the services from that peer's handshake.
|
/// and the services must be the services from that peer's handshake.
|
||||||
///
|
///
|
||||||
/// Otherwise:
|
/// Otherwise:
|
||||||
/// - malicious peers could interfere with other peers' `AddressBook` state,
|
/// - malicious peers could interfere with other peers' [`AddressBook`](crate::AddressBook) state,
|
||||||
/// or
|
/// or
|
||||||
/// - Zebra could advertise unreachable addresses to its own peers.
|
/// - Zebra could advertise unreachable addresses to its own peers.
|
||||||
pub fn new_responded(addr: &SocketAddr, services: &PeerServices) -> MetaAddrChange {
|
pub fn new_responded(addr: &SocketAddr, services: &PeerServices) -> MetaAddrChange {
|
||||||
|
@ -851,9 +854,11 @@ impl Ord for MetaAddr {
|
||||||
/// with `Responded` peers sorted first as a group.
|
/// with `Responded` peers sorted first as a group.
|
||||||
///
|
///
|
||||||
/// This order should not be used for reconnection attempts: use
|
/// This order should not be used for reconnection attempts: use
|
||||||
/// [`AddressBook::reconnection_peers`] instead.
|
/// [`reconnection_peers`][rp] instead.
|
||||||
///
|
///
|
||||||
/// See [`CandidateSet`] for more details.
|
/// See [`CandidateSet`] for more details.
|
||||||
|
///
|
||||||
|
/// [rp]: crate::AddressBook::reconnection_peers
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
use std::net::IpAddr::{V4, V6};
|
use std::net::IpAddr::{V4, V6};
|
||||||
use Ordering::*;
|
use Ordering::*;
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl ClientTestHarness {
|
||||||
.expect("heartbeat shutdown receiver endpoint has already been dropped");
|
.expect("heartbeat shutdown receiver endpoint has already been dropped");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Closes the receiver endpoint of [`ClientRequests`] that are supposed to be sent to the
|
/// Closes the receiver endpoint of [`ClientRequest`]s that are supposed to be sent to the
|
||||||
/// remote peer.
|
/// remote peer.
|
||||||
///
|
///
|
||||||
/// The remote peer that would receive the requests is mocked for testing.
|
/// The remote peer that would receive the requests is mocked for testing.
|
||||||
|
@ -92,7 +92,7 @@ impl ClientTestHarness {
|
||||||
.close();
|
.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drops the receiver endpoint of [`ClientRequests`], forcefully closing the channel.
|
/// Drops the receiver endpoint of [`ClientRequest`]s, forcefully closing the channel.
|
||||||
///
|
///
|
||||||
/// The remote peer that would receive the requests is mocked for testing.
|
/// The remote peer that would receive the requests is mocked for testing.
|
||||||
pub fn drop_outbound_client_request_receiver(&mut self) {
|
pub fn drop_outbound_client_request_receiver(&mut self) {
|
||||||
|
@ -118,7 +118,7 @@ impl ClientTestHarness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drops the receiver endpoint of [`InventoryChanges`], forcefully closing the channel.
|
/// Drops the receiver endpoint of [`InventoryChange`]s, forcefully closing the channel.
|
||||||
///
|
///
|
||||||
/// The inventory registry that would track the changes is mocked for testing.
|
/// The inventory registry that would track the changes is mocked for testing.
|
||||||
///
|
///
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
BoxError, Request, Response,
|
BoxError, Request, Response,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A wrapper around [`peer::Handshake`] that opens a TCP connection before
|
/// A wrapper around [`Handshake`] that opens a TCP connection before
|
||||||
/// forwarding to the inner handshake service. Writing this as its own
|
/// forwarding to the inner handshake service. Writing this as its own
|
||||||
/// [`tower::Service`] lets us apply unified timeout policies, etc.
|
/// [`tower::Service`] lets us apply unified timeout policies, etc.
|
||||||
pub struct Connector<S, C = NoChainTip>
|
pub struct Connector<S, C = NoChainTip>
|
||||||
|
|
|
@ -40,19 +40,19 @@ pub enum PeerError {
|
||||||
#[error("Peer closed connection")]
|
#[error("Peer closed connection")]
|
||||||
ConnectionClosed,
|
ConnectionClosed,
|
||||||
|
|
||||||
/// Zebra dropped the [`Connection`].
|
/// Zebra dropped the [`Connection`](crate::peer::Connection).
|
||||||
#[error("Internal connection dropped")]
|
#[error("Internal connection dropped")]
|
||||||
ConnectionDropped,
|
ConnectionDropped,
|
||||||
|
|
||||||
/// Zebra dropped the [`Client`].
|
/// Zebra dropped the [`Client`](crate::peer::Client).
|
||||||
#[error("Internal client dropped")]
|
#[error("Internal client dropped")]
|
||||||
ClientDropped,
|
ClientDropped,
|
||||||
|
|
||||||
/// A [`Client`]'s internal connection task exited.
|
/// A [`Client`](crate::peer::Client)'s internal connection task exited.
|
||||||
#[error("Internal peer connection task exited")]
|
#[error("Internal peer connection task exited")]
|
||||||
ConnectionTaskExited,
|
ConnectionTaskExited,
|
||||||
|
|
||||||
/// Zebra's [`Client`] cancelled its heartbeat task.
|
/// Zebra's [`Client`](crate::peer::Client) cancelled its heartbeat task.
|
||||||
#[error("Internal client cancelled its heartbeat task")]
|
#[error("Internal client cancelled its heartbeat task")]
|
||||||
ClientCancelledHeartbeatTask,
|
ClientCancelledHeartbeatTask,
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ pub enum PeerError {
|
||||||
#[error("Sending Client request timed out")]
|
#[error("Sending Client request timed out")]
|
||||||
ConnectionSendTimeout,
|
ConnectionSendTimeout,
|
||||||
|
|
||||||
/// Receiving a response to a [`peer::Client`] request took too long.
|
/// Receiving a response to a [`Client`](crate::peer::Client) request took too long.
|
||||||
#[error("Receiving client response timed out")]
|
#[error("Receiving client response timed out")]
|
||||||
ConnectionReceiveTimeout,
|
ConnectionReceiveTimeout,
|
||||||
|
|
||||||
|
@ -94,7 +94,9 @@ pub enum PeerError {
|
||||||
/// or peers can download and verify the missing data.
|
/// or peers can download and verify the missing data.
|
||||||
///
|
///
|
||||||
/// If the peer has some of the data, the request returns an [`Ok`] response,
|
/// If the peer has some of the data, the request returns an [`Ok`] response,
|
||||||
/// with any `notfound` data is marked as [`Missing`](InventoryResponse::Missing).
|
/// with any `notfound` data is marked as [`Missing`][m].
|
||||||
|
///
|
||||||
|
/// [m] crate::protocol::external::InventoryResponse::Missing
|
||||||
#[error("Remote peer could not find any of the items: {0:?}")]
|
#[error("Remote peer could not find any of the items: {0:?}")]
|
||||||
NotFoundResponse(Vec<InventoryHash>),
|
NotFoundResponse(Vec<InventoryHash>),
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ impl ErrorSlot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error returned when the `ErrorSlot` already contains an error.
|
/// Error returned when the [`ErrorSlot`] already contains an error.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AlreadyErrored {
|
pub struct AlreadyErrored {
|
||||||
/// The original error in the error slot.
|
/// The original error in the error slot.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Initial [`Handshake`s] with Zebra peers over a `PeerTransport`.
|
//! Initial [`Handshake`]s with Zebra peers over a [`PeerTransport`].
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::min,
|
cmp::min,
|
||||||
|
@ -747,7 +747,8 @@ pub struct HandshakeRequest<PeerTransport>
|
||||||
where
|
where
|
||||||
PeerTransport: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
PeerTransport: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
{
|
{
|
||||||
/// The tokio [`TcpStream`] or Tor [`DataStream`] to the peer.
|
/// The tokio [`TcpStream`](tokio::net::TcpStream) or Tor
|
||||||
|
/// [`DataStream`](arti_client::DataStream) to the peer.
|
||||||
pub data_stream: PeerTransport,
|
pub data_stream: PeerTransport,
|
||||||
|
|
||||||
/// The address of the peer, and other related information.
|
/// The address of the peer, and other related information.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Zcash `version` message node address serialization.
|
//! Zcash `version` message node address serialization.
|
||||||
//!
|
//!
|
||||||
//! The [`AddrInVersion`] format is the same as the `addr` ([`v1`]) message,
|
//! The [`AddrInVersion`] format is the same as the `addr` ([`super::v1`]) message,
|
||||||
//! but without the timestamp field.
|
//! but without the timestamp field.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
|
|
@ -126,14 +126,14 @@ impl Arbitrary for Version {
|
||||||
|
|
||||||
/// Returns a random canonical Zebra `SocketAddr`.
|
/// Returns a random canonical Zebra `SocketAddr`.
|
||||||
///
|
///
|
||||||
/// See [`canonical_ip_addr`] for details.
|
/// See [`canonical_ip_addr`](super::addr::canonical_ip_addr) for details.
|
||||||
pub fn canonical_socket_addr_strategy() -> impl Strategy<Value = SocketAddr> {
|
pub fn canonical_socket_addr_strategy() -> impl Strategy<Value = SocketAddr> {
|
||||||
any::<SocketAddr>().prop_map(canonical_socket_addr)
|
any::<SocketAddr>().prop_map(canonical_socket_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a random `SocketAddrV6` for use in `addr` (v1) Zcash network messages.
|
/// Returns a random `SocketAddrV6` for use in `addr` (v1) Zcash network messages.
|
||||||
///
|
///
|
||||||
/// See [`canonical_ip_addr`] for details.
|
/// See [`canonical_ip_addr`](super::addr::canonical_ip_addr) for details.
|
||||||
pub fn addr_v1_ipv6_mapped_socket_addr_strategy() -> impl Strategy<Value = SocketAddrV6> {
|
pub fn addr_v1_ipv6_mapped_socket_addr_strategy() -> impl Strategy<Value = SocketAddrV6> {
|
||||||
any::<SocketAddr>().prop_map(ipv6_mapped_socket_addr)
|
any::<SocketAddr>().prop_map(ipv6_mapped_socket_addr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,12 +83,14 @@ pub enum Message {
|
||||||
start_height: block::Height,
|
start_height: block::Height,
|
||||||
|
|
||||||
/// Whether the remote peer should announce relayed
|
/// Whether the remote peer should announce relayed
|
||||||
/// transactions or not, see [BIP 0037](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki)
|
/// transactions or not, see [BIP 0037].
|
||||||
///
|
///
|
||||||
/// Zebra does not implement the bloom filters in BIP 0037.
|
/// Zebra does not implement the bloom filters in [BIP 0037].
|
||||||
/// Instead, it only relays:
|
/// Instead, it only relays:
|
||||||
/// - newly verified best chain block hashes and mempool transaction IDs,
|
/// - newly verified best chain block hashes and mempool transaction IDs,
|
||||||
/// - after it reaches the chain tip.
|
/// - after it reaches the chain tip.
|
||||||
|
///
|
||||||
|
/// [BIP 0037]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
||||||
relay: bool,
|
relay: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -277,6 +279,7 @@ pub enum Message {
|
||||||
/// This was defined in [BIP35], which is included in Zcash.
|
/// This was defined in [BIP35], which is included in Zcash.
|
||||||
///
|
///
|
||||||
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#mempool)
|
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#mempool)
|
||||||
|
///
|
||||||
/// [BIP35]: https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki
|
/// [BIP35]: https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki
|
||||||
Mempool,
|
Mempool,
|
||||||
|
|
||||||
|
@ -287,6 +290,7 @@ pub enum Message {
|
||||||
/// Zebra currently ignores this message.
|
/// Zebra currently ignores this message.
|
||||||
///
|
///
|
||||||
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock)
|
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock)
|
||||||
|
///
|
||||||
/// [BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
/// [BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
||||||
FilterLoad {
|
FilterLoad {
|
||||||
/// The filter itself is simply a bit field of arbitrary
|
/// The filter itself is simply a bit field of arbitrary
|
||||||
|
@ -312,6 +316,7 @@ pub enum Message {
|
||||||
/// Zebra currently ignores this message.
|
/// Zebra currently ignores this message.
|
||||||
///
|
///
|
||||||
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock)
|
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock)
|
||||||
|
///
|
||||||
/// [BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
/// [BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
||||||
FilterAdd {
|
FilterAdd {
|
||||||
/// The data element to add to the current filter.
|
/// The data element to add to the current filter.
|
||||||
|
@ -330,6 +335,7 @@ pub enum Message {
|
||||||
/// Zebra currently ignores this message.
|
/// Zebra currently ignores this message.
|
||||||
///
|
///
|
||||||
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock)
|
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock)
|
||||||
|
///
|
||||||
/// [BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
/// [BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
||||||
FilterClear,
|
FilterClear,
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,11 +153,11 @@ pub enum Request {
|
||||||
/// how we interpret advertisements from zcashd, which sometimes advertises
|
/// how we interpret advertisements from zcashd, which sometimes advertises
|
||||||
/// multiple transactions at once.
|
/// multiple transactions at once.
|
||||||
///
|
///
|
||||||
/// This is implemented by sending an `inv` message containing the
|
/// This is implemented by sending an `inv` message containing the unmined
|
||||||
/// unmined transaction ID, allowing the remote peer to choose whether to download
|
/// transaction ID, allowing the remote peer to choose whether to download
|
||||||
/// it. Remote peers who choose to download the transaction will generate a
|
/// it. Remote peers who choose to download the transaction will generate a
|
||||||
/// [`Request::TransactionsById`] against the "inbound" service passed to
|
/// [`Request::TransactionsById`] against the "inbound" service passed to
|
||||||
/// [`zebra_network::init`].
|
/// [`init`](crate::init).
|
||||||
///
|
///
|
||||||
/// v4 transactions use a legacy transaction ID, and
|
/// v4 transactions use a legacy transaction ID, and
|
||||||
/// v5 transactions use a witnessed transaction ID.
|
/// v5 transactions use a witnessed transaction ID.
|
||||||
|
@ -178,7 +178,7 @@ pub enum Request {
|
||||||
/// block hash, allowing the remote peer to choose whether to download
|
/// block hash, allowing the remote peer to choose whether to download
|
||||||
/// it. Remote peers who choose to download the block will generate a
|
/// it. Remote peers who choose to download the block will generate a
|
||||||
/// [`Request::BlocksByHash`] against the "inbound" service passed to
|
/// [`Request::BlocksByHash`] against the "inbound" service passed to
|
||||||
/// [`zebra_network::init`].
|
/// [`init`](crate::init).
|
||||||
///
|
///
|
||||||
/// The peer set routes this request specially, sending it to *half of*
|
/// The peer set routes this request specially, sending it to *half of*
|
||||||
/// the available peers.
|
/// the available peers.
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub enum Request {
|
||||||
TransactionsById(HashSet<UnminedTxId>),
|
TransactionsById(HashSet<UnminedTxId>),
|
||||||
|
|
||||||
/// Query matching transactions in the mempool,
|
/// Query matching transactions in the mempool,
|
||||||
/// using a unique set of [`Hash`]s. Pre-V5 transactions are matched
|
/// using a unique set of [`struct@Hash`]s. Pre-V5 transactions are matched
|
||||||
/// directly; V5 transaction are matched just by the Hash, disregarding
|
/// directly; V5 transaction are matched just by the Hash, disregarding
|
||||||
/// the [`AuthDigest`].
|
/// the [`AuthDigest`].
|
||||||
TransactionsByMinedId(HashSet<Hash>),
|
TransactionsByMinedId(HashSet<Hash>),
|
||||||
|
@ -79,9 +79,9 @@ pub enum Response {
|
||||||
|
|
||||||
/// Returns matching transactions from the mempool.
|
/// Returns matching transactions from the mempool.
|
||||||
///
|
///
|
||||||
/// Since the [`TransactionsById`] request is unique,
|
/// Since the [`Request::TransactionsById`] request is unique,
|
||||||
/// the response transactions are also unique. The same applies to
|
/// the response transactions are also unique. The same applies to
|
||||||
/// [`TransactionByMinedId`] requests, since the mempool does not allow
|
/// [`Request::TransactionsByMinedId`] requests, since the mempool does not allow
|
||||||
/// different transactions with different mined IDs.
|
/// different transactions with different mined IDs.
|
||||||
Transactions(Vec<UnminedTx>),
|
Transactions(Vec<UnminedTx>),
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ impl PreparedBlock {
|
||||||
/// with fake zero-valued spent UTXOs.
|
/// with fake zero-valued spent UTXOs.
|
||||||
///
|
///
|
||||||
/// Only for use in tests.
|
/// Only for use in tests.
|
||||||
|
#[cfg(test)]
|
||||||
pub fn test_with_zero_spent_utxos(&self) -> ContextuallyValidBlock {
|
pub fn test_with_zero_spent_utxos(&self) -> ContextuallyValidBlock {
|
||||||
ContextuallyValidBlock::test_with_zero_spent_utxos(self)
|
ContextuallyValidBlock::test_with_zero_spent_utxos(self)
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,7 @@ impl PreparedBlock {
|
||||||
/// using a fake chain value pool change.
|
/// using a fake chain value pool change.
|
||||||
///
|
///
|
||||||
/// Only for use in tests.
|
/// Only for use in tests.
|
||||||
|
#[cfg(test)]
|
||||||
pub fn test_with_chain_pool_change(
|
pub fn test_with_chain_pool_change(
|
||||||
&self,
|
&self,
|
||||||
fake_chain_value_pool_change: ValueBalance<NegativeAllowed>,
|
fake_chain_value_pool_change: ValueBalance<NegativeAllowed>,
|
||||||
|
@ -91,13 +93,14 @@ impl PreparedBlock {
|
||||||
/// with no chain value pool change.
|
/// with no chain value pool change.
|
||||||
///
|
///
|
||||||
/// Only for use in tests.
|
/// Only for use in tests.
|
||||||
|
#[cfg(test)]
|
||||||
pub fn test_with_zero_chain_pool_change(&self) -> ContextuallyValidBlock {
|
pub fn test_with_zero_chain_pool_change(&self) -> ContextuallyValidBlock {
|
||||||
ContextuallyValidBlock::test_with_zero_chain_pool_change(self)
|
ContextuallyValidBlock::test_with_zero_chain_pool_change(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextuallyValidBlock {
|
impl ContextuallyValidBlock {
|
||||||
/// Create a block that's ready for non-finalized [`Chain`] contextual validation,
|
/// Create a block that's ready for non-finalized `Chain` contextual validation,
|
||||||
/// using a [`PreparedBlock`] and fake zero-valued spent UTXOs.
|
/// using a [`PreparedBlock`] and fake zero-valued spent UTXOs.
|
||||||
///
|
///
|
||||||
/// Only for use in tests.
|
/// Only for use in tests.
|
||||||
|
|
|
@ -89,7 +89,7 @@ pub struct PreparedBlock {
|
||||||
/// The height of the block.
|
/// The height of the block.
|
||||||
pub height: block::Height,
|
pub height: block::Height,
|
||||||
/// New transparent outputs created in this block, indexed by
|
/// New transparent outputs created in this block, indexed by
|
||||||
/// [`Outpoint`](transparent::Outpoint).
|
/// [`OutPoint`](transparent::OutPoint).
|
||||||
///
|
///
|
||||||
/// Each output is tagged with its transaction index in the block.
|
/// Each output is tagged with its transaction index in the block.
|
||||||
/// (The outputs of earlier transactions in a block can be spent by later
|
/// (The outputs of earlier transactions in a block can be spent by later
|
||||||
|
@ -112,7 +112,7 @@ pub struct PreparedBlock {
|
||||||
/// A contextually validated block, ready to be committed directly to the finalized state with
|
/// A contextually validated block, ready to be committed directly to the finalized state with
|
||||||
/// no checks, if it becomes the root of the best non-finalized chain.
|
/// no checks, if it becomes the root of the best non-finalized chain.
|
||||||
///
|
///
|
||||||
/// Used by the state service and non-finalized [`Chain`].
|
/// Used by the state service and non-finalized `Chain`.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct ContextuallyValidBlock {
|
pub struct ContextuallyValidBlock {
|
||||||
/// The block to commit to the state.
|
/// The block to commit to the state.
|
||||||
|
@ -125,7 +125,7 @@ pub struct ContextuallyValidBlock {
|
||||||
pub(crate) height: block::Height,
|
pub(crate) height: block::Height,
|
||||||
|
|
||||||
/// New transparent outputs created in this block, indexed by
|
/// New transparent outputs created in this block, indexed by
|
||||||
/// [`Outpoint`](transparent::Outpoint).
|
/// [`OutPoint`](transparent::OutPoint).
|
||||||
///
|
///
|
||||||
/// Note: although these transparent outputs are newly created, they may not
|
/// Note: although these transparent outputs are newly created, they may not
|
||||||
/// be unspent, since a later transaction in a block can spend outputs of an
|
/// be unspent, since a later transaction in a block can spend outputs of an
|
||||||
|
@ -135,7 +135,7 @@ pub struct ContextuallyValidBlock {
|
||||||
pub(crate) new_outputs: HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
|
pub(crate) new_outputs: HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
|
||||||
|
|
||||||
/// The outputs spent by this block, indexed by the [`transparent::Input`]'s
|
/// The outputs spent by this block, indexed by the [`transparent::Input`]'s
|
||||||
/// [`Outpoint`](transparent::Outpoint).
|
/// [`OutPoint`](transparent::OutPoint).
|
||||||
///
|
///
|
||||||
/// Note: these inputs can come from earlier transactions in this block,
|
/// Note: these inputs can come from earlier transactions in this block,
|
||||||
/// or earlier blocks in the chain.
|
/// or earlier blocks in the chain.
|
||||||
|
@ -164,7 +164,7 @@ pub struct FinalizedBlock {
|
||||||
/// The height of the block.
|
/// The height of the block.
|
||||||
pub height: block::Height,
|
pub height: block::Height,
|
||||||
/// New transparent outputs created in this block, indexed by
|
/// New transparent outputs created in this block, indexed by
|
||||||
/// [`Outpoint`](transparent::Outpoint).
|
/// [`OutPoint`](transparent::OutPoint).
|
||||||
///
|
///
|
||||||
/// Note: although these transparent outputs are newly created, they may not
|
/// Note: although these transparent outputs are newly created, they may not
|
||||||
/// be unspent, since a later transaction in a block can spend outputs of an
|
/// be unspent, since a later transaction in a block can spend outputs of an
|
||||||
|
@ -188,15 +188,15 @@ impl From<&PreparedBlock> for PreparedBlock {
|
||||||
// This allows moving work out of the single-threaded state service.
|
// This allows moving work out of the single-threaded state service.
|
||||||
|
|
||||||
impl ContextuallyValidBlock {
|
impl ContextuallyValidBlock {
|
||||||
/// Create a block that's ready for non-finalized [`Chain`] contextual validation,
|
/// Create a block that's ready for non-finalized `Chain` contextual validation,
|
||||||
/// using a [`PreparedBlock`] and the UTXOs it spends.
|
/// using a [`PreparedBlock`] and the UTXOs it spends.
|
||||||
///
|
///
|
||||||
/// When combined, `prepared.new_outputs` and `spent_utxos` must contain
|
/// When combined, `prepared.new_outputs` and `spent_utxos` must contain
|
||||||
/// the [`Utxo`]s spent by every transparent input in this block,
|
/// the [`Utxo`](transparent::Utxo)s spent by every transparent input in this block,
|
||||||
/// including UTXOs created by earlier transactions in this block.
|
/// including UTXOs created by earlier transactions in this block.
|
||||||
///
|
///
|
||||||
/// Note: a [`ContextuallyValidBlock`] isn't actually contextually valid until
|
/// Note: a [`ContextuallyValidBlock`] isn't actually contextually valid until
|
||||||
/// [`Chain::update_chain_state_with`] returns success.
|
/// `Chain::update_chain_state_with` returns success.
|
||||||
pub fn with_block_and_spent_utxos(
|
pub fn with_block_and_spent_utxos(
|
||||||
prepared: PreparedBlock,
|
prepared: PreparedBlock,
|
||||||
mut spent_outputs: HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
|
mut spent_outputs: HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
|
||||||
|
@ -282,7 +282,8 @@ impl From<ContextuallyValidBlock> for FinalizedBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
/// A query about or modification to the chain state, via the [`StateService`].
|
/// A query about or modification to the chain state, via the
|
||||||
|
/// [`StateService`](crate::service::StateService).
|
||||||
pub enum Request {
|
pub enum Request {
|
||||||
/// Performs contextual validation of the given block, committing it to the
|
/// Performs contextual validation of the given block, committing it to the
|
||||||
/// state if successful.
|
/// state if successful.
|
||||||
|
@ -370,8 +371,9 @@ pub enum Request {
|
||||||
/// [`block::Height`] using `.into()`.
|
/// [`block::Height`] using `.into()`.
|
||||||
Block(HashOrHeight),
|
Block(HashOrHeight),
|
||||||
|
|
||||||
/// Request a UTXO identified by the given Outpoint, waiting until it becomes
|
/// Request a UTXO identified by the given
|
||||||
/// available if it is unknown.
|
/// [`OutPoint`](transparent::OutPoint), waiting until it becomes available
|
||||||
|
/// if it is unknown.
|
||||||
///
|
///
|
||||||
/// This request is purely informational, and there are no guarantees about
|
/// This request is purely informational, and there are no guarantees about
|
||||||
/// whether the UTXO remains unspent or is on the best chain, or any chain.
|
/// whether the UTXO remains unspent or is on the best chain, or any chain.
|
||||||
|
@ -432,7 +434,8 @@ pub enum Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
/// A read-only query about the chain state, via the [`ReadStateService`].
|
/// A read-only query about the chain state, via the
|
||||||
|
/// [`ReadStateService`](crate::service::ReadStateService).
|
||||||
pub enum ReadRequest {
|
pub enum ReadRequest {
|
||||||
/// Looks up a block by hash or height in the current best chain.
|
/// Looks up a block by hash or height in the current best chain.
|
||||||
///
|
///
|
||||||
|
@ -455,7 +458,8 @@ pub enum ReadRequest {
|
||||||
|
|
||||||
/// Looks up the balance of a set of transparent addresses.
|
/// Looks up the balance of a set of transparent addresses.
|
||||||
///
|
///
|
||||||
/// Returns an [`Amount`] with the total balance of the set of addresses.
|
/// Returns an [`Amount`](zebra_chain::amount::Amount) with the total
|
||||||
|
/// balance of the set of addresses.
|
||||||
AddressBalance(HashSet<transparent::Address>),
|
AddressBalance(HashSet<transparent::Address>),
|
||||||
|
|
||||||
/// Looks up a Sapling note commitment tree either by a hash or height.
|
/// Looks up a Sapling note commitment tree either by a hash or height.
|
||||||
|
|
|
@ -328,7 +328,7 @@ impl<T> TestChild<T> {
|
||||||
/// To never match any log lines, use `RegexSet::empty()`.
|
/// To never match any log lines, use `RegexSet::empty()`.
|
||||||
///
|
///
|
||||||
/// This method is a [`TestChild::with_failure_regexes`] wrapper for
|
/// This method is a [`TestChild::with_failure_regexes`] wrapper for
|
||||||
/// strings, [`Regex`]es, and [`RegexSet`]s.
|
/// strings, `Regex`es, and [`RegexSet`]s.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
@ -944,7 +944,7 @@ impl<T> TestOutput<T> {
|
||||||
/// Checks each line in the output of a command, using a closure to determine
|
/// Checks each line in the output of a command, using a closure to determine
|
||||||
/// if the line is valid.
|
/// if the line is valid.
|
||||||
///
|
///
|
||||||
/// See [`output_check`] for details.
|
/// See [`Self::output_check`] for details.
|
||||||
#[instrument(skip(self, line_predicate, output))]
|
#[instrument(skip(self, line_predicate, output))]
|
||||||
pub fn any_output_line<P>(
|
pub fn any_output_line<P>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -975,7 +975,7 @@ impl<T> TestOutput<T> {
|
||||||
|
|
||||||
/// Tests if any lines in the output of a command contain `s`.
|
/// Tests if any lines in the output of a command contain `s`.
|
||||||
///
|
///
|
||||||
/// See [`any_output_line`] for details.
|
/// See [`Self::any_output_line`] for details.
|
||||||
#[instrument(skip(self, output))]
|
#[instrument(skip(self, output))]
|
||||||
pub fn any_output_line_contains(
|
pub fn any_output_line_contains(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -231,9 +231,9 @@ impl MockServiceBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [`MockService`] to be used in `proptest`s.
|
/// Create a [`MockService`] to be used in [`mod@proptest`]s.
|
||||||
///
|
///
|
||||||
/// The assertions performed by [`MockService`] use the macros provided by [`proptest`], like
|
/// The assertions performed by [`MockService`] use the macros provided by [`mod@proptest`], like
|
||||||
/// [`prop_assert`].
|
/// [`prop_assert`].
|
||||||
pub fn for_prop_tests<Request, Response, Error>(
|
pub fn for_prop_tests<Request, Response, Error>(
|
||||||
self,
|
self,
|
||||||
|
@ -455,7 +455,7 @@ impl<Request, Response, Error> MockService<Request, Response, PanicAssertion, Er
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of [`MockService`] methods that use [`proptest`] assertions.
|
/// Implementation of [`MockService`] methods that use [`mod@proptest`] assertions.
|
||||||
impl<Request, Response, Error> MockService<Request, Response, PropTestAssertion, Error> {
|
impl<Request, Response, Error> MockService<Request, Response, PropTestAssertion, Error> {
|
||||||
/// Expect a specific request to be received.
|
/// Expect a specific request to be received.
|
||||||
///
|
///
|
||||||
|
@ -468,7 +468,7 @@ impl<Request, Response, Error> MockService<Request, Response, PropTestAssertion,
|
||||||
/// sender of the requests receives an error.
|
/// sender of the requests receives an error.
|
||||||
///
|
///
|
||||||
/// If no request is received or if a request is received that's not equal to the expected
|
/// If no request is received or if a request is received that's not equal to the expected
|
||||||
/// request, this method returns an error generated by a [`proptest`] assertion.
|
/// request, this method returns an error generated by a [`mod@proptest`] assertion.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -535,7 +535,7 @@ impl<Request, Response, Error> MockService<Request, Response, PropTestAssertion,
|
||||||
/// to it. If no response is sent, the sender of the requests receives an error.
|
/// to it. If no response is sent, the sender of the requests receives an error.
|
||||||
///
|
///
|
||||||
/// If the `condition` function returns `false`, this method returns an error generated by a
|
/// If the `condition` function returns `false`, this method returns an error generated by a
|
||||||
/// [`proptest`] assertion.
|
/// [`mod@proptest`] assertion.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -597,7 +597,7 @@ impl<Request, Response, Error> MockService<Request, Response, PropTestAssertion,
|
||||||
/// for the max delay time configured by [`MockServiceBuilder::with_max_request_delay`].
|
/// for the max delay time configured by [`MockServiceBuilder::with_max_request_delay`].
|
||||||
///
|
///
|
||||||
/// If the queue is not empty or if a request is received before the max request delay timeout
|
/// If the queue is not empty or if a request is received before the max request delay timeout
|
||||||
/// expires, an error generated by a [`proptest`] assertion is returned.
|
/// expires, an error generated by a [`mod@proptest`] assertion is returned.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -652,7 +652,7 @@ impl<Request, Response, Error> MockService<Request, Response, PropTestAssertion,
|
||||||
/// received, and then returns that.
|
/// received, and then returns that.
|
||||||
///
|
///
|
||||||
/// If the queue is empty and a request is not received before the max request delay timeout
|
/// If the queue is empty and a request is not received before the max request delay timeout
|
||||||
/// expires, an error generated by a [`proptest`] assertion is returned.
|
/// expires, an error generated by a [`mod@proptest`] assertion is returned.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
async fn next_request(
|
async fn next_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -852,7 +852,7 @@ trait AssertionType {}
|
||||||
/// Represents normal Rust assertions that panic, like [`assert_eq`].
|
/// Represents normal Rust assertions that panic, like [`assert_eq`].
|
||||||
pub enum PanicAssertion {}
|
pub enum PanicAssertion {}
|
||||||
|
|
||||||
/// Represents [`proptest`] assertions that return errors, like [`prop_assert_eq`].
|
/// Represents [`mod@proptest`] assertions that return errors, like [`prop_assert_eq`].
|
||||||
pub enum PropTestAssertion {}
|
pub enum PropTestAssertion {}
|
||||||
|
|
||||||
impl AssertionType for PanicAssertion {}
|
impl AssertionType for PanicAssertion {}
|
||||||
|
|
|
@ -53,14 +53,14 @@ type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
|
||||||
|
|
||||||
/// Controls how long we wait for a transaction download request to complete.
|
/// Controls how long we wait for a transaction download request to complete.
|
||||||
///
|
///
|
||||||
/// This is currently equal to [`crate::components::sync::BLOCK_DOWNLOAD_TIMEOUT`] for
|
/// This is currently equal to [`BLOCK_DOWNLOAD_TIMEOUT`] for
|
||||||
/// consistency, even though parts of the rationale used for defining the value
|
/// consistency, even though parts of the rationale used for defining the value
|
||||||
/// don't apply here (e.g. we can drop transactions hashes when the queue is full).
|
/// don't apply here (e.g. we can drop transactions hashes when the queue is full).
|
||||||
pub(crate) const TRANSACTION_DOWNLOAD_TIMEOUT: Duration = BLOCK_DOWNLOAD_TIMEOUT;
|
pub(crate) const TRANSACTION_DOWNLOAD_TIMEOUT: Duration = BLOCK_DOWNLOAD_TIMEOUT;
|
||||||
|
|
||||||
/// Controls how long we wait for a transaction verify request to complete.
|
/// Controls how long we wait for a transaction verify request to complete.
|
||||||
///
|
///
|
||||||
/// This is currently equal to [`crate::components::sync::BLOCK_VERIFY_TIMEOUT`] for
|
/// This is currently equal to [`BLOCK_VERIFY_TIMEOUT`] for
|
||||||
/// consistency.
|
/// consistency.
|
||||||
///
|
///
|
||||||
/// This timeout may lead to denial of service, which will be handled in
|
/// This timeout may lead to denial of service, which will be handled in
|
||||||
|
|
Loading…
Reference in New Issue