From 9db903b3f50183753c1b9802e134d44153949886 Mon Sep 17 00:00:00 2001 From: GuyLewin Date: Sun, 2 Jul 2023 21:25:42 -0400 Subject: [PATCH 1/3] feature: validate term value Signed-off-by: GuyLewin --- src/raft.rs | 6 ++++++ src/storage.rs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/raft.rs b/src/raft.rs index 5af1eca4..02945eb0 100644 --- a/src/raft.rs +++ b/src/raft.rs @@ -380,6 +380,12 @@ impl Raft { if raft_state.hard_state != HardState::default() { r.load_state(&raft_state.hard_state); } + if r.term == 0 { + fatal!( + r.logger, + "Invalid term value: 0" + ); + } if c.applied > 0 { r.commit_apply(c.applied); } diff --git a/src/storage.rs b/src/storage.rs index ae58f566..b40b1966 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -419,6 +419,8 @@ impl MemStorage { // In practice, we choose the second way by assigning non-zero index to first index. Here // we choose the first way for historical reason and easier to write tests. core.raft_state.conf_state = ConfState::from(conf_state); + // Initialize term with a valid value (anything except 0) + core.raft_state.hard_state.term = 1; } /// Opens up a read lock on the storage and returns a guard handle. Use this From 19adcb3266a225b3e949c6052a66dec014100e5c Mon Sep 17 00:00:00 2001 From: GuyLewin Date: Sun, 2 Jul 2023 22:12:27 -0400 Subject: [PATCH 2/3] fix: format Signed-off-by: GuyLewin --- src/raft.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/raft.rs b/src/raft.rs index 02945eb0..17a1bc70 100644 --- a/src/raft.rs +++ b/src/raft.rs @@ -381,10 +381,7 @@ impl Raft { r.load_state(&raft_state.hard_state); } if r.term == 0 { - fatal!( - r.logger, - "Invalid term value: 0" - ); + fatal!(r.logger, "Invalid term value: 0"); } if c.applied > 0 { r.commit_apply(c.applied); From b0a374060334a35442e7da1f3769599de7a040ed Mon Sep 17 00:00:00 2001 From: GuyLewin Date: Mon, 3 Jul 2023 09:22:29 -0400 Subject: [PATCH 3/3] fix: pr comments Signed-off-by: GuyLewin --- src/raft.rs | 2 +- src/tracker.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/raft.rs b/src/raft.rs index 17a1bc70..1c3e79a6 100644 --- a/src/raft.rs +++ b/src/raft.rs @@ -380,7 +380,7 @@ impl Raft { if raft_state.hard_state != HardState::default() { r.load_state(&raft_state.hard_state); } - if r.term == 0 { + if !r.prs.is_empty() && r.term == 0 { fatal!(r.logger, "Invalid term value: 0"); } if c.applied > 0 { diff --git a/src/tracker.rs b/src/tracker.rs index 4814d381..6d22751c 100644 --- a/src/tracker.rs +++ b/src/tracker.rs @@ -240,6 +240,10 @@ impl ProgressTracker { self.votes.clear(); } + pub(crate) fn is_empty(&self) -> bool { + self.progress.is_empty() && self.votes.is_empty() + } + /// Returns true if (and only if) there is only one voting member /// (i.e. the leader) in the current configuration. pub fn is_singleton(&self) -> bool {