mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 01:41:03 +00:00
Initial version of the polite-grandpa networking protocol (#2110)
* Consensus status packet * Allow for repropagation after status * More generic gossip * add a basic view struct and gossip module * move gossip stuff to the gossip module * integrate view into gossip * some reshuffling * alter rules for keeping one commit at a time in view * Allow sending addressed messages * don't cast outgoing votes if we know that we voted before * Handle one hop messages * initial run at polite grandpa * build WASM * handle neighbor messages * refactor validator's internals into an Inner struct * gossip only knows to keep or discard messages. optimize should_send_to * Periodic rebroadcast * implement `should_send_to` and message_expired * track peers' best received commit height * Pass peer id to topic steam * kill rebroadcasting network * Notify about existing peers * clean up network APIs a bunch * implement gossip::send_message for direct messages * refactor network trait * implement gossip::send_message for direct messages * get all non set-change tests passing * treat unknown rebroadcasts as broadcasts * get all other main tests passing * remove unimplemented test * everything compiles * treat unknown rebroadcasts as broadcasts * Rebradcast interval * Apply suggestions from code review Style Co-Authored-By: arkpar <arkady.paronyan@gmail.com> * Style * some module docs * address some grumbles + docs * allow rebroadcast every few minutes * send_topic && generic context * some tests for view change * more grumbles & tests * use send_peer
This commit is contained in:
committed by
GitHub
parent
b7eeb28de9
commit
bb95e7d6a2
@@ -20,6 +20,7 @@ use super::*;
|
||||
use network::test::{Block, DummySpecialization, Hash, TestNetFactory, Peer, PeersClient};
|
||||
use network::test::{PassThroughVerifier};
|
||||
use network::config::{ProtocolConfig, Roles};
|
||||
use network::consensus_gossip as network_gossip;
|
||||
use parking_lot::Mutex;
|
||||
use tokio::runtime::current_thread;
|
||||
use keyring::AuthorityKeyring;
|
||||
@@ -33,11 +34,12 @@ use consensus_common::{BlockOrigin, ForkChoiceStrategy, ImportedAux, ImportBlock
|
||||
use consensus_common::import_queue::{SharedBlockImport, SharedJustificationImport};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::result;
|
||||
use runtime_primitives::traits::{ApiRef, ProvideRuntimeApi};
|
||||
use runtime_primitives::traits::{ApiRef, ProvideRuntimeApi, Header as HeaderT};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use substrate_primitives::{NativeOrEncoded, ExecutionContext};
|
||||
|
||||
use authorities::AuthoritySet;
|
||||
use communication::GRANDPA_ENGINE_ID;
|
||||
use consensus_changes::ConsensusChanges;
|
||||
|
||||
type PeerData =
|
||||
@@ -137,102 +139,72 @@ impl TestNetFactory for GrandpaTestNet {
|
||||
struct MessageRouting {
|
||||
inner: Arc<Mutex<GrandpaTestNet>>,
|
||||
peer_id: usize,
|
||||
validator: Arc<GossipValidator<Block>>,
|
||||
}
|
||||
|
||||
impl MessageRouting {
|
||||
fn new(inner: Arc<Mutex<GrandpaTestNet>>, peer_id: usize,) -> Self {
|
||||
let validator = Arc::new(GossipValidator::new());
|
||||
let v = validator.clone();
|
||||
{
|
||||
let inner = inner.lock();
|
||||
let peer = inner.peer(peer_id);
|
||||
peer.with_gossip(move |gossip, _| {
|
||||
gossip.register_validator(GRANDPA_ENGINE_ID, v);
|
||||
});
|
||||
}
|
||||
MessageRouting {
|
||||
inner,
|
||||
peer_id,
|
||||
validator,
|
||||
}
|
||||
}
|
||||
|
||||
fn drop_messages(&self, topic: Hash) {
|
||||
let inner = self.inner.lock();
|
||||
let peer = inner.peer(self.peer_id);
|
||||
peer.consensus_gossip_collect_garbage_for_topic(topic);
|
||||
}
|
||||
}
|
||||
|
||||
fn make_topic(round: u64, set_id: u64) -> Hash {
|
||||
message_topic::<Block>(round, set_id)
|
||||
}
|
||||
|
||||
fn make_commit_topic(set_id: u64) -> Hash {
|
||||
commit_topic::<Block>(set_id)
|
||||
}
|
||||
|
||||
impl Network<Block> for MessageRouting {
|
||||
type In = Box<Stream<Item=Vec<u8>,Error=()> + Send>;
|
||||
type In = Box<Stream<Item=network_gossip::TopicNotification, Error=()> + Send>;
|
||||
|
||||
fn messages_for(&self, round: u64, set_id: u64) -> Self::In {
|
||||
self.validator.note_round(round, set_id);
|
||||
/// Get a stream of messages for a specific gossip topic.
|
||||
fn messages_for(&self, topic: Hash) -> Self::In {
|
||||
let inner = self.inner.lock();
|
||||
let peer = inner.peer(self.peer_id);
|
||||
|
||||
let messages = peer.consensus_gossip_messages_for(
|
||||
GRANDPA_ENGINE_ID,
|
||||
make_topic(round, set_id),
|
||||
topic,
|
||||
);
|
||||
|
||||
let messages = messages.map_err(
|
||||
move |_| panic!("Messages for round {} dropped too early", round)
|
||||
move |_| panic!("Messages for topic {} dropped too early", topic)
|
||||
);
|
||||
|
||||
Box::new(messages)
|
||||
}
|
||||
|
||||
fn send_message(&self, round: u64, set_id: u64, message: Vec<u8>, force: bool) {
|
||||
let inner = self.inner.lock();
|
||||
inner.peer(self.peer_id)
|
||||
.gossip_message(make_topic(round, set_id), GRANDPA_ENGINE_ID, message, force);
|
||||
}
|
||||
|
||||
fn drop_round_messages(&self, round: u64, set_id: u64) {
|
||||
self.validator.drop_round(round, set_id);
|
||||
let topic = make_topic(round, set_id);
|
||||
self.drop_messages(topic);
|
||||
}
|
||||
|
||||
fn drop_set_messages(&self, set_id: u64) {
|
||||
self.validator.drop_set(set_id);
|
||||
let topic = make_commit_topic(set_id);
|
||||
self.drop_messages(topic);
|
||||
}
|
||||
|
||||
fn commit_messages(&self, set_id: u64) -> Self::In {
|
||||
self.validator.note_set(set_id);
|
||||
fn register_validator(&self, v: Arc<dyn network_gossip::Validator<Block>>) {
|
||||
let inner = self.inner.lock();
|
||||
let peer = inner.peer(self.peer_id);
|
||||
let messages = peer.consensus_gossip_messages_for(
|
||||
GRANDPA_ENGINE_ID,
|
||||
make_commit_topic(set_id),
|
||||
);
|
||||
|
||||
let messages = messages.map_err(
|
||||
move |_| panic!("Commit messages for set {} dropped too early", set_id)
|
||||
);
|
||||
|
||||
Box::new(messages)
|
||||
peer.with_gossip(move |gossip, context| {
|
||||
gossip.register_validator(context, GRANDPA_ENGINE_ID, v);
|
||||
});
|
||||
}
|
||||
|
||||
fn send_commit(&self, _round: u64, set_id: u64, message: Vec<u8>, force: bool) {
|
||||
fn gossip_message(&self, topic: Hash, data: Vec<u8>, force: bool) {
|
||||
let inner = self.inner.lock();
|
||||
inner.peer(self.peer_id)
|
||||
.gossip_message(make_commit_topic(set_id), GRANDPA_ENGINE_ID, message, force);
|
||||
inner.peer(self.peer_id).gossip_message(
|
||||
topic,
|
||||
GRANDPA_ENGINE_ID,
|
||||
data,
|
||||
force,
|
||||
);
|
||||
}
|
||||
|
||||
fn announce(&self, _round: u64, _set_id: u64, _block: H256) {
|
||||
fn send_message(&self, who: Vec<network::PeerId>, data: Vec<u8>) {
|
||||
let inner = self.inner.lock();
|
||||
let peer = inner.peer(self.peer_id);
|
||||
|
||||
peer.with_gossip(move |gossip, ctx| for who in &who {
|
||||
gossip.send_message(
|
||||
ctx,
|
||||
who,
|
||||
network_gossip::ConsensusMessage {
|
||||
engine_id: GRANDPA_ENGINE_ID,
|
||||
data: data.clone(),
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn announce(&self, _block: Hash) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user