Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanity Check proposal sender from proposal messages #2344

Merged
merged 2 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions primitives/src/slots_allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ impl Validators {
}

/// Calculates the slot band of the validator that owns the given slot.
///
/// ## Panic
/// This function requires the slot to be within bounds. If it is not this function will panic.
pub fn get_band_from_slot(&self, slot: u16) -> u16 {
assert!(slot < Policy::SLOTS);

Expand All @@ -151,11 +154,17 @@ impl Validators {
}

/// Returns the validator given the slot number.
///
/// ## Panic
/// This function requires the slot_number to be within bounds. If it is not this function will panic.
pub fn get_validator_by_slot_number(&self, slot_number: u16) -> &Validator {
&self.validators[self.get_band_from_slot(slot_number) as usize]
}

/// Returns the validator given the slot band.
///
/// ## Panic
/// This function requires the slot_band to be within bounds. If it is not this function will panic.
pub fn get_validator_by_slot_band(&self, slot_band: u16) -> &Validator {
&self.validators[slot_band as usize]
}
Expand Down
29 changes: 29 additions & 0 deletions validator/src/proposal_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use nimiq_consensus::consensus::{
use nimiq_keys::Ed25519Signature as SchnorrSignature;
use nimiq_macros::store_waker;
use nimiq_network_interface::network::{CloseReason, MsgAcceptance, Network, PubsubId as _, Topic};
use nimiq_primitives::policy::Policy;
use nimiq_serde::Serialize;
use nimiq_tendermint::SignedProposalMessage;
use nimiq_validator_network::{PubsubId, ValidatorNetwork};
Expand Down Expand Up @@ -356,6 +357,7 @@ where
// proposal is in the future
let bc = self.blockchain.read();
if bc.block_number() >= proposal.0.proposal.block_number {
log::trace!(proposal = ?proposal.0, "Encountered old proposal");
// The proposal is older than the current height, meaning the macro block was finalized and cannot be changed.
// The proposal is dropped.
self.network
Expand All @@ -366,13 +368,40 @@ where
return;
}

// Make sure the proposal is in the current epoch.
if Policy::election_block_after(bc.block_number()) < proposal.0.proposal.block_number {
log::trace!(proposal = ?proposal.0, "Encountered proposal from the next epoch");
// The proposal is in the next epoch. The validators can not be determined for it and as such it must be ignored.
// The proposal is dropped.
self.network
.validate_message::<ProposalTopic<TValidatorNetwork>>(
proposal.1,
MsgAcceptance::Ignore,
);
return;
}

// Fetch current validators.
let validators = bc.current_validators().unwrap();

// No need to hold the lock as validators would only change with an election block which makes
// the validity of proposals moot.
drop(bc);

// Make sure the given validator id is not outside of the range of valid validator ids for the current validator set.
if proposal.0.signer as usize > validators.num_validators() {
// The proposal indicates a nonsensical proposer as the validator id is out of bounds.
// The proposal is dropped and propagation is stopped.
self.network
.validate_message::<ProposalTopic<TValidatorNetwork>>(
proposal.1,
MsgAcceptance::Reject,
);
return;
} else {
log::debug!(proposal = ?proposal.0, "Proposal signer does not exist");
}

// Get the validator whose id was presented in the proposal message.
let stated_proposer = validators.get_validator_by_slot_band(proposal.0.signer);

Expand Down