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

Commit 6949b8e

Browse files
mxindenandresilva
authored andcommitted
core/finality-grandpa: Minor refactorings (#3825)
* core/finality-grandpa: Improve code comments * core/finality-grandpa: Rename VoteOrPrecommit to PrevoteOrPrecommit According to the Grandpa paper [1]: > A vote is a block hash, together with some metadata such as round number and the type of vote, such as prevote or precommit, all signed with a voter’s private key. To reduce confusion this patch makes the code consistent with the research paper. [1] https://github.com/w3f/consensus/blob/master/pdf/grandpa.pdf * core/finality-grandpa: Add comment for NetworkStream concept * core/finality-grandpa: Improve round_communication doc comment * core/finality-grandpa: Rename PrevoteOrPrecommit to Vote * core/finality-grandpa: Represent NetworkStream state machine as enum * core/finality-grandpa: Improve KeepTopics comment
1 parent fb26c56 commit 6949b8e

File tree

3 files changed

+59
-31
lines changed

3 files changed

+59
-31
lines changed

core/finality-grandpa/primitives/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub type AuthorityWeight = u64;
5252
/// The index of an authority.
5353
pub type AuthorityIndex = u64;
5454

55-
/// The identifier of a GRANDPA set.
55+
/// The monotonic identifier of a GRANDPA set of authorities.
5656
pub type SetId = u64;
5757

5858
/// The round indicator.

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,13 @@ impl<N: Ord> View<N> {
183183

184184
const KEEP_RECENT_ROUNDS: usize = 3;
185185

186-
/// Tracks topics we keep messages for.
186+
/// Tracks gossip topics that we are keeping messages for. We keep topics of:
187+
///
188+
/// - the last `KEEP_RECENT_ROUNDS` complete GRANDPA rounds,
189+
///
190+
/// - the topic for the current and next round,
191+
///
192+
/// - and a global topic for commit and catch-up messages.
187193
struct KeepTopics<B: BlockT> {
188194
current_set: SetId,
189195
rounds: VecDeque<(Round, SetId)>,
@@ -256,7 +262,7 @@ fn neighbor_topics<B: BlockT>(view: &View<NumberFor<B>>) -> Vec<B::Hash> {
256262
#[derive(Debug, Encode, Decode)]
257263
pub(super) enum GossipMessage<Block: BlockT> {
258264
/// Grandpa message with round and set info.
259-
VoteOrPrecommit(VoteOrPrecommitMessage<Block>),
265+
Vote(VoteMessage<Block>),
260266
/// Grandpa commit message with round and set info.
261267
Commit(FullCommitMessage<Block>),
262268
/// A neighbor packet. Not repropagated.
@@ -273,9 +279,9 @@ impl<Block: BlockT> From<NeighborPacket<NumberFor<Block>>> for GossipMessage<Blo
273279
}
274280
}
275281

276-
/// Network level message with topic information.
282+
/// Network level vote message with topic information.
277283
#[derive(Debug, Encode, Decode)]
278-
pub(super) struct VoteOrPrecommitMessage<Block: BlockT> {
284+
pub(super) struct VoteMessage<Block: BlockT> {
279285
/// The round this message is from.
280286
pub(super) round: Round,
281287
/// The voter set ID this message is from.
@@ -612,7 +618,7 @@ impl<Block: BlockT> Inner<Block> {
612618
cost::PAST_REJECTION
613619
}
614620

615-
fn validate_round_message(&self, who: &PeerId, full: &VoteOrPrecommitMessage<Block>)
621+
fn validate_round_message(&self, who: &PeerId, full: &VoteMessage<Block>)
616622
-> Action<Block::Hash>
617623
{
618624
match self.consider_vote(full.round, full.set_id) {
@@ -1003,7 +1009,7 @@ impl<Block: BlockT> GossipValidator<Block> {
10031009

10041010
let action = {
10051011
match GossipMessage::<Block>::decode(&mut data) {
1006-
Ok(GossipMessage::VoteOrPrecommit(ref message))
1012+
Ok(GossipMessage::Vote(ref message))
10071013
=> self.inner.write().validate_round_message(who, message),
10081014
Ok(GossipMessage::Commit(ref message)) => self.inner.write().validate_commit_message(who, message),
10091015
Ok(GossipMessage::Neighbor(update)) => {
@@ -1163,7 +1169,7 @@ impl<Block: BlockT> network_gossip::Validator<Block> for GossipValidator<Block>
11631169
Ok(GossipMessage::Neighbor(_)) => false,
11641170
Ok(GossipMessage::CatchUpRequest(_)) => false,
11651171
Ok(GossipMessage::CatchUp(_)) => false,
1166-
Ok(GossipMessage::VoteOrPrecommit(_)) => false, // should not be the case.
1172+
Ok(GossipMessage::Vote(_)) => false, // should not be the case.
11671173
}
11681174
})
11691175
}
@@ -1478,7 +1484,7 @@ mod tests {
14781484
val.note_round(Round(1), |_, _| {});
14791485

14801486
let inner = val.inner.read();
1481-
let unknown_voter = inner.validate_round_message(&peer, &VoteOrPrecommitMessage {
1487+
let unknown_voter = inner.validate_round_message(&peer, &VoteMessage {
14821488
round: Round(1),
14831489
set_id: SetId(set_id),
14841490
message: SignedMessage::<Block> {
@@ -1491,7 +1497,7 @@ mod tests {
14911497
}
14921498
});
14931499

1494-
let bad_sig = inner.validate_round_message(&peer, &VoteOrPrecommitMessage {
1500+
let bad_sig = inner.validate_round_message(&peer, &VoteMessage {
14951501
round: Round(1),
14961502
set_id: SetId(set_id),
14971503
message: SignedMessage::<Block> {

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

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use crate::{
4848
};
4949
use crate::environment::HasVoted;
5050
use gossip::{
51-
GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteOrPrecommitMessage, GossipValidator
51+
GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteMessage, GossipValidator
5252
};
5353
use fg_primitives::{
5454
AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber,
@@ -148,12 +148,21 @@ impl<B, S, H> Network<B> for Arc<NetworkService<B, S, H>> where
148148
type In = NetworkStream;
149149

150150
fn messages_for(&self, topic: B::Hash) -> Self::In {
151+
// Given that one can only communicate with the Substrate network via the `NetworkService` via message-passing,
152+
// and given that methods on the network consensus gossip are not exposed but only reachable by passing a
153+
// closure into `with_gossip` on the `NetworkService` this function needs to make use of the `NetworkStream`
154+
// construction.
155+
//
156+
// We create a oneshot channel and pass the sender within a closure to the network. At some point in the future
157+
// the network passes the message channel back through the oneshot channel. But the consumer of this function
158+
// expects a stream, not a stream within a oneshot. This complexity is abstracted within `NetworkStream`,
159+
// waiting for the oneshot to resolve and from there on acting like a normal message channel.
151160
let (tx, rx) = oneshot::channel();
152161
self.with_gossip(move |gossip, _| {
153162
let inner_rx = gossip.messages_for(GRANDPA_ENGINE_ID, topic);
154163
let _ = tx.send(inner_rx);
155164
});
156-
NetworkStream { outer: rx, inner: None }
165+
NetworkStream::PollingOneshot(rx)
157166
}
158167

159168
fn register_validator(&self, validator: Arc<dyn network_gossip::Validator<B>>) {
@@ -202,28 +211,40 @@ impl<B, S, H> Network<B> for Arc<NetworkService<B, S, H>> where
202211
}
203212
}
204213

205-
/// A stream used by NetworkBridge in its implementation of Network.
206-
pub struct NetworkStream {
207-
inner: Option<mpsc::UnboundedReceiver<network_gossip::TopicNotification>>,
208-
outer: oneshot::Receiver<mpsc::UnboundedReceiver<network_gossip::TopicNotification>>
214+
/// A stream used by NetworkBridge in its implementation of Network. Given a oneshot that eventually returns a channel
215+
/// which eventually returns messages, instead of:
216+
///
217+
/// 1. polling the oneshot until it returns a message channel
218+
///
219+
/// 2. polling the message channel for messages
220+
///
221+
/// `NetworkStream` combines the two steps into one, requiring a consumer to only poll `NetworkStream` to retrieve
222+
/// messages directly.
223+
pub enum NetworkStream {
224+
PollingOneshot(oneshot::Receiver<mpsc::UnboundedReceiver<network_gossip::TopicNotification>>),
225+
PollingTopicNotifications(mpsc::UnboundedReceiver<network_gossip::TopicNotification>),
209226
}
210227

211228
impl Stream for NetworkStream {
212229
type Item = network_gossip::TopicNotification;
213230
type Error = ();
214231

215232
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
216-
if let Some(ref mut inner) = self.inner {
217-
return inner.poll();
218-
}
219-
match self.outer.poll() {
220-
Ok(futures::Async::Ready(mut inner)) => {
221-
let poll_result = inner.poll();
222-
self.inner = Some(inner);
223-
poll_result
233+
match self {
234+
NetworkStream::PollingOneshot(oneshot) => {
235+
match oneshot.poll() {
236+
Ok(futures::Async::Ready(mut stream)) => {
237+
let poll_result = stream.poll();
238+
*self = NetworkStream::PollingTopicNotifications(stream);
239+
poll_result
240+
},
241+
Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady),
242+
Err(_) => Err(())
243+
}
244+
},
245+
NetworkStream::PollingTopicNotifications(stream) => {
246+
stream.poll()
224247
},
225-
Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady),
226-
Err(_) => Err(())
227248
}
228249
}
229250
}
@@ -275,8 +296,8 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
275296
validator.note_round(Round(round.number), |_, _| {});
276297

277298
for signed in round.votes.iter() {
278-
let message = gossip::GossipMessage::VoteOrPrecommit(
279-
gossip::VoteOrPrecommitMessage::<B> {
299+
let message = gossip::GossipMessage::Vote(
300+
gossip::VoteMessage::<B> {
280301
message: signed.clone(),
281302
round: Round(round.number),
282303
set_id: SetId(set_id),
@@ -341,7 +362,8 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
341362
);
342363
}
343364

344-
/// Get the round messages for a round in the current set ID. These are signature-checked.
365+
/// Get a stream of signature-checked round messages from the network as well as a sink for round messages to the
366+
/// network all within the current set.
345367
pub(crate) fn round_communication(
346368
&self,
347369
round: Round,
@@ -379,7 +401,7 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
379401
})
380402
.and_then(move |msg| {
381403
match msg {
382-
GossipMessage::VoteOrPrecommit(msg) => {
404+
GossipMessage::Vote(msg) => {
383405
// check signature.
384406
if !voters.contains_key(&msg.message.id) {
385407
debug!(target: "afg", "Skipping message from unknown voter {}", msg.message.id);
@@ -707,7 +729,7 @@ impl<Block: BlockT, N: Network<Block>> Sink for OutgoingMessages<Block, N>
707729
id: local_id.clone(),
708730
};
709731

710-
let message = GossipMessage::VoteOrPrecommit(VoteOrPrecommitMessage::<Block> {
732+
let message = GossipMessage::Vote(VoteMessage::<Block> {
711733
message: signed.clone(),
712734
round: Round(self.round),
713735
set_id: SetId(self.set_id),

0 commit comments

Comments
 (0)