Skip to content

Commit

Permalink
node-data: move attestation structs in their own module
Browse files Browse the repository at this point in the history
  • Loading branch information
herr-seppia committed Jul 3, 2024
1 parent bef750e commit a6f87b1
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 160 deletions.
164 changes: 6 additions & 158 deletions node-data/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,128 +13,22 @@ 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;
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<Option<IterationInfo>>,
}

impl IterationsInfo {
pub fn new(attestations: Vec<Option<IterationInfo>>) -> Self {
Self {
att_list: attestations,
}
}

pub fn to_missed_generators(&self) -> Result<Vec<BlsPublicKey>, 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<Item = &PublicKeyBytes> {
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<const N: usize>(bytes: &[u8; N]) -> String {
let e = hex::encode(bytes);
Expand All @@ -148,49 +42,3 @@ pub fn to_str<const N: usize>(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<T> Dummy<T> for PublicKeyBytes {
fn dummy_with_rng<R: Rng + ?Sized>(_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<T> Dummy<T> for bls::PublicKey {
fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
let rand_val = rng.gen();
bls::PublicKey::from_sk_seed_u64(rand_val)
}
}

impl<T> Dummy<T> for Signature {
fn dummy_with_rng<R: Rng + ?Sized>(_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<T> Dummy<T> for IterationsInfo {
fn dummy_with_rng<R: Rng + ?Sized>(_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 }
}
}
}
165 changes: 165 additions & 0 deletions node-data/src/ledger/attestation.rs
Original file line number Diff line number Diff line change
@@ -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<Option<IterationInfo>>,
}

impl IterationsInfo {
pub fn new(attestations: Vec<Option<IterationInfo>>) -> Self {
Self {
att_list: attestations,
}
}

pub fn to_missed_generators(&self) -> Result<Vec<BlsPublicKey>, 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<Item = &PublicKeyBytes> {
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<T> Dummy<T> for PublicKeyBytes {
fn dummy_with_rng<R: Rng + ?Sized>(_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<T> Dummy<T> for bls::PublicKey {
fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
let rand_val = rng.gen();
bls::PublicKey::from_sk_seed_u64(rand_val)
}
}

impl<T> Dummy<T> for Signature {
fn dummy_with_rng<R: Rng + ?Sized>(_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<T> Dummy<T> for IterationsInfo {
fn dummy_with_rng<R: Rng + ?Sized>(_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 }
}
}
}
4 changes: 2 additions & 2 deletions node-data/src/ledger/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit a6f87b1

Please sign in to comment.