dusk_node_data/ledger/
attestation.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use serde::Serialize;
8
9use super::*;
10use crate::message::payload::RatificationResult;
11
12#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Serialize)]
13#[cfg_attr(any(feature = "faker", test), derive(Dummy))]
14pub struct Attestation {
15    pub result: RatificationResult,
16    pub validation: StepVotes,
17    pub ratification: StepVotes,
18}
19
20#[derive(Debug, Default, Clone, Copy, Eq, Hash, PartialEq, Serialize)]
21#[cfg_attr(any(feature = "faker", test), derive(Dummy))]
22pub struct StepVotes {
23    pub bitset: u64,
24    pub(crate) aggregate_signature: Signature,
25}
26
27impl StepVotes {
28    pub fn new(aggregate_signature: [u8; 48], bitset: u64) -> StepVotes {
29        StepVotes {
30            bitset,
31            aggregate_signature: Signature(aggregate_signature),
32        }
33    }
34
35    pub fn is_empty(&self) -> bool {
36        if self.bitset == 0 {
37            debug_assert!(
38                self.aggregate_signature.is_zeroed(),
39                "inconsistent struct, signature"
40            );
41        }
42
43        if self.aggregate_signature.is_zeroed() {
44            debug_assert_eq!(self.bitset, 0, "inconsistent struct, bitset");
45        }
46
47        self.bitset == 0 && self.aggregate_signature.is_zeroed()
48    }
49
50    pub fn aggregate_signature(&self) -> &Signature {
51        &self.aggregate_signature
52    }
53}
54
55/// A wrapper of 48-sized array to facilitate Signature
56#[derive(Clone, Copy, Eq, Hash, PartialEq, Serialize)]
57pub struct Signature(
58    #[serde(serialize_with = "crate::serialize_hex")] [u8; 48],
59);
60
61impl Signature {
62    pub const EMPTY: [u8; 48] = [0u8; 48];
63
64    fn is_zeroed(&self) -> bool {
65        self.0 == Self::EMPTY
66    }
67    pub fn inner(&self) -> &[u8; 48] {
68        &self.0
69    }
70}
71
72impl std::fmt::Debug for Signature {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        f.debug_struct("Signature")
75            .field("signature", &to_str(&self.0))
76            .finish()
77    }
78}
79
80impl From<[u8; 48]> for Signature {
81    fn from(value: [u8; 48]) -> Self {
82        Self(value)
83    }
84}
85
86impl Default for Signature {
87    fn default() -> Self {
88        Self(Self::EMPTY)
89    }
90}
91
92/// Includes a failed attestation and the key of the expected block
93/// generator
94pub type IterationInfo = (Attestation, PublicKeyBytes);
95
96/// Defines a set of attestations of former iterations
97#[derive(Default, Eq, PartialEq, Clone, Serialize)]
98#[serde(transparent)]
99pub struct IterationsInfo {
100    /// Represents a list of attestations where position is the iteration
101    /// number
102    pub att_list: Vec<Option<IterationInfo>>,
103}
104
105impl IterationsInfo {
106    pub fn new(attestations: Vec<Option<IterationInfo>>) -> Self {
107        Self {
108            att_list: attestations,
109        }
110    }
111}
112
113#[cfg(any(feature = "faker", test))]
114pub mod faker {
115    use rand::Rng;
116
117    use super::*;
118    use crate::bls;
119
120    impl<T> Dummy<T> for PublicKeyBytes {
121        fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
122            let rand_val = rng.gen::<[u8; 32]>();
123            let mut bls_key = [0u8; 96];
124            bls_key[..32].copy_from_slice(&rand_val);
125            bls::PublicKeyBytes(bls_key)
126        }
127    }
128
129    impl<T> Dummy<T> for bls::PublicKey {
130        fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
131            let rand_val = rng.gen();
132            bls::PublicKey::from_sk_seed_u64(rand_val)
133        }
134    }
135
136    impl<T> Dummy<T> for Signature {
137        fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
138            let rand_val = rng.gen::<[u8; 32]>();
139            let mut rand_signature = Self::EMPTY;
140            rand_signature[..32].copy_from_slice(&rand_val);
141
142            Signature(rand_signature)
143        }
144    }
145
146    impl<T> Dummy<T> for IterationsInfo {
147        fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
148            let att_list = vec![
149                None,
150                Some(Faker.fake_with_rng(rng)),
151                None,
152                Some(Faker.fake_with_rng(rng)),
153                None,
154            ];
155            IterationsInfo { att_list }
156        }
157    }
158}