1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// Copyright 2019 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/
use crate::{
message::RequestId,
sync::{
message::{Context, GetBlockHashesByEpoch, Handleable},
Error,
},
};
use cfx_types::H256;
use rlp_derive::{RlpDecodable, RlpEncodable};
#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
pub struct GetBlockHashesResponse {
pub request_id: RequestId,
pub hashes: Vec<H256>,
}
impl Handleable for GetBlockHashesResponse {
fn handle(self, ctx: &Context) -> Result<(), Error> {
debug!("on_block_hashes_response, msg={:?}", self);
let req = ctx.match_request(self.request_id)?;
let delay = req.delay;
let epoch_req = req.downcast_ref::<GetBlockHashesByEpoch>(
ctx.io,
&ctx.manager.request_manager,
)?;
// assume received everything
// FIXME: peer should signal error?
let req = epoch_req.epochs.iter().cloned().collect();
let rec = epoch_req.epochs.iter().cloned().collect();
ctx.manager
.request_manager
.epochs_received(ctx.io, req, rec, delay);
// request missing headers
let missing_headers = self
.hashes
.iter()
.filter(|h| !ctx.manager.graph.contains_block_header(&h))
.cloned()
.collect();
// NOTE: this is to make sure no section of the DAG is skipped
// e.g. if the request for epoch 4 is lost or the reply is in-
// correct, the request for epoch 5 should recursively request
// all dependent blocks (see on_block_headers_response)
ctx.manager.request_block_headers(
ctx.io,
Some(ctx.node_id),
missing_headers,
true, /* ignore_db */
);
// TODO: handle empty response
// try requesting some more epochs
ctx.manager.start_sync(ctx.io);
Ok(())
}
}