Skip to content

Commit

Permalink
round change fix and prepare consensus recording
Browse files Browse the repository at this point in the history
  • Loading branch information
Zacholme7 committed Jan 22, 2025
1 parent d7ddc24 commit 86d0591
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 43 deletions.
58 changes: 24 additions & 34 deletions anchor/common/qbft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ mod msg_container;
mod qbft_types;
mod validation;

struct ConsensusRecord {
round: Round,
hash: Hash256,
prepare_messages: Vec<WrappedQbftMessage>,
}

#[cfg(test)]
mod tests;

Expand Down Expand Up @@ -81,7 +75,7 @@ where
last_prepared_value: Option<D::Hash>,

/// Past prepare consensus that we have reached
past_consensus: HashMap<Round, ConsensusRecord>,
past_consensus: HashMap<Round, D::Hash>,

// Network sender
send_message: S,
Expand Down Expand Up @@ -234,18 +228,14 @@ where
let prepared_round = Round::from(highest_msg.qbft_message.data_round);

// Verify we have also seen this consensus
if let Some(our_record) = self.past_consensus.get(&prepared_round) {
if let Some(hash) = self.past_consensus.get(&prepared_round) {
// We have seen consensus on the data, get the value
let our_data = self
.data
.get(&our_record.hash)
.expect("Data must exist")
.clone();
let our_data = self.data.get(hash).expect("Data must exist").clone();

// Verify the data matches what we saw
if prepared_data == our_data {
// We agree with the prepared data - use it
return Some((our_record.hash, our_data));
return Some((*hash, our_data));
}
}
}
Expand Down Expand Up @@ -408,21 +398,14 @@ where
// Move the state forward since we have a prepare quorum
self.state = InstanceState::Commit;

// Record this prepare consensus. Fetch all of the preapre messages for the data and then
// record the consensus for them
let prepare_messages: Vec<WrappedQbftMessage> = self
.prepare_container
.get_messages_for_value(round, hash)
.into_iter()
.cloned()
.collect();

let record = ConsensusRecord {
round,
hash,
prepare_messages,
};
self.past_consensus.insert(round, record);
// Record this prepare consensus
// todo!() may need to record all of the prepare messages for the hash and save that
// too, used for justifications
self.past_consensus.insert(round, hash);

// Record as last prepared value and round
self.last_prepared_value = Some(hash);
self.last_prepared_round = Some(self.current_round);

// Send a commit message for the prepare quorum data
self.send_commit(hash);
Expand Down Expand Up @@ -499,6 +482,7 @@ where
round = *round,
"Round change quorum reached"
);

self.set_round(round);
} else {
let num_messages_for_round =
Expand All @@ -520,16 +504,20 @@ where
self.completed = Some(Completed::TimedOut);
return;
};

if next_round.get() > self.config.max_rounds() {
self.state = InstanceState::Complete;
self.completed = Some(Completed::TimedOut);
return;
}

// Get the data to send with the round change?
self.send_round_change(self.start_data_hash);
// Start a new round
self.set_round(next_round);
self.current_round.set(next_round);
// Check if we have a prepared value, if so we want to send a round change proposing the
// value. Else, send a blank hash
let hash = self.last_prepared_value.unwrap_or_default();
self.send_round_change(hash);
self.start_round();
}

// Construct a new unsigned message. This will be passed to the processor to be signed and then
Expand All @@ -546,7 +534,9 @@ where
round: self.current_round.get() as u64,
identifier: self.identifier.clone(),
root: data_hash as Hash256,
data_round: self.current_round.get() as u64,
data_round: self
.last_prepared_round
.map_or(0, |round| round.get() as u64),
round_change_justification: vec![], // Empty for MVP
prepare_justification: vec![], // Empty for MVP
};
Expand All @@ -560,7 +550,7 @@ where
// Wrap in unsigned SSV message
UnsignedSSVMessage {
ssv_message,
full_data: self.data.get(&data_hash).unwrap().clone(),
full_data: self.data.get(&data_hash).unwrap_or(&Vec::new()).clone(),
}
}

Expand Down
8 changes: 0 additions & 8 deletions anchor/common/qbft/src/msg_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,4 @@ impl<M: Clone + Data<Hash = Hash256>> MessageContainer<M> {
})
.unwrap_or_default()
}

/// Get all of the messages for the round and hash
pub fn get_messages_for_value(&self, round: Round, value: Hash256) -> Vec<&M> {
self.messages
.get(&round)
.map(|msgs| msgs.values().filter(|msg| msg.hash() == value).collect())
.unwrap_or_default()
}
}
3 changes: 2 additions & 1 deletion anchor/validator_store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ impl<T: SlotClock, E: EthSpec> AnchorValidatorStore<T, E> {
BeaconBlock::Capella(_) => DATA_VERSION_CAPELLA,
BeaconBlock::Deneb(_) => DATA_VERSION_DENEB,
BeaconBlock::Electra(_) => DATA_VERSION_UNKNOWN,
BeaconBlock::Fulu(_) => DATA_VERSION_UNKNOWN, // todo! fulu is now upstream
},
data_ssz: wrapped_block.as_ssz_bytes(),
},
Expand Down Expand Up @@ -741,7 +742,7 @@ impl<T: SlotClock, E: EthSpec> ValidatorStore for AnchorValidatorStore<T, E> {
.await
.map_err(SpecificError::from)?;
// todo SSZ deser
let _data = match completed {
let data = match completed {
Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)),
Completed::Success(data) => data,
};
Expand Down

0 comments on commit 86d0591

Please sign in to comment.