diff --git a/node/src/components/consensus/highway_core/active_validator.rs b/node/src/components/consensus/highway_core/active_validator.rs index 81f89f11c3..dc09ed1e2d 100644 --- a/node/src/components/consensus/highway_core/active_validator.rs +++ b/node/src/components/consensus/highway_core/active_validator.rs @@ -1,3 +1,5 @@ +use std::fmt::{self, Debug}; + use tracing::warn; use super::{ @@ -36,7 +38,6 @@ pub(crate) enum Effect { /// If the rounds are long enough (i.e. message delivery is fast enough) and there are enough /// honest validators, there will be a lot of confirmations for the proposal, and enough witness /// votes citing all those confirmations, to create a summit and finalize the proposal. -#[derive(Debug)] pub(crate) struct ActiveValidator { /// Our own validator index. vidx: ValidatorIndex, @@ -48,6 +49,17 @@ pub(crate) struct ActiveValidator { next_timer: u64, } +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Debug` +impl Debug for ActiveValidator { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("ActiveValidator") + .field("vidx", &self.vidx) + .field("round_exp", &self.round_exp) + .field("next_timer", &self.next_timer) + .finish() + } +} + impl ActiveValidator { /// Creates a new `ActiveValidator` and the timer effect for the first call. pub(crate) fn new( diff --git a/node/src/components/consensus/highway_core/vertex.rs b/node/src/components/consensus/highway_core/vertex.rs index d6a9d97d4b..8b2aa30868 100644 --- a/node/src/components/consensus/highway_core/vertex.rs +++ b/node/src/components/consensus/highway_core/vertex.rs @@ -1,4 +1,7 @@ -use std::iter; +use std::{ + fmt::{self, Debug}, + iter, +}; use serde::{Deserialize, Serialize}; @@ -51,7 +54,7 @@ impl Vertex { } } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Serialize, Deserialize)] #[serde(bound( serialize = "C::Hash: Serialize", deserialize = "C::Hash: Deserialize<'de>", @@ -61,6 +64,36 @@ pub(crate) struct SignedWireVote { pub(crate) signature: ::Signature, } +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Clone` +impl Clone for SignedWireVote { + fn clone(&self) -> Self { + Self { + wire_vote: self.wire_vote.clone(), + signature: self.signature.clone(), + } + } +} + +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Debug` +impl Debug for SignedWireVote { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SignedWireVote") + .field("wire_vote", &self.wire_vote) + .field("signature", &self.signature) + .finish() + } +} + +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `PartialEq` +impl PartialEq for SignedWireVote { + fn eq(&self, other: &SignedWireVote) -> bool { + self.wire_vote == other.wire_vote && self.signature == other.signature + } +} + +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Eq` +impl Eq for SignedWireVote {} + impl SignedWireVote { pub(crate) fn new(wire_vote: WireVote, secret_key: &C::ValidatorSecret) -> Self { let signature = secret_key.sign(&wire_vote.hash()); diff --git a/node/src/components/consensus/highway_core/vote.rs b/node/src/components/consensus/highway_core/vote.rs index 45ee10f524..884e5d18a5 100644 --- a/node/src/components/consensus/highway_core/vote.rs +++ b/node/src/components/consensus/highway_core/vote.rs @@ -1,3 +1,5 @@ +use std::fmt::{self, Debug}; + use serde::{Deserialize, Serialize}; use super::{state::State, validators::ValidatorIndex, vertex::WireVote}; @@ -103,7 +105,6 @@ impl Panorama { } /// A vote sent to or received from the network. -#[derive(Clone, Debug, Eq, PartialEq)] pub(crate) struct Vote { // TODO: Signature /// The list of latest messages and faults observed by the creator of this message. @@ -125,6 +126,52 @@ pub(crate) struct Vote { pub(crate) signature: ::Signature, } +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Clone` +impl Clone for Vote { + fn clone(&self) -> Self { + Self { + panorama: self.panorama.clone(), + seq_number: self.seq_number, + creator: self.creator, + block: self.block.clone(), + skip_idx: self.skip_idx.clone(), + timestamp: self.timestamp, + signature: self.signature.clone(), + } + } +} + +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Debug` +impl Debug for Vote { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Vote") + .field("panorama", &self.panorama) + .field("seq_number", &self.seq_number) + .field("creator", &self.creator) + .field("block", &self.block) + .field("skip_idx", &self.skip_idx) + .field("timestamp", &self.timestamp) + .field("signature", &self.signature) + .finish() + } +} + +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `PartialEq` +impl PartialEq for Vote { + fn eq(&self, other: &Vote) -> bool { + self.panorama == other.panorama + && self.seq_number == other.seq_number + && self.creator == other.creator + && self.block == other.block + && self.skip_idx == other.skip_idx + && self.timestamp == other.timestamp + && self.signature == other.signature + } +} + +// `#[derive]` doesn't work if `C::ValidatorSecret` is not `Eq` +impl Eq for Vote {} + impl Vote { /// Creates a new `Vote` from the `WireVote`, and returns the value if it contained any. /// Values must be stored as a block, with the same hash. diff --git a/node/src/components/consensus/traits.rs b/node/src/components/consensus/traits.rs index 61ab9a5667..fea48a8aee 100644 --- a/node/src/components/consensus/traits.rs +++ b/node/src/components/consensus/traits.rs @@ -24,7 +24,7 @@ pub(crate) trait HashT: impl HashT for H where H: Eq + Ord + Clone + Debug + Hash + Serialize + DeserializeOwned {} /// A validator's secret signing key. -pub(crate) trait ValidatorSecret: Debug + Eq + Clone { +pub(crate) trait ValidatorSecret { type Hash; type Signature: Eq + PartialEq + Clone + Debug + Hash + Serialize + DeserializeOwned;