mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 03:17:56 +00:00
Sync block justifications (#1410)
* core: sync protocol for justifications * core: basic test for justification sync * core: pass block number with justification * grandpa: request justifications when importing change blocks * core: pass finality notifications to chain sync * core: require justifications for pending change blocks on start * core: avoid requesting justifications from previous failed peers * core: timeout block justification requests * core: add some docs * core: fix unused variables warning * core: tick pending justifications fetch periodically * grandpa: add test for syncing justifications * core: early exit dispatch of pending justifications * core: style fix * core: grandpa: change logging level * core: sync: add missing docs * core: network: report peer on bad justification * core: replace mem::replace with Option::take * core: revert authority set changes on failed block finalization * core: grandpa: add docs to import_justification * core: warn on re-finalization of last finalized block * core: only notify sync with last finality notification * core: style fix * core: add docs for PendingJustifications * core: network: use BlockRequest messages for justification requests * core: reference issues in todo comments * core: grandpa: revert authority set changes on db * core: grandpa: remove inconsistent state warning
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::{HashMap, HashSet, BTreeMap};
|
||||
use std::{mem, cmp};
|
||||
use std::cmp;
|
||||
use std::sync::Arc;
|
||||
use std::time;
|
||||
use parking_lot::RwLock;
|
||||
@@ -273,7 +273,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
let mut peers = self.context_data.peers.write();
|
||||
if let Some(ref mut peer) = peers.get_mut(&who) {
|
||||
peer.request_timestamp = None;
|
||||
match mem::replace(&mut peer.block_request, None) {
|
||||
match peer.block_request.take() {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
io.report_peer(who, Severity::Bad("Unexpected response packet received from peer"));
|
||||
@@ -285,10 +285,12 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if request.id != r.id {
|
||||
trace!(target: "sync", "Ignoring mismatched response packet from {} (expected {} got {})", who, request.id, r.id);
|
||||
return;
|
||||
}
|
||||
|
||||
self.on_block_response(io, who, request, r);
|
||||
},
|
||||
GenericMessage::BlockAnnounce(announce) => self.on_block_announce(io, who, announce),
|
||||
@@ -330,7 +332,6 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
pub fn on_peer_disconnected(&self, io: &mut SyncIo, peer: NodeIndex) {
|
||||
trace!(target: "sync", "Disconnecting {}: {}", peer, io.peer_debug_info(peer));
|
||||
|
||||
|
||||
// lock all the the peer lists so that add/remove peer events are in order
|
||||
let mut sync = self.sync.write();
|
||||
let mut spec = self.specialization.write();
|
||||
@@ -351,7 +352,15 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
|
||||
fn on_block_request(&self, io: &mut SyncIo, peer: NodeIndex, request: message::BlockRequest<B>) {
|
||||
trace!(target: "sync", "BlockRequest {} from {}: from {:?} to {:?} max {:?}", request.id, peer, request.from, request.to, request.max);
|
||||
trace!(target: "sync", "BlockRequest {} from {} with fields {:?}: from {:?} to {:?} max {:?}",
|
||||
request.id,
|
||||
peer,
|
||||
request.fields,
|
||||
request.from,
|
||||
request.to,
|
||||
request.max,
|
||||
);
|
||||
|
||||
let mut blocks = Vec::new();
|
||||
let mut id = match request.from {
|
||||
message::FromBlock::Hash(h) => BlockId::Hash(h),
|
||||
@@ -409,25 +418,36 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
trace!(target: "sync", "BlockResponse {} from {} with {} blocks{}",
|
||||
response.id, peer, response.blocks.len(), blocks_range);
|
||||
|
||||
// import_queue.import_blocks also acquires sync.write();
|
||||
// Break the cycle by doing these separately from the outside;
|
||||
let new_blocks = {
|
||||
// TODO [andre]: move this logic to the import queue so that
|
||||
// justifications are imported asynchronously (#1482)
|
||||
if request.fields == message::BlockAttributes::JUSTIFICATION {
|
||||
let mut sync = self.sync.write();
|
||||
sync.on_block_data(&mut ProtocolContext::new(&self.context_data, io), peer, request, response)
|
||||
};
|
||||
sync.on_block_justification_data(
|
||||
&mut ProtocolContext::new(&self.context_data, io),
|
||||
peer,
|
||||
request,
|
||||
response,
|
||||
);
|
||||
} else {
|
||||
// import_queue.import_blocks also acquires sync.write();
|
||||
// Break the cycle by doing these separately from the outside;
|
||||
let new_blocks = {
|
||||
let mut sync = self.sync.write();
|
||||
sync.on_block_data(&mut ProtocolContext::new(&self.context_data, io), peer, request, response)
|
||||
};
|
||||
|
||||
if let Some((origin, new_blocks)) = new_blocks {
|
||||
let import_queue = self.sync.read().import_queue();
|
||||
import_queue.import_blocks(origin, new_blocks);
|
||||
if let Some((origin, new_blocks)) = new_blocks {
|
||||
let import_queue = self.sync.read().import_queue();
|
||||
import_queue.import_blocks(origin, new_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Perform time based maintenance.
|
||||
pub fn tick(&self, io: &mut SyncIo) {
|
||||
self.consensus_gossip.write().collect_garbage(|_| true);
|
||||
self.maintain_peers(io);
|
||||
self.sync.write().tick(&mut ProtocolContext::new(&self.context_data, io));
|
||||
self.on_demand.as_ref().map(|s| s.maintain_peers(io));
|
||||
}
|
||||
|
||||
@@ -439,7 +459,8 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
let handshaking_peers = self.handshaking_peers.read();
|
||||
for (who, timestamp) in peers.iter()
|
||||
.filter_map(|(id, peer)| peer.request_timestamp.as_ref().map(|r| (id, r)))
|
||||
.chain(handshaking_peers.iter()) {
|
||||
.chain(handshaking_peers.iter())
|
||||
{
|
||||
if (tick - *timestamp).as_secs() > REQUEST_TIMEOUT_SEC {
|
||||
trace!(target: "sync", "Timeout {}", who);
|
||||
aborting.push(*who);
|
||||
@@ -648,6 +669,10 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_block_finalized(&self, _io: &mut SyncIo, hash: B::Hash, header: &B::Header) {
|
||||
self.sync.write().block_finalized(&hash, *header.number());
|
||||
}
|
||||
|
||||
fn on_remote_call_request(&self, io: &mut SyncIo, who: NodeIndex, request: message::RemoteCallRequest<B::Hash>) {
|
||||
trace!(target: "sync", "Remote call request {} from {} ({} at {})", request.id, who, request.method, request.block);
|
||||
let proof = match self.context_data.chain.execution_proof(&request.block, &request.method, &request.data) {
|
||||
@@ -752,8 +777,8 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
|
||||
fn send_message<B: BlockT, H: ExHashT>(peers: &RwLock<HashMap<NodeIndex, Peer<B, H>>>, io: &mut SyncIo, who: NodeIndex, mut message: Message<B>) {
|
||||
match &mut message {
|
||||
&mut GenericMessage::BlockRequest(ref mut r) => {
|
||||
match message {
|
||||
GenericMessage::BlockRequest(ref mut r) => {
|
||||
let mut peers = peers.write();
|
||||
if let Some(ref mut peer) = peers.get_mut(&who) {
|
||||
r.id = peer.next_request_id;
|
||||
|
||||
Reference in New Issue
Block a user