Support running TendermintMachine when not a validator

This supports validators who leave the current set, without crashing 
their nodes, along with nodes trying to become validators (who will now 
seamlessly transition in).
This commit is contained in:
Luke Parker 2022-11-11 06:04:37 -05:00
parent dbcddb2fb0
commit 43b43bdbd9
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
4 changed files with 20 additions and 22 deletions
substrate/tendermint
client/src
machine

View file

@ -123,17 +123,14 @@ impl<T: TendermintClient> Signer for TendermintSigner<T> {
type ValidatorId = u16;
type Signature = Signature;
async fn validator_id(&self) -> u16 {
async fn validator_id(&self) -> Option<u16> {
let key = self.get_public_key().await;
for (i, k) in (*self.1 .0).read().unwrap().lookup.iter().enumerate() {
if k == &key {
return u16::try_from(i).unwrap();
return Some(u16::try_from(i).unwrap());
}
}
// TODO: Enable switching between being a validator and not being one, likely be returning
// Option<u16> here. Non-validators should be able to simply not broadcast when they think
// they have messages.
panic!("not a validator");
None
}
async fn sign(&self, msg: &[u8]) -> Signature {

View file

@ -41,8 +41,8 @@ pub trait Signer: Send + Sync {
/// Signature type.
type Signature: Signature;
/// Returns the validator's current ID.
async fn validator_id(&self) -> Self::ValidatorId;
/// Returns the validator's current ID. Returns None if they aren't a current validator.
async fn validator_id(&self) -> Option<Self::ValidatorId>;
/// Sign a signature with the current validator's private key.
async fn sign(&self, msg: &[u8]) -> Self::Signature;
}
@ -52,7 +52,7 @@ impl<S: Signer> Signer for Arc<S> {
type ValidatorId = S::ValidatorId;
type Signature = S::Signature;
async fn validator_id(&self) -> Self::ValidatorId {
async fn validator_id(&self) -> Option<Self::ValidatorId> {
self.as_ref().validator_id().await
}

View file

@ -107,7 +107,7 @@ pub struct TendermintMachine<N: Network> {
validators: N::SignatureScheme,
weights: Arc<N::Weights>,
validator_id: N::ValidatorId,
validator_id: Option<N::ValidatorId>,
number: BlockNumber,
canonical_start_time: u64,
@ -179,20 +179,21 @@ impl<N: Network + 'static> TendermintMachine<N> {
&mut self,
data: Data<N::Block, <N::SignatureScheme as SignatureScheme>::Signature>,
) {
let step = data.step();
// 27, 33, 41, 46, 60, 64
self.step = step;
self.queue.push_back(Message {
sender: self.validator_id,
number: self.number,
round: self.round,
data,
});
if let Some(validator_id) = &self.validator_id {
// 27, 33, 41, 46, 60, 64
self.step = data.step();
self.queue.push_back(Message {
sender: *validator_id,
number: self.number,
round: self.round,
data,
});
}
}
// 14-21
fn round_propose(&mut self) -> bool {
if self.weights.proposer(self.number, self.round) == self.validator_id {
if Some(self.weights.proposer(self.number, self.round)) == self.validator_id {
let (round, block) = self
.valid
.clone()

View file

@ -21,8 +21,8 @@ impl Signer for TestSigner {
type ValidatorId = TestValidatorId;
type Signature = [u8; 32];
async fn validator_id(&self) -> TestValidatorId {
self.0
async fn validator_id(&self) -> Option<TestValidatorId> {
Some(self.0)
}
async fn sign(&self, msg: &[u8]) -> [u8; 32] {