Skip to content

Commit

Permalink
Merge pull request #2547 from dusk-network/chores
Browse files Browse the repository at this point in the history
rusk: check for double nullifiers during tx preverify
  • Loading branch information
herr-seppia authored Oct 1, 2024
2 parents 2d7adcd + 466c566 commit 79ebddd
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 30 deletions.
6 changes: 2 additions & 4 deletions rusk/src/bin/config/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ use serde::{Deserialize, Serialize};

pub const DEFAULT_BLOCK_GAS_LIMIT: u64 = 5 * 1_000_000_000;

// Tue Sep 10 2024 20:00:00 GMT+0000
pub const DEFAULT_GENESIS_TIMESTAMP: u64 = 1725998400;

use crate::args::Args;

#[derive(Serialize, Deserialize, Clone, Default)]
Expand All @@ -26,6 +23,7 @@ pub(crate) struct ChainConfig {

consensus_keys_path: Option<PathBuf>,
#[serde(with = "humantime_serde")]
#[serde(default)]
generation_timeout: Option<Duration>,

max_queue_size: Option<usize>,
Expand Down Expand Up @@ -109,6 +107,6 @@ impl ChainConfig {
.map(|n| n.as_secs())
.expect("This is heavy.")
})
.unwrap_or(DEFAULT_GENESIS_TIMESTAMP)
.unwrap_or_default()
}
}
31 changes: 8 additions & 23 deletions rusk/src/lib/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{fmt, io};
use dusk_bytes::Serializable;
use execution_core::{
signatures::bls::PublicKey as BlsPublicKey, transfer::phoenix::CoreError,
BlsScalar, Dusk, Error as ExecErr,
BlsScalar, Error as ExecErr,
};
use rusk_abi::PiecrustError;

Expand All @@ -25,6 +25,8 @@ pub enum Error {
OutOfGas,
/// Repeated nullifier in transaction verification
RepeatingNullifiers(Vec<BlsScalar>),
/// Repeated nullifier in the same transaction
DoubleNullifiers,
/// Repeating a nonce that has already been used
RepeatingNonce(Box<BlsPublicKey>, u64),
/// Wrong inputs and/or outputs in the transaction verification
Expand All @@ -45,10 +47,6 @@ pub enum Error {
Vm(PiecrustError),
/// IO Errors
Io(io::Error),
/// Bad block height in coinbase (got, expected)
CoinbaseBlockHeight(u64, u64),
/// Bad dusk spent in coinbase (got, expected).
CoinbaseDuskSpent(Dusk, Dusk),
/// Failed to produce proper state
#[cfg(feature = "chain")]
InconsistentState(Box<dusk_consensus::operations::VerificationOutput>),
Expand Down Expand Up @@ -157,18 +155,12 @@ impl fmt::Display for Error {
Error::Transaction(err) => write!(f, "Transaction Error: {err}"),
Error::Phoenix(err) => write!(f, "Phoenix error: {err}"),
Error::Other(err) => write!(f, "Other error: {err}"),
Error::CoinbaseBlockHeight(got, expected) => write!(
f,
"Coinbase has block height {got}, expected {expected}"
),
Error::CoinbaseDuskSpent(got, expected) => {
write!(f, "Coinbase has dusk spent {got}, expected {expected}")
}
Error::ProofVerification => write!(f, "Proof verification failure"),
Error::OutOfGas => write!(f, "Out of gas"),
Error::RepeatingNullifiers(n) => {
write!(f, "Nullifiers repeat: {n:?}")
write!(f, "Nullifiers already spent: {n:?}")
}
Error::DoubleNullifiers => write!(f, "Double nullifiers"),
Error::RepeatingNonce(account, nonce) => {
let encoded_account =
bs58::encode(&account.to_bytes()).into_string();
Expand All @@ -178,21 +170,14 @@ impl fmt::Display for Error {
write!(f,"Expected: 0 < (inputs: {inputs_len}) < 5, 0 ≤ (outputs: {outputs_len}) < 3")
}
#[cfg(feature = "chain")]
Error::InconsistentState(verification_output) => {
write!(
f,
"Inconsistent state verification data {verification_output}",
)
Error::InconsistentState(vo) => {
write!(f, "Inconsistent state verification data {vo}",)
}
Error::CommitNotFound(commit_id) => {
write!(f, "Commit not found, id = {}", hex::encode(commit_id),)
}
Error::InvalidCreditsCount(height, credits) => {
write!(
f,
"Invalid credits count, height = {}, credits = {}",
height, credits
)
write!(f, "Invalid credits: H= {height}, credits= {credits}",)
}
Error::MemoTooLarge(size) => {
write!(f, "The memo size {size} is too large")
Expand Down
20 changes: 17 additions & 3 deletions rusk/src/lib/node/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ impl VMExecution for Rusk {

match tx {
ProtocolTransaction::Phoenix(tx) => {
let existing_nullifiers = self
.existing_nullifiers(&tx.nullifiers().to_vec())
.map_err(|e| {
let tx_nullifiers = tx.nullifiers().to_vec();
let existing_nullifiers =
self.existing_nullifiers(&tx_nullifiers).map_err(|e| {
anyhow::anyhow!("Cannot check nullifiers: {e}")
})?;

Expand All @@ -134,6 +134,11 @@ impl VMExecution for Rusk {
return Err(anyhow::anyhow!("Invalid tx: {err}"));
}

if !has_unique_elements(tx_nullifiers) {
let err = crate::Error::DoubleNullifiers;
return Err(anyhow::anyhow!("Invalid tx: {err}"));
}

match crate::verifier::verify_proof(tx) {
Ok(true) => Ok(()),
Ok(false) => Err(anyhow::anyhow!("Invalid proof")),
Expand Down Expand Up @@ -228,6 +233,15 @@ impl VMExecution for Rusk {
}
}

fn has_unique_elements<T>(iter: T) -> bool
where
T: IntoIterator,
T::Item: Eq + std::hash::Hash,
{
let mut uniq = std::collections::HashSet::new();
iter.into_iter().all(move |x| uniq.insert(x))
}

impl Rusk {
fn query_provisioners(
&self,
Expand Down

0 comments on commit 79ebddd

Please sign in to comment.