mirror of https://github.com/poanetwork/hbbft.git
Log more DKG-related faults.
This commit is contained in:
parent
b3e858a079
commit
d49350ecd9
|
@ -133,11 +133,17 @@ where
|
|||
|
||||
/// Proposes a contribution in the current epoch.
|
||||
pub fn propose(&mut self, contrib: C) -> Result<Step<C, N>> {
|
||||
let key_gen_messages = self
|
||||
.key_gen_msg_buffer
|
||||
.iter()
|
||||
.filter(|kg_msg| kg_msg.epoch() == self.start_epoch)
|
||||
.cloned()
|
||||
.collect();
|
||||
let step = self
|
||||
.honey_badger
|
||||
.handle_input(InternalContrib {
|
||||
contrib,
|
||||
key_gen_messages: self.key_gen_msg_buffer.clone(),
|
||||
key_gen_messages,
|
||||
votes: self.vote_counter.pending_votes().cloned().collect(),
|
||||
}).map_err(ErrorKind::ProposeHoneyBadger)?;
|
||||
self.process_output(step)
|
||||
|
@ -273,23 +279,26 @@ where
|
|||
self.key_gen_msg_buffer
|
||||
.retain(|skgm| !key_gen_messages.contains(skgm));
|
||||
for SignedKeyGenMsg(epoch, s_id, kg_msg, sig) in key_gen_messages {
|
||||
if epoch < self.start_epoch {
|
||||
info!("Obsolete key generation message: {:?}.", kg_msg);
|
||||
continue;
|
||||
}
|
||||
if !self.verify_signature(&s_id, &sig, &kg_msg)? {
|
||||
if epoch != self.start_epoch {
|
||||
info!(
|
||||
"Obsolete or premature key generation message: {:?}.",
|
||||
kg_msg
|
||||
);
|
||||
let fault_kind = FaultKind::InvalidKeyGenMessageEpoch;
|
||||
step.fault_log.append(id.clone(), fault_kind);
|
||||
} else if !self.verify_signature(&s_id, &sig, &kg_msg)? {
|
||||
info!(
|
||||
"Invalid signature in {:?}'s batch from {:?} for: {:?}.",
|
||||
id, s_id, kg_msg
|
||||
);
|
||||
let fault_kind = FaultKind::InvalidKeyGenMessageSignature;
|
||||
step.fault_log.append(id.clone(), fault_kind);
|
||||
continue;
|
||||
} else {
|
||||
step.extend(match kg_msg {
|
||||
KeyGenMessage::Part(part) => self.handle_part(&s_id, part)?,
|
||||
KeyGenMessage::Ack(ack) => self.handle_ack(&s_id, ack)?.into(),
|
||||
});
|
||||
}
|
||||
step.extend(match kg_msg {
|
||||
KeyGenMessage::Part(part) => self.handle_part(&s_id, part)?,
|
||||
KeyGenMessage::Ack(ack) => self.handle_ack(&s_id, ack)?.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,8 +367,7 @@ where
|
|||
self.start_epoch = epoch;
|
||||
self.key_gen_msg_buffer.retain(|kg_msg| kg_msg.0 >= epoch);
|
||||
let netinfo = Arc::new(self.netinfo.clone());
|
||||
let counter = VoteCounter::new(netinfo.clone(), epoch);
|
||||
mem::replace(&mut self.vote_counter, counter);
|
||||
self.vote_counter = VoteCounter::new(netinfo.clone(), epoch);
|
||||
self.honey_badger = HoneyBadger::builder(netinfo)
|
||||
.max_future_epochs(self.max_future_epochs)
|
||||
.rng(self.rng.sub_rng())
|
||||
|
@ -371,8 +379,9 @@ where
|
|||
let outcome = if let Some(kgs) = self.key_gen_state.as_mut() {
|
||||
kgs.key_gen.handle_part(&mut self.rng, &sender_id, part)
|
||||
} else {
|
||||
// No key generation ongoing. Return early.
|
||||
return Ok(Step::default());
|
||||
// No key generation ongoing.
|
||||
let fault_kind = FaultKind::UnexpectedKeyGenPart;
|
||||
return Ok(Fault::new(sender_id.clone(), fault_kind).into());
|
||||
};
|
||||
|
||||
match outcome {
|
||||
|
@ -387,7 +396,9 @@ where
|
|||
if let Some(kgs) = self.key_gen_state.as_mut() {
|
||||
Ok(kgs.key_gen.handle_ack(sender_id, ack))
|
||||
} else {
|
||||
Ok(FaultLog::new())
|
||||
// No key generation ongoing.
|
||||
let fault_kind = FaultKind::UnexpectedKeyGenAck;
|
||||
return Ok(Fault::new(sender_id.clone(), fault_kind).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -195,3 +195,10 @@ struct InternalContrib<C, N> {
|
|||
/// A signed internal message.
|
||||
#[derive(Eq, PartialEq, Debug, Serialize, Deserialize, Hash, Clone)]
|
||||
struct SignedKeyGenMsg<N>(u64, N, KeyGenMessage, Signature);
|
||||
|
||||
impl<N> SignedKeyGenMsg<N> {
|
||||
/// Returns the start epoch of the ongoing key generation.
|
||||
fn epoch(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,12 +44,17 @@ pub enum FaultKind {
|
|||
/// `HoneyBadger` could not deserialize bytes (i.e. a serialized Batch)
|
||||
/// from a given proposer into a vector of transactions.
|
||||
BatchDeserializationFailed,
|
||||
/// `DynamicHoneyBadger` received a key generation message with an invalid
|
||||
/// signature.
|
||||
/// `DynamicHoneyBadger` received a key generation message with an invalid signature.
|
||||
InvalidKeyGenMessageSignature,
|
||||
/// `DynamicHoneyBadger` received a key generation message with an invalid epoch.
|
||||
InvalidKeyGenMessageEpoch,
|
||||
/// `DynamicHoneyBadger` received a key generation message when there was no key generation in
|
||||
/// progress.
|
||||
UnexpectedKeyGenMessage,
|
||||
/// `DynamicHoneyBadger` received a signed `Ack` when no key generation in progress.
|
||||
UnexpectedKeyGenAck,
|
||||
/// `DynamicHoneyBadger` received a signed `Part` when no key generation in progress.
|
||||
UnexpectedKeyGenPart,
|
||||
/// `DynamicHoneyBadger` received more key generation messages from the candidate than expected.
|
||||
TooManyCandidateKeyGenMessages,
|
||||
/// `DynamicHoneyBadger` received a message (Accept, Propose, or Change)
|
||||
|
@ -59,6 +64,8 @@ pub enum FaultKind {
|
|||
AckMessage(AckMessageFault),
|
||||
/// `DynamicHoneyBadger`/`SyncKeyGen` received an invalid Part message.
|
||||
InvalidPartMessage,
|
||||
/// `DynamicHoneyBadger`/`SyncKeyGen` received multiple Part messages from a node.
|
||||
MultiplePartMessages,
|
||||
/// `DynamicHoneyBadger` received a change vote with an invalid signature.
|
||||
InvalidVoteSignature,
|
||||
/// A validator committed an invalid vote in `DynamicHoneyBadger`.
|
||||
|
|
|
@ -226,7 +226,7 @@ impl Debug for Ack {
|
|||
}
|
||||
|
||||
/// The information needed to track a single proposer's secret sharing process.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct ProposalState {
|
||||
/// The proposer's commitment.
|
||||
commit: BivarCommitment,
|
||||
|
@ -340,11 +340,16 @@ impl<N: NodeIdT> SyncKeyGen<N> {
|
|||
sender_id: &N,
|
||||
Part(commit, rows): Part,
|
||||
) -> Option<PartOutcome<N>> {
|
||||
let sender_idx = self.node_index(sender_id)?;
|
||||
let sender_idx = self.node_index(sender_id)?; // TODO: Return an error.
|
||||
let opt_commit_row = self.our_idx.map(|idx| commit.row(idx + 1));
|
||||
match self.parts.entry(sender_idx) {
|
||||
Entry::Occupied(_) => {
|
||||
debug!("Received multiple parts from node {:?}.", sender_id);
|
||||
Entry::Occupied(entry) => {
|
||||
if *entry.get() != ProposalState::new(commit) {
|
||||
debug!("Received multiple parts from node {:?}.", sender_id);
|
||||
let fault_log =
|
||||
FaultLog::init(sender_id.clone(), FaultKind::MultiplePartMessages);
|
||||
return Some(PartOutcome::Invalid(fault_log));
|
||||
}
|
||||
return None;
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
|
|
Loading…
Reference in New Issue