cfxcore/sync/message/
get_block_hashes_response.rs

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