cfxcore/sync/message/
get_block_hashes_by_epoch.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::{Message, RequestId},
7    sync::{
8        message::{
9            Context, GetBlockHashesResponse, Handleable, Key, KeyContainer,
10        },
11        request_manager::{AsAny, Request},
12        Error, ProtocolConfiguration,
13    },
14};
15use cfx_parameters::sync::MAX_EPOCHS_TO_SEND;
16use malloc_size_of_derive::MallocSizeOf as DeriveMallocSizeOf;
17use rlp_derive::{RlpDecodable, RlpEncodable};
18use std::{any::Any, time::Duration};
19
20#[derive(
21    Debug, PartialEq, Clone, RlpDecodable, RlpEncodable, DeriveMallocSizeOf,
22)]
23pub struct GetBlockHashesByEpoch {
24    pub request_id: RequestId,
25    pub epochs: Vec<u64>,
26}
27
28impl AsAny for GetBlockHashesByEpoch {
29    fn as_any(&self) -> &dyn Any { self }
30
31    fn as_any_mut(&mut self) -> &mut dyn Any { self }
32}
33
34impl Request for GetBlockHashesByEpoch {
35    fn timeout(&self, conf: &ProtocolConfiguration) -> Duration {
36        conf.headers_request_timeout
37    }
38
39    fn on_removed(&self, inflight_keys: &KeyContainer) {
40        let mut inflight_keys = inflight_keys.write(self.msg_id());
41        for epoch in self.epochs.iter() {
42            inflight_keys.remove(&Key::Num(*epoch));
43        }
44    }
45
46    fn with_inflight(&mut self, inflight_keys: &KeyContainer) {
47        let mut inflight_keys = inflight_keys.write(self.msg_id());
48        self.epochs
49            .retain(|epoch| inflight_keys.insert(Key::Num(*epoch)));
50    }
51
52    fn is_empty(&self) -> bool { self.epochs.is_empty() }
53
54    fn resend(&self) -> Option<Box<dyn Request>> {
55        Some(Box::new(self.clone()))
56    }
57}
58
59impl Handleable for GetBlockHashesByEpoch {
60    fn handle(self, ctx: &Context) -> Result<(), Error> {
61        let hashes = self
62            .epochs
63            .iter()
64            .take(MAX_EPOCHS_TO_SEND as usize)
65            .map(|&e| ctx.manager.graph.get_all_block_hashes_by_epoch(e))
66            .filter_map(Result::ok)
67            .fold(vec![], |mut res, sub| {
68                res.extend(sub);
69                res
70            });
71
72        let response = GetBlockHashesResponse {
73            request_id: self.request_id,
74            hashes,
75        };
76
77        ctx.send_response(&response)
78    }
79}