Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
herr-seppia committed Jul 4, 2024
1 parent 3b7b075 commit 1e89669
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 14 deletions.
156 changes: 143 additions & 13 deletions node-data/src/ledger/faults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,153 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::message::payload::{Ratification, Validation};
use crate::message::{
payload::{Candidate, Ratification, Validation, Vote},
ConsensusHeader, SignInfo, StepMessage,
};

use dusk_bytes::Serializable as DuskSerializeble;
use execution_core::{BlsAggPublicKey, BlsSigError, BlsSignature};

use super::*;

#[derive(Debug, Clone)]
#[cfg_attr(any(feature = "faker", test), derive(fake::Dummy, Eq, PartialEq))]
#[allow(clippy::large_enum_variant)]
pub enum Fault {
DoubleCandidate(Header, Header),
DoubleRatification(Ratification, Ratification),
DoubleValidation(Validation, Validation),
DoubleCandidate(FaultData<Hash>, FaultData<Hash>),
DoubleRatificationVote(FaultData<Vote>, FaultData<Vote>),
DoubleValidationVote(FaultData<Vote>, FaultData<Vote>),
}

impl Fault {
/// Hash the serialized form
pub fn hash(&self) -> [u8; 32] {
let mut b = vec![];
self.write(&mut b).expect("Write to a vec shall not fail");
Hasher::digest(b).to_bytes()
}

/// Return the IDs of the inner faults.
pub fn ids(&self) -> (Hash, Hash) {
match self {
Fault::DoubleCandidate(a, b) => {
let seed = Candidate::SIGN_SEED;
let a = Hasher::digest(a.get_signed_data(seed)).to_bytes();
let b = Hasher::digest(b.get_signed_data(seed)).to_bytes();
(a, b)
}
Fault::DoubleRatificationVote(a, b) => {
let seed = Ratification::SIGN_SEED;
let a = Hasher::digest(a.get_signed_data(seed)).to_bytes();
let b = Hasher::digest(b.get_signed_data(seed)).to_bytes();
(a, b)
}
Fault::DoubleValidationVote(a, b) => {
let seed = Validation::SIGN_SEED;
let a = Hasher::digest(a.get_signed_data(seed)).to_bytes();
let b = Hasher::digest(b.get_signed_data(seed)).to_bytes();
(a, b)
}
}
}

//& Get the ConsensusHeader related to the inner FaultDatas
pub fn consensus_header(&self) -> (&ConsensusHeader, &ConsensusHeader) {
match self {
Fault::DoubleRatificationVote(a, b)
| Fault::DoubleValidationVote(a, b) => (&a.header, &b.header),
Fault::DoubleCandidate(a, b) => (&a.header, &b.header),
}
}

/// Check if both faults are signed properly
pub fn verify_sigs(&self) -> Result<(), BlsSigError> {
match self {
Fault::DoubleCandidate(a, b) => {
let seed = Candidate::SIGN_SEED;
let msg = a.get_signed_data(seed);
Self::verify_signature(&a.sig, &msg)?;
let msg = b.get_signed_data(seed);
Self::verify_signature(&b.sig, &msg)?;
Ok(())
}
Fault::DoubleRatificationVote(a, b) => {
let seed = Ratification::SIGN_SEED;
let msg = a.get_signed_data(seed);
Self::verify_signature(&a.sig, &msg)?;
let msg = b.get_signed_data(seed);
Self::verify_signature(&b.sig, &msg)?;
Ok(())
}
Fault::DoubleValidationVote(a, b) => {
let seed = Validation::SIGN_SEED;
let msg = a.get_signed_data(seed);
Self::verify_signature(&a.sig, &msg)?;
let msg = b.get_signed_data(seed);
Self::verify_signature(&b.sig, &msg)?;
Ok(())
}
}
}

fn verify_signature(
sign_info: &SignInfo,
msg: &[u8],
) -> Result<(), BlsSigError> {
let signature = sign_info.signature.inner();
let sig = BlsSignature::from_bytes(signature)?;
let pk = BlsAggPublicKey::from(sign_info.signer.inner());
pk.verify(&sig, msg)
}
}

impl FaultData<Hash> {
fn get_signed_data(&self, seed: &[u8]) -> Vec<u8> {
let mut signable = self.header.signable();
signable.extend_from_slice(seed);
signable.extend_from_slice(&self.data);
signable
}
}
impl FaultData<Vote> {
fn get_signed_data(&self, seed: &[u8]) -> Vec<u8> {
let mut signable = self.header.signable();
signable.extend_from_slice(seed);
self.data
.write(&mut signable)
.expect("Writing to vec should succeed");
signable
}
}

#[derive(Debug, Clone)]
#[cfg_attr(any(feature = "faker", test), derive(fake::Dummy, Eq, PartialEq))]
#[allow(clippy::large_enum_variant)]
pub struct FaultData<V> {
header: ConsensusHeader,
sig: SignInfo,
data: V,
}

impl<V: Serializable> Serializable for FaultData<V> {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
self.header.write(w)?;
self.sig.write(w)?;
self.data.write(w)?;
Ok(())
}

fn read<R: Read>(r: &mut R) -> io::Result<Self>
where
Self: Sized,
{
let header = ConsensusHeader::read(r)?;
let sig = SignInfo::read(r)?;
let data = V::read(r)?;

Ok(Self { header, sig, data })
}
}

impl Serializable for Fault {
Expand All @@ -33,12 +161,12 @@ impl Serializable for Fault {
a.write(w)?;
b.write(w)?;
}
Fault::DoubleRatification(a, b) => {
Fault::DoubleRatificationVote(a, b) => {
w.write_all(&[1u8])?;
a.write(w)?;
b.write(w)?;
}
Fault::DoubleValidation(a, b) => {
Fault::DoubleValidationVote(a, b) => {
w.write_all(&[2u8])?;
a.write(w)?;
b.write(w)?;
Expand All @@ -54,14 +182,16 @@ impl Serializable for Fault {
{
let fault = Self::read_u8(r)?;
let fault = match fault {
0 => Fault::DoubleCandidate(Header::read(r)?, Header::read(r)?),
1 => Fault::DoubleRatification(
Ratification::read(r)?,
Ratification::read(r)?,
0 => {
Fault::DoubleCandidate(FaultData::read(r)?, FaultData::read(r)?)
}
1 => Fault::DoubleRatificationVote(
FaultData::read(r)?,
FaultData::read(r)?,
),
2 => Fault::DoubleValidation(
Validation::read(r)?,
Validation::read(r)?,
2 => Fault::DoubleValidationVote(
FaultData::read(r)?,
FaultData::read(r)?,
),
p => {
println!("{p}");
Expand Down
15 changes: 15 additions & 0 deletions node-data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub mod message;

use std::io::{self, Read, Write};

use ledger::Hash;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum StepName {
Proposal = 0,
Expand Down Expand Up @@ -74,3 +76,16 @@ pub trait Serializable {
Ok(buf)
}
}

impl Serializable for Hash {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
w.write_all(&self[..])
}

fn read<R: Read>(r: &mut R) -> io::Result<Self>
where
Self: Sized,
{
Self::read_bytes(r)
}
}
2 changes: 1 addition & 1 deletion node/src/database/rocksdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl<'db, DB: DBAccess> Ledger for DBTransaction<'db, DB> {
{
let cf = self.ledger_faults_cf;

// store all block transactions
// store all block faults
for f in faults {
let mut d = vec![];
f.write(&mut d)?;
Expand Down

0 comments on commit 1e89669

Please sign in to comment.