diff --git a/node-data/src/ledger.rs b/node-data/src/ledger.rs index 42b2155379..e29ed507a0 100644 --- a/node-data/src/ledger.rs +++ b/node-data/src/ledger.rs @@ -13,8 +13,12 @@ pub use block::{Block, BlockWithLabel, Hash, Label}; mod transaction; pub use transaction::{SpentTransaction, Transaction}; -use crate::bls::{self, PublicKeyBytes}; -use crate::message::payload::{RatificationResult, Vote}; +mod attestation; +pub use attestation::{ + Attestation, IterationInfo, IterationsInfo, Signature, StepVotes, +}; + +use crate::bls::PublicKeyBytes; use crate::Serializable; use dusk_bytes::DeserializableSlice; @@ -22,119 +26,9 @@ use rusk_abi::hash::Hasher; use sha3::Digest; use std::io::{self, Read, Write}; -use execution_core::BlsPublicKey; - #[cfg(any(feature = "faker", test))] use fake::{Dummy, Fake, Faker}; -#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)] -#[cfg_attr(any(feature = "faker", test), derive(Dummy))] -pub struct Attestation { - pub result: RatificationResult, - pub validation: StepVotes, - pub ratification: StepVotes, -} - -#[derive(Debug, Default, Clone, Copy, Eq, Hash, PartialEq)] -#[cfg_attr(any(feature = "faker", test), derive(Dummy))] -pub struct StepVotes { - pub bitset: u64, - pub(crate) aggregate_signature: Signature, -} - -impl StepVotes { - pub fn new(aggregate_signature: [u8; 48], bitset: u64) -> StepVotes { - StepVotes { - bitset, - aggregate_signature: Signature(aggregate_signature), - } - } - - pub fn is_empty(&self) -> bool { - self.bitset == 0 || self.aggregate_signature.is_zeroed() - } - - pub fn aggregate_signature(&self) -> &Signature { - &self.aggregate_signature - } -} - -/// a wrapper of 48-sized array to facilitate Signature -#[derive(Clone, Copy, Eq, Hash, PartialEq)] -pub struct Signature([u8; 48]); - -impl Signature { - pub const EMPTY: [u8; 48] = [0u8; 48]; - - fn is_zeroed(&self) -> bool { - self.0 == Self::EMPTY - } - pub fn inner(&self) -> &[u8; 48] { - &self.0 - } -} - -impl std::fmt::Debug for Signature { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Signature") - .field("signature", &to_str(&self.0)) - .finish() - } -} - -impl From<[u8; 48]> for Signature { - fn from(value: [u8; 48]) -> Self { - Self(value) - } -} - -impl Default for Signature { - fn default() -> Self { - Self(Self::EMPTY) - } -} - -/// Includes a failed attestation and the key of the expected block -/// generator -pub type IterationInfo = (Attestation, PublicKeyBytes); - -/// Defines a set of attestations of any former iterations -#[derive(Default, Eq, PartialEq, Clone)] -pub struct IterationsInfo { - /// Represents a list of attestations where position is the iteration - /// number - pub att_list: Vec>, -} - -impl IterationsInfo { - pub fn new(attestations: Vec>) -> Self { - Self { - att_list: attestations, - } - } - - pub fn to_missed_generators(&self) -> Result, io::Error> { - self.to_missed_generators_bytes() - .map(|pk| BlsPublicKey::from_slice(pk.inner()).map_err(|e|{ - tracing::error!("Unable to generate missing generators from failed_iterations: {e:?}"); - io::Error::new(io::ErrorKind::InvalidData, "Error in deserialize") - })) - .collect() - } - - pub fn to_missed_generators_bytes( - &self, - ) -> impl Iterator { - self.att_list - .iter() - .flatten() - .filter(|(c, _)| { - c.result == RatificationResult::Fail(Vote::NoCandidate) - }) - .map(|(_, pk)| pk) - } -} - /// Encode a byte array into a shortened HEX representation. pub fn to_str(bytes: &[u8; N]) -> String { let e = hex::encode(bytes); @@ -148,49 +42,3 @@ pub fn to_str(bytes: &[u8; N]) -> String { first.to_owned() + "..." + second } - -#[cfg(any(feature = "faker", test))] -pub mod faker { - use super::*; - use crate::bls::PublicKeyBytes; - use rand::Rng; - - impl Dummy for PublicKeyBytes { - fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { - let rand_val = rng.gen::<[u8; 32]>(); - let mut bls_key = [0u8; 96]; - bls_key[..32].copy_from_slice(&rand_val); - bls::PublicKeyBytes(bls_key) - } - } - - impl Dummy for bls::PublicKey { - fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { - let rand_val = rng.gen(); - bls::PublicKey::from_sk_seed_u64(rand_val) - } - } - - impl Dummy for Signature { - fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { - let rand_val = rng.gen::<[u8; 32]>(); - let mut rand_signature = Self::EMPTY; - rand_signature[..32].copy_from_slice(&rand_val); - - Signature(rand_signature) - } - } - - impl Dummy for IterationsInfo { - fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { - let att_list = vec![ - None, - Some(Faker.fake_with_rng(rng)), - None, - Some(Faker.fake_with_rng(rng)), - None, - ]; - IterationsInfo { att_list } - } - } -} diff --git a/node-data/src/ledger/attestation.rs b/node-data/src/ledger/attestation.rs new file mode 100644 index 0000000000..8cbba66fee --- /dev/null +++ b/node-data/src/ledger/attestation.rs @@ -0,0 +1,165 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +use super::*; + +use execution_core::BlsPublicKey; + +use crate::message::payload::{RatificationResult, Vote}; + +#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)] +#[cfg_attr(any(feature = "faker", test), derive(Dummy))] +pub struct Attestation { + pub result: RatificationResult, + pub validation: StepVotes, + pub ratification: StepVotes, +} + +#[derive(Debug, Default, Clone, Copy, Eq, Hash, PartialEq)] +#[cfg_attr(any(feature = "faker", test), derive(Dummy))] +pub struct StepVotes { + pub bitset: u64, + pub(crate) aggregate_signature: Signature, +} + +impl StepVotes { + pub fn new(aggregate_signature: [u8; 48], bitset: u64) -> StepVotes { + StepVotes { + bitset, + aggregate_signature: Signature(aggregate_signature), + } + } + + pub fn is_empty(&self) -> bool { + self.bitset == 0 || self.aggregate_signature.is_zeroed() + } + + pub fn aggregate_signature(&self) -> &Signature { + &self.aggregate_signature + } +} + +/// a wrapper of 48-sized array to facilitate Signature +#[derive(Clone, Copy, Eq, Hash, PartialEq)] +pub struct Signature([u8; 48]); + +impl Signature { + pub const EMPTY: [u8; 48] = [0u8; 48]; + + fn is_zeroed(&self) -> bool { + self.0 == Self::EMPTY + } + pub fn inner(&self) -> &[u8; 48] { + &self.0 + } +} + +impl std::fmt::Debug for Signature { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Signature") + .field("signature", &to_str(&self.0)) + .finish() + } +} + +impl From<[u8; 48]> for Signature { + fn from(value: [u8; 48]) -> Self { + Self(value) + } +} + +impl Default for Signature { + fn default() -> Self { + Self(Self::EMPTY) + } +} + +/// Includes a failed attestation and the key of the expected block +/// generator +pub type IterationInfo = (Attestation, PublicKeyBytes); + +/// Defines a set of attestations of any former iterations +#[derive(Default, Eq, PartialEq, Clone)] +pub struct IterationsInfo { + /// Represents a list of attestations where position is the iteration + /// number + pub att_list: Vec>, +} + +impl IterationsInfo { + pub fn new(attestations: Vec>) -> Self { + Self { + att_list: attestations, + } + } + + pub fn to_missed_generators(&self) -> Result, io::Error> { + self.to_missed_generators_bytes() + .map(|pk| BlsPublicKey::from_slice(pk.inner()).map_err(|e|{ + tracing::error!("Unable to generate missing generators from failed_iterations: {e:?}"); + io::Error::new(io::ErrorKind::InvalidData, "Error in deserialize") + })) + .collect() + } + + pub fn to_missed_generators_bytes( + &self, + ) -> impl Iterator { + self.att_list + .iter() + .flatten() + .filter(|(c, _)| { + c.result == RatificationResult::Fail(Vote::NoCandidate) + }) + .map(|(_, pk)| pk) + } +} + +#[cfg(any(feature = "faker", test))] +pub mod faker { + use super::*; + use crate::bls; + use rand::Rng; + + impl Dummy for PublicKeyBytes { + fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { + let rand_val = rng.gen::<[u8; 32]>(); + let mut bls_key = [0u8; 96]; + bls_key[..32].copy_from_slice(&rand_val); + bls::PublicKeyBytes(bls_key) + } + } + + impl Dummy for bls::PublicKey { + fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { + let rand_val = rng.gen(); + bls::PublicKey::from_sk_seed_u64(rand_val) + } + } + + impl Dummy for Signature { + fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { + let rand_val = rng.gen::<[u8; 32]>(); + let mut rand_signature = Self::EMPTY; + rand_signature[..32].copy_from_slice(&rand_val); + + Signature(rand_signature) + } + } + + impl Dummy for IterationsInfo { + fn dummy_with_rng(_config: &T, rng: &mut R) -> Self { + let att_list = vec![ + None, + Some(Faker.fake_with_rng(rng)), + None, + Some(Faker.fake_with_rng(rng)), + None, + ]; + IterationsInfo { att_list } + } + } +} diff --git a/node-data/src/ledger/header.rs b/node-data/src/ledger/header.rs index cf9144d003..bd1566cfd4 100644 --- a/node-data/src/ledger/header.rs +++ b/node-data/src/ledger/header.rs @@ -18,7 +18,7 @@ pub struct Header { pub seed: Seed, pub state_hash: Hash, pub event_hash: Hash, - pub generator_bls_pubkey: bls::PublicKeyBytes, + pub generator_bls_pubkey: PublicKeyBytes, pub txroot: Hash, pub gas_limit: u64, pub iteration: u8, @@ -103,7 +103,7 @@ impl Header { gas_limit, prev_block_hash, seed: Seed::from(seed), - generator_bls_pubkey: bls::PublicKeyBytes(generator_bls_pubkey), + generator_bls_pubkey: PublicKeyBytes(generator_bls_pubkey), iteration, state_hash, event_hash,