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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
crate::ix!();

pub trait ProcessGetFilters {
    fn process_get_filters(self: Arc<Self>, 
        peer: &mut AmoWriteGuard<Box<dyn NodeInterface>>,
        recv: &mut DataStream);
}

impl ProcessGetFilters for PeerManager {

    /**
      | Handle a filters request.
      | 
      | May disconnect from the peer in the case
      | of a bad request.
      | 
      | -----------
      | @param[in] peer
      | 
      | The peer that we received the request
      | from
      | ----------
      | @param[in] vRecv
      | 
      | The raw message received
      |
      */
    fn process_get_filters(
        self:     Arc<Self>, 
        mut peer: &mut AmoWriteGuard<Box<dyn NodeInterface>>,
        recv:     &mut DataStream)  {

        let mut filter_type_ser: u8  = 0;
        let mut start_height:    u32 = 0;

        let mut stop_hash = u256::default();

        recv.stream_into(&mut filter_type_ser);
        recv.stream_into(&mut start_height);
        recv.stream_into(&mut stop_hash);

        let filter_type = BlockFilterType::from(filter_type_ser);

        let mut stop_index:   Option<Arc<BlockIndex>> = None;
        let mut filter_index: Amo<BlockFilterIndex>   = Amo::<BlockFilterIndex>::none();

        if !self.clone()
            .prepare_block_filter_request(
                peer,
                filter_type,
                start_height,
                &stop_hash,
                MAX_GETCFILTERS_SIZE,
                &mut stop_index,
                &mut filter_index) 
        {
            return;
        }

        let mut filters: Vec<BlockFilter> = vec![];

        if !filter_index.get().lookup_filter_range(
            start_height.try_into().unwrap(), 
            stop_index.clone(), 
            &mut filters) 
        {
            log_print!(
                LogFlags::NET, 
                "Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n", 
                block_filter_type_name(filter_type), 
                start_height, 
                stop_hash.to_string()
            );

            return;
        }

        for filter in filters.iter() {

            let common_version = peer.get_common_version();

            let msg_maker = NetMsgMaker::new(common_version);

            let msg: SerializedNetMsg = msg_maker.make(NetMsgType::CFILTER, &[filter]);

            self.connman.get_mut().push_message(&mut *peer, msg /* move */);
        }
    }
}