cfxcore/sync/message/
new_block_hashes.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::sync::{
6    message::{Context, Handleable},
7    Error,
8};
9use cfx_types::H256;
10use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
11
12#[derive(Debug, PartialEq)]
13pub struct NewBlockHashes {
14    pub block_hashes: Vec<H256>,
15}
16
17impl Encodable for NewBlockHashes {
18    fn rlp_append(&self, s: &mut RlpStream) {
19        s.append_list(&self.block_hashes);
20    }
21}
22
23impl Decodable for NewBlockHashes {
24    fn decode(d: &Rlp) -> Result<Self, DecoderError> {
25        let block_hashes = d.as_list()?;
26        Ok(NewBlockHashes { block_hashes })
27    }
28}
29
30impl Handleable for NewBlockHashes {
31    fn handle(self, ctx: &Context) -> Result<(), Error> {
32        debug!("on_new_block_hashes, msg={:?}", self);
33
34        if ctx.manager.catch_up_mode() {
35            // If a node is in catch-up mode and we are not in test-mode, we
36            // just simple ignore new block hashes.
37            if ctx.manager.protocol_config.test_mode {
38                if let Ok(info) = ctx.manager.syn.get_peer_info(&ctx.node_id) {
39                    let mut info = info.write();
40                    self.block_hashes.iter().for_each(|h| {
41                        info.latest_block_hashes.insert(*h);
42                    });
43                }
44            }
45            return Ok(());
46        }
47
48        let headers_to_request = self
49            .block_hashes
50            .iter()
51            .filter(|hash| {
52                ctx.manager
53                    .graph
54                    .data_man
55                    .block_header_by_hash(&hash)
56                    .is_none()
57            })
58            .cloned()
59            .collect::<Vec<_>>();
60
61        ctx.manager.request_block_headers(
62            ctx.io,
63            Some(ctx.node_id.clone()),
64            headers_to_request,
65            // We have already checked db that these headers do not exist.
66            true, /* ignore_db */
67        );
68
69        Ok(())
70    }
71}