Skip to content

Commit

Permalink
missed generators
Browse files Browse the repository at this point in the history
  • Loading branch information
herr-seppia committed Jan 16, 2024
1 parent 55ca1e4 commit f161f76
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 23 deletions.
3 changes: 3 additions & 0 deletions consensus/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use std::fmt;

use dusk_bls12_381_sign::PublicKey;
use node_data::ledger::{Block, Header, SpentTransaction, Transaction};

pub type StateRoot = [u8; 32];
Expand All @@ -14,13 +15,15 @@ pub type EventHash = [u8; 32];
#[derive(Debug)]
pub enum Error {
Failed,
InvalidIterationInfo
}

#[derive(Default, Clone, Debug)]
pub struct CallParams {
pub round: u64,
pub block_gas_limit: u64,
pub generator_pubkey: node_data::bls::PublicKey,
pub missed_generators: Vec<PublicKey>,
}

#[derive(Default)]
Expand Down
11 changes: 8 additions & 3 deletions consensus/src/proposal/block_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<T: Operations> Generator<T> {
&self,
ru: &RoundUpdate,
iteration: u8,
failed_iterations: Vec<Option<Certificate>>,
failed_iterations: IterationsInfo,
) -> Result<Message, crate::operations::Error> {
// Sign seed
let seed = ru
Expand Down Expand Up @@ -80,14 +80,19 @@ impl<T: Operations> Generator<T> {
ru: &RoundUpdate,
seed: Seed,
iteration: u8,
failed_iterations: Vec<Option<Certificate>>,
failed_iterations: IterationsInfo,
) -> Result<Block, crate::operations::Error> {
let start_time = Instant::now();

let missed_generators = failed_iterations
.to_missed_generators()
.map_err(|_| crate::operations::Error::InvalidIterationInfo)?;

let call_params = CallParams {
round: ru.round,
block_gas_limit: config::DEFAULT_BLOCK_GAS_LIMIT,
generator_pubkey: ru.pubkey_bls.clone(),
missed_generators,
};

let result = self
Expand Down Expand Up @@ -118,7 +123,7 @@ impl<T: Operations> Generator<T> {
prev_block_cert: *ru.cert(),
txroot,
iteration,
failed_iterations: IterationsInfo::new(failed_iterations),
failed_iterations,
};

// Apply a delay in block generator accordingly
Expand Down
3 changes: 2 additions & 1 deletion consensus/src/proposal/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::commons::{ConsensusError, Database};
use crate::execution_ctx::ExecutionCtx;
use crate::msg_handler::{HandleMsgOutput, MsgHandler};
use crate::operations::Operations;
use node_data::ledger::IterationsInfo;
use node_data::message::Message;
use std::cmp;
use std::sync::Arc;
Expand Down Expand Up @@ -67,7 +68,7 @@ impl<T: Operations + 'static, D: Database> ProposalStep<T, D> {
.generate_candidate_message(
&ctx.round_update,
ctx.iteration,
failed_certificates,
IterationsInfo::new(failed_certificates),
)
.await
{
Expand Down
12 changes: 7 additions & 5 deletions consensus/src/step_votes_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::commons::RoundUpdate;
use node_data::ledger::StepVotes;
use node_data::bls::PublicKeyBytes;
use node_data::ledger::{to_str, Certificate};
use node_data::ledger::{IterationInfo, StepVotes};
use node_data::message::{payload, Message, Topics};
use std::collections::HashMap;
use std::fmt;
Expand Down Expand Up @@ -98,6 +99,7 @@ pub type SafeCertificateInfoRegistry = Arc<Mutex<CertInfoRegistry>>;
struct IterationCerts {
valid: Option<CertificateInfo>,
nil: CertificateInfo,
generator: PublicKeyBytes,
}

impl IterationCerts {
Expand Down Expand Up @@ -181,16 +183,16 @@ impl CertInfoRegistry {
pub(crate) fn get_nil_certificates(
&mut self,
to: u8,
) -> Vec<Option<Certificate>> {
) -> Vec<Option<IterationInfo>> {
let mut res = Vec::with_capacity(to as usize);

for iteration in 0u8..to {
res.push(
self.cert_list
.get(&iteration)
.map(|c| c.nil)
.filter(|ci| ci.has_votes())
.map(|ci| ci.cert),
.map(|c| (c.nil, c.generator))
.filter(|(ci, _)| ci.is_ready())
.map(|(ci, pk)| (ci.cert, pk)),
);
}

Expand Down
14 changes: 10 additions & 4 deletions node-data/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::bls::PublicKeyBytes;
use crate::ledger::*;
use crate::message::payload::{QuorumType, Ratification, ValidationResult};
use crate::Serializable;
Expand Down Expand Up @@ -192,11 +193,12 @@ impl Serializable for IterationsInfo {
let count = self.cert_list.len() as u8;
w.write_all(&count.to_le_bytes())?;

for cert in &self.cert_list {
match cert {
Some(cert) => {
for iter in &self.cert_list {
match iter {
Some((cert, pk)) => {
w.write_all(&[1])?;
cert.write(w)?;
w.write_all(pk.inner())?;
}
None => w.write_all(&[0])?,
}
Expand All @@ -218,7 +220,11 @@ impl Serializable for IterationsInfo {

let cert = match opt {
0 => None,
1 => Some(Certificate::read(r)?),
1 => {
let cert = Certificate::read(r)?;
let pk = Self::read_bytes(r)?;
Some((cert, PublicKeyBytes(pk)))
}
_ => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
Expand Down
24 changes: 21 additions & 3 deletions node-data/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::{bls, Serializable};
use crate::bls::{self, PublicKeyBytes};
use crate::Serializable;

use dusk_bytes::DeserializableSlice;
use rusk_abi::hash::Hasher;
use sha3::Digest;
use std::io::{self, Read, Write};
Expand Down Expand Up @@ -323,20 +326,35 @@ impl PartialEq<Self> for SpentTransaction {

impl Eq for SpentTransaction {}

pub type IterationInfo = (Certificate, PublicKeyBytes);

/// Defines a set of certificates of any former iterations
#[derive(Default, Eq, PartialEq, Clone)]
pub struct IterationsInfo {
/// Represents a list of certificates where position is the iteration
/// number
pub cert_list: Vec<Option<Certificate>>,
pub cert_list: Vec<Option<IterationInfo>>,
}

impl IterationsInfo {
pub fn new(certificates: Vec<Option<Certificate>>) -> Self {
pub fn new(certificates: Vec<Option<IterationInfo>>) -> Self {
Self {
cert_list: certificates,
}
}

pub fn to_missed_generators(
&self,
) -> Result<Vec<dusk_bls12_381_sign::PublicKey>, io::Error> {
self.cert_list
.iter()
.flatten()
.map(|(_, pk)| dusk_bls12_381_sign::PublicKey::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()
}
}

/// Encode a byte array into a shortened HEX representation.
Expand Down
12 changes: 10 additions & 2 deletions node/src/chain/header_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,16 @@ impl<'a, DB: database::DB> Validator<'a, DB> {
.iter()
.enumerate()
{
if let Some(cert) = cert {
if let Some((cert, pk)) = cert {
info!(event = "verify_cert", cert_type = "failed_cert", iter);
let expected_pk = self.provisioners.current().get_generator(
candidate_block.iteration,
candidate_block.seed,
candidate_block.height,
);
if pk != &expected_pk {
anyhow::bail!("Invalid generator. Expected {expected_pk:?}, actual {pk:?}");
}

let quorums = verify_block_cert(
self.block.seed,
Expand All @@ -148,7 +156,7 @@ impl<'a, DB: database::DB> Validator<'a, DB> {
candidate_block.height,
cert,
iter as u8,
false,
true,
)
.await?;

Expand Down
40 changes: 36 additions & 4 deletions rusk/src/lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ impl Rusk {
block_gas_limit: u64,
generator: &BlsPublicKey,
txs: I,
missed_generators: &[BlsPublicKey],
) -> Result<(Vec<SpentTransaction>, Vec<Transaction>, VerificationOutput)>
{
let inner = self.inner.lock();
Expand Down Expand Up @@ -179,11 +180,12 @@ impl Rusk {
}
}

reward_and_update_root(
reward_slash_and_update_root(
&mut session,
block_height,
dusk_spent,
generator,
missed_generators,
)?;

let state_root = session.root();
Expand All @@ -206,14 +208,22 @@ impl Rusk {
block_gas_limit: u64,
generator: &BlsPublicKey,
txs: &[Transaction],
missed_generators: &[BlsPublicKey],
) -> Result<(Vec<SpentTransaction>, VerificationOutput)> {
let inner = self.inner.lock();

let current_commit = inner.current_commit;
let mut session =
rusk_abi::new_session(&inner.vm, current_commit, block_height)?;

accept(&mut session, block_height, block_gas_limit, generator, txs)
accept(
&mut session,
block_height,
block_gas_limit,
generator,
txs,
missed_generators,
)
}

/// Accept the given transactions.
Expand All @@ -228,6 +238,7 @@ impl Rusk {
generator: BlsPublicKey,
txs: Vec<Transaction>,
consistency_check: Option<VerificationOutput>,
missed_generators: &[BlsPublicKey],
) -> Result<(Vec<SpentTransaction>, VerificationOutput)> {
let mut inner = self.inner.lock();

Expand All @@ -241,6 +252,7 @@ impl Rusk {
block_gas_limit,
&generator,
&txs[..],
missed_generators,
)?;

if let Some(expected_verification) = consistency_check {
Expand Down Expand Up @@ -269,6 +281,7 @@ impl Rusk {
generator: BlsPublicKey,
txs: Vec<Transaction>,
consistency_check: Option<VerificationOutput>,
missed_generators: &[BlsPublicKey],
) -> Result<(Vec<SpentTransaction>, VerificationOutput)> {
let mut inner = self.inner.lock();

Expand All @@ -282,6 +295,7 @@ impl Rusk {
block_gas_limit,
&generator,
&txs[..],
missed_generators,
)?;

if let Some(expected_verification) = consistency_check {
Expand Down Expand Up @@ -620,6 +634,7 @@ fn accept(
block_gas_limit: u64,
generator: &BlsPublicKey,
txs: &[Transaction],
missed_generators: &[BlsPublicKey],
) -> Result<(Vec<SpentTransaction>, VerificationOutput)> {
let mut block_gas_left = block_gas_limit;

Expand Down Expand Up @@ -651,7 +666,13 @@ fn accept(
});
}

reward_and_update_root(session, block_height, dusk_spent, generator)?;
reward_slash_and_update_root(
session,
block_height,
dusk_spent,
generator,
missed_generators,
)?;

let state_root = session.root();
let event_hash = event_hasher.finalize().into();
Expand Down Expand Up @@ -717,11 +738,12 @@ fn update_hasher(hasher: &mut Sha3_256, event: Event) {
hasher.update(event.data);
}

fn reward_and_update_root(
fn reward_slash_and_update_root(
session: &mut Session,
block_height: u64,
dusk_spent: Dusk,
generator: &BlsPublicKey,
slashing: &[BlsPublicKey],
) -> Result<()> {
let (dusk_value, generator_value) =
coinbase_value(block_height, dusk_spent);
Expand All @@ -738,6 +760,16 @@ fn reward_and_update_root(
&(*generator, generator_value),
u64::MAX,
)?;
let slash_amount = emission_amount(block_height) / 255;

for to_slash in slashing {
session.call::<_, ()>(
STAKE_CONTRACT,
"slash",
&(*to_slash, slash_amount),
u64::MAX,
)?;
}

session.call::<_, ()>(TRANSFER_CONTRACT, "update_root", &(), u64::MAX)?;

Expand Down
Loading

0 comments on commit f161f76

Please sign in to comment.