Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 734f1c3

Browse files
andresilvaDemi-Marie
authored andcommitted
grandpa: don't expire next round messages (#3845)
* grandpa: don't expire next round messages * grandpa: fix test * grandpa: first round in set is 1 * grandpa: fix test * grandpa: update doc
1 parent d0e68bf commit 734f1c3

File tree

2 files changed

+62
-23
lines changed

2 files changed

+62
-23
lines changed

core/finality-grandpa/src/communication/gossip.rs

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ struct View<N> {
132132
impl<N> Default for View<N> {
133133
fn default() -> Self {
134134
View {
135-
round: Round(0),
135+
round: Round(1),
136136
set_id: SetId(0),
137137
last_commit: None,
138138
}
@@ -144,7 +144,7 @@ impl<N: Ord> View<N> {
144144
fn update_set(&mut self, set_id: SetId) {
145145
if set_id != self.set_id {
146146
self.set_id = set_id;
147-
self.round = Round(0);
147+
self.round = Round(1);
148148
}
149149
}
150150

@@ -194,21 +194,30 @@ impl<B: BlockT> KeepTopics<B> {
194194
fn new() -> Self {
195195
KeepTopics {
196196
current_set: SetId(0),
197-
rounds: VecDeque::with_capacity(KEEP_RECENT_ROUNDS + 1),
197+
rounds: VecDeque::with_capacity(KEEP_RECENT_ROUNDS + 2),
198198
reverse_map: HashMap::new(),
199199
}
200200
}
201201

202202
fn push(&mut self, round: Round, set_id: SetId) {
203203
self.current_set = std::cmp::max(self.current_set, set_id);
204-
self.rounds.push_back((round, set_id));
205204

206-
// the 1 is for the current round.
207-
while self.rounds.len() > KEEP_RECENT_ROUNDS + 1 {
205+
// under normal operation the given round is already tracked (since we
206+
// track one round ahead). if we skip rounds (with a catch up) the given
207+
// round topic might not be tracked yet.
208+
if !self.rounds.contains(&(round, set_id)) {
209+
self.rounds.push_back((round, set_id));
210+
}
211+
212+
// we also accept messages for the next round
213+
self.rounds.push_back((Round(round.0.saturating_add(1)), set_id));
214+
215+
// the 2 is for the current and next round.
216+
while self.rounds.len() > KEEP_RECENT_ROUNDS + 2 {
208217
let _ = self.rounds.pop_front();
209218
}
210219

211-
let mut map = HashMap::with_capacity(KEEP_RECENT_ROUNDS + 2);
220+
let mut map = HashMap::with_capacity(KEEP_RECENT_ROUNDS + 3);
212221
map.insert(super::global_topic::<B>(self.current_set.0), (None, self.current_set));
213222

214223
for &(round, set) in &self.rounds {
@@ -554,7 +563,7 @@ impl<Block: BlockT> Inner<Block> {
554563
{
555564
let local_view = match self.local_view {
556565
ref mut x @ None => x.get_or_insert(View {
557-
round: Round(0),
566+
round: Round(1),
558567
set_id,
559568
last_commit: None,
560569
}),
@@ -566,7 +575,7 @@ impl<Block: BlockT> Inner<Block> {
566575
};
567576

568577
local_view.update_set(set_id);
569-
self.live_topics.push(Round(0), set_id);
578+
self.live_topics.push(Round(1), set_id);
570579
self.authorities = authorities;
571580
}
572581
self.multicast_neighbor_packet()
@@ -1466,11 +1475,11 @@ mod tests {
14661475
let peer = PeerId::random();
14671476

14681477
val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {});
1469-
val.note_round(Round(0), |_, _| {});
1478+
val.note_round(Round(1), |_, _| {});
14701479

14711480
let inner = val.inner.read();
14721481
let unknown_voter = inner.validate_round_message(&peer, &VoteOrPrecommitMessage {
1473-
round: Round(0),
1482+
round: Round(1),
14741483
set_id: SetId(set_id),
14751484
message: SignedMessage::<Block> {
14761485
message: grandpa::Message::Prevote(grandpa::Prevote {
@@ -1483,7 +1492,7 @@ mod tests {
14831492
});
14841493

14851494
let bad_sig = inner.validate_round_message(&peer, &VoteOrPrecommitMessage {
1486-
round: Round(0),
1495+
round: Round(1),
14871496
set_id: SetId(set_id),
14881497
message: SignedMessage::<Block> {
14891498
message: grandpa::Message::Prevote(grandpa::Prevote {
@@ -1512,7 +1521,7 @@ mod tests {
15121521
let peer = PeerId::random();
15131522

15141523
val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {});
1515-
val.note_round(Round(0), |_, _| {});
1524+
val.note_round(Round(1), |_, _| {});
15161525

15171526
let validate_catch_up = || {
15181527
let mut inner = val.inner.write();
@@ -1548,19 +1557,19 @@ mod tests {
15481557

15491558
#[test]
15501559
fn unanswerable_catch_up_requests_discarded() {
1551-
// create voter set state with round 1 completed
1560+
// create voter set state with round 2 completed
15521561
let set_state: SharedVoterSetState<Block> = {
15531562
let mut completed_rounds = voter_set_state().read().completed_rounds();
15541563

15551564
completed_rounds.push(environment::CompletedRound {
1556-
number: 1,
1565+
number: 2,
15571566
state: grandpa::round::State::genesis(Default::default()),
15581567
base: Default::default(),
15591568
votes: Default::default(),
15601569
});
15611570

15621571
let mut current_rounds = environment::CurrentRounds::new();
1563-
current_rounds.insert(2, environment::HasVoted::No);
1572+
current_rounds.insert(3, environment::HasVoted::No);
15641573

15651574
let set_state = environment::VoterSetState::<Block>::Live {
15661575
completed_rounds,
@@ -1581,7 +1590,7 @@ mod tests {
15811590
let peer = PeerId::random();
15821591

15831592
val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {});
1584-
val.note_round(Round(2), |_, _| {});
1593+
val.note_round(Round(3), |_, _| {});
15851594

15861595
// add the peer making the request to the validator,
15871596
// otherwise it is discarded
@@ -1597,24 +1606,24 @@ mod tests {
15971606
&set_state,
15981607
);
15991608

1600-
// we're at round 2, a catch up request for round 10 is out of scope
1609+
// we're at round 3, a catch up request for round 10 is out of scope
16011610
assert!(res.0.is_none());
16021611
assert_eq!(res.1, Action::Discard(cost::OUT_OF_SCOPE_MESSAGE));
16031612

16041613
let res = inner.handle_catch_up_request(
16051614
&peer,
16061615
CatchUpRequestMessage {
16071616
set_id: SetId(set_id),
1608-
round: Round(1),
1617+
round: Round(2),
16091618
},
16101619
&set_state,
16111620
);
16121621

1613-
// a catch up request for round 1 should be answered successfully
1622+
// a catch up request for round 2 should be answered successfully
16141623
match res.0.unwrap() {
16151624
GossipMessage::CatchUp(catch_up) => {
16161625
assert_eq!(catch_up.set_id, SetId(set_id));
1617-
assert_eq!(catch_up.message.round_number, 1);
1626+
assert_eq!(catch_up.message.round_number, 2);
16181627

16191628
assert_eq!(res.1, Action::Discard(cost::CATCH_UP_REPLY));
16201629
},
@@ -1849,4 +1858,34 @@ mod tests {
18491858
_ => panic!("expected catch up message"),
18501859
}
18511860
}
1861+
1862+
#[test]
1863+
fn doesnt_expire_next_round_messages() {
1864+
// NOTE: this is a regression test
1865+
let (val, _) = GossipValidator::<Block>::new(
1866+
config(),
1867+
voter_set_state(),
1868+
true,
1869+
);
1870+
1871+
// the validator starts at set id 1.
1872+
val.note_set(SetId(1), Vec::new(), |_, _| {});
1873+
1874+
// we are at round 10
1875+
val.note_round(Round(9), |_, _| {});
1876+
val.note_round(Round(10), |_, _| {});
1877+
1878+
let mut is_expired = val.message_expired();
1879+
1880+
// we accept messages from rounds 9, 10 and 11
1881+
// therefore neither of those should be considered expired
1882+
for round in &[9, 10, 11] {
1883+
assert!(
1884+
!is_expired(
1885+
crate::communication::round_topic::<Block>(*round, 1),
1886+
&[],
1887+
)
1888+
)
1889+
}
1890+
}
18521891
}

core/finality-grandpa/src/communication/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ fn good_commit_leads_to_relay() {
217217
let public = make_ids(&private[..]);
218218
let voter_set = Arc::new(public.iter().cloned().collect::<VoterSet<AuthorityId>>());
219219

220-
let round = 0;
220+
let round = 1;
221221
let set_id = 1;
222222

223223
let commit = {
@@ -332,7 +332,7 @@ fn bad_commit_leads_to_report() {
332332
let public = make_ids(&private[..]);
333333
let voter_set = Arc::new(public.iter().cloned().collect::<VoterSet<AuthorityId>>());
334334

335-
let round = 0;
335+
let round = 1;
336336
let set_id = 1;
337337

338338
let commit = {

0 commit comments

Comments
 (0)