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
crate::ix!();

pub trait FindTxForGetData {

    fn find_tx_for_get_data(self: Arc<Self>, 
        peer:        &dyn NodeInterface,
        gtxid:       &GenTxId,
        mempool_req: Option<OffsetDateTime> /* seconds */,
        now:         OffsetDateTime /* seconds */) -> TransactionRef;
}

impl FindTxForGetData for PeerManager {

    /**
      | Determine whether or not a peer can request
      | a transaction, and return it (or nullptr
      | if not found or not allowed).
      |
      */
    #[LOCKS_EXCLUDED(CS_MAIN)]
    fn find_tx_for_get_data(
        self:        Arc<Self>, 
        peer:        &dyn NodeInterface,
        gtxid:       &GenTxId,
        mempool_req: Option<OffsetDateTime>,
        now:         OffsetDateTime) -> TransactionRef {

        let txinfo = self.mempool.get().info(gtxid);

        if txinfo.tx.is_some() {

            // If a TX could have been INVed in
            // reply to a MEMPOOL request, or is
            // older than
            // UNCONDITIONAL_RELAY_DELAY, permit
            // the request unconditionally.
            if (mempool_req.is_some() && txinfo.time <= mempool_req.unwrap()) 
            || txinfo.time <= now - UNCONDITIONAL_RELAY_DELAY {
                return txinfo.tx /* move */;
            }
        }

        {
            let mut guard = CS_MAIN.lock();

            let state = create_state(peer.get_id());

            // Otherwise, the transaction must
            // have been announced recently.
            if state.get().recently_announced_invs.contains_key(gtxid.get_hash().as_slice()) {

                // If it was, it can be relayed
                // from either the mempool...
                if txinfo.tx.is_some() {
                    return txinfo.tx /* move */;
                }

                let inner = self.inner.lock();

                //  ... or the relay pool.
                let mi = inner.map_relay.get(gtxid.get_hash());

                if mi.is_some() {
                    return mi.unwrap().clone();
                }
            }
        }

        TransactionRef::none()
    }
}