cfxcore/sync/message/
get_block_headers.rs1use crate::{
6 message::{Message, RequestId},
7 sync::{
8 message::{
9 Context, GetBlockHeadersResponse, Handleable, Key, KeyContainer,
10 },
11 request_manager::{AsAny, Request},
12 Error, ProtocolConfiguration,
13 },
14};
15use cfx_parameters::sync::MAX_HEADERS_TO_SEND;
16use cfx_types::H256;
17use malloc_size_of_derive::MallocSizeOf as DeriveMallocSizeOf;
18use rlp_derive::{RlpDecodable, RlpEncodable};
19use std::{any::Any, time::Duration};
20
21#[derive(
22 Debug, PartialEq, Clone, RlpDecodable, RlpEncodable, DeriveMallocSizeOf,
23)]
24pub struct GetBlockHeaders {
25 pub request_id: RequestId,
26 pub hashes: Vec<H256>,
27}
28
29impl AsAny for GetBlockHeaders {
30 fn as_any(&self) -> &dyn Any { self }
31
32 fn as_any_mut(&mut self) -> &mut dyn Any { self }
33}
34
35impl Request for GetBlockHeaders {
36 fn timeout(&self, conf: &ProtocolConfiguration) -> Duration {
37 conf.headers_request_timeout
38 }
39
40 fn on_removed(&self, inflight_keys: &KeyContainer) {
41 let mut inflight_keys = inflight_keys.write(self.msg_id());
42 for hash in self.hashes.iter() {
43 inflight_keys.remove(&Key::Hash(*hash));
44 }
45 }
46
47 fn with_inflight(&mut self, inflight_keys: &KeyContainer) {
48 let mut inflight_keys = inflight_keys.write(self.msg_id());
49 self.hashes.retain(|h| inflight_keys.insert(Key::Hash(*h)));
50 }
51
52 fn is_empty(&self) -> bool { self.hashes.is_empty() }
53
54 fn resend(&self) -> Option<Box<dyn Request>> {
55 Some(Box::new(self.clone()))
56 }
57}
58
59impl Handleable for GetBlockHeaders {
60 fn handle(self, ctx: &Context) -> Result<(), Error> {
61 debug!("Received GetBlockHeaders {:?}", self);
62 let headers = self
63 .hashes
64 .iter()
65 .take(MAX_HEADERS_TO_SEND as usize)
66 .filter_map(|hash| {
67 ctx.manager
70 .graph
71 .data_man
72 .block_header_by_hash(&hash)
73 .map(|header_arc| header_arc.as_ref().clone())
74 })
75 .collect();
76
77 let mut block_headers_resp = GetBlockHeadersResponse::default();
78 block_headers_resp.request_id = self.request_id;
79 block_headers_resp.headers = headers;
80
81 debug!(
82 "Returned {:?} block headers to peer {:?}",
83 block_headers_resp.headers.len(),
84 ctx.node_id,
85 );
86
87 ctx.send_response(&block_headers_resp)
88 }
89}