mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 12:49:23 +00:00
Have verify_precommit_signature return if it verified the signature
Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits.
This commit is contained in:
@@ -380,13 +380,16 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns Ok(true) if this was a Precommit which had its signature validated
|
||||||
|
// Returns Ok(false) if the signature wasn't validated yet
|
||||||
|
// Returns Err if the signature was invalid
|
||||||
fn verify_precommit_signature(
|
fn verify_precommit_signature(
|
||||||
&self,
|
&self,
|
||||||
sender: N::ValidatorId,
|
sender: N::ValidatorId,
|
||||||
round: RoundNumber,
|
round: RoundNumber,
|
||||||
data: &DataFor<N>,
|
data: &DataFor<N>,
|
||||||
) -> Result<(), TendermintError<N::ValidatorId>> {
|
) -> Result<bool, TendermintError<N::ValidatorId>> {
|
||||||
if let Data::Precommit(Some((id, sig))) = data {
|
Ok(if let Data::Precommit(Some((id, sig))) = data {
|
||||||
// Also verify the end_time of the commit
|
// Also verify the end_time of the commit
|
||||||
// Only perform this verification if we already have the end_time
|
// Only perform this verification if we already have the end_time
|
||||||
// Else, there's a DoS where we receive a precommit for some round infinitely in the future
|
// Else, there's a DoS where we receive a precommit for some round infinitely in the future
|
||||||
@@ -395,9 +398,13 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
|||||||
if !self.validators.verify(sender, &commit_msg(end_time.canonical(), id.as_ref()), sig) {
|
if !self.validators.verify(sender, &commit_msg(end_time.canonical(), id.as_ref()), sig) {
|
||||||
Err(TendermintError::Malicious(sender))?;
|
Err(TendermintError::Malicious(sender))?;
|
||||||
}
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
Ok(())
|
false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn message(
|
async fn message(
|
||||||
@@ -456,7 +463,21 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
|||||||
let round_msgs = self.block.log.log[&msg.round].clone();
|
let round_msgs = self.block.log.log[&msg.round].clone();
|
||||||
for (validator, msgs) in &round_msgs {
|
for (validator, msgs) in &round_msgs {
|
||||||
if let Some(data) = msgs.get(&Step::Precommit) {
|
if let Some(data) = msgs.get(&Step::Precommit) {
|
||||||
if self.verify_precommit_signature(*validator, msg.round, data).is_err() {
|
if let Ok(res) = self.verify_precommit_signature(*validator, msg.round, data) {
|
||||||
|
// Ensure this actually verified the signature instead of believing it shouldn't yet
|
||||||
|
debug_assert!(res);
|
||||||
|
} else {
|
||||||
|
// Remove the message so it isn't counted towards forming a commit/included in one
|
||||||
|
// This won't remove the fact the precommitted for this block hash in the MessageLog
|
||||||
|
self
|
||||||
|
.block
|
||||||
|
.log
|
||||||
|
.log
|
||||||
|
.get_mut(&msg.round)
|
||||||
|
.unwrap()
|
||||||
|
.get_mut(validator)
|
||||||
|
.unwrap()
|
||||||
|
.remove(&Step::Precommit);
|
||||||
self.slash(*validator).await;
|
self.slash(*validator).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user