Skip to main content

fiber_types/
network.rs

1//! Network state types.
2//!
3//! Contains the persistent network actor state that is stored in the node's database.
4
5use crate::Pubkey;
6use ckb_types::packed::OutPoint;
7use serde::{Deserialize, Serialize};
8use serde_with::serde_as;
9use std::collections::{hash_map::Entry, HashMap};
10use tentacle_multiaddr::Multiaddr;
11
12/// A hop requirement to meet when building a router. Does not include the source node;
13/// the last hop is the target node.
14#[serde_as]
15#[derive(Clone, Debug, Serialize, Deserialize)]
16pub struct HopRequire {
17    /// The public key of the node
18    pub pubkey: Pubkey,
19    /// The outpoint for the channel, which means use channel with `channel_outpoint` to reach this node
20    #[serde_as(as = "Option<crate::EntityHex>")]
21    pub channel_outpoint: Option<OutPoint>,
22}
23
24/// The persistent state of the network actor.
25#[derive(Default, Clone, Serialize, Deserialize)]
26pub struct PersistentNetworkActorState {
27    // These addresses are saved by the user (e.g. the user sends a ConnectPeer rpc to the node),
28    // we will then save these addresses to the peer store.
29    saved_peer_addresses: HashMap<Pubkey, Vec<Multiaddr>>,
30}
31
32impl PersistentNetworkActorState {
33    pub fn new() -> Self {
34        Default::default()
35    }
36
37    pub fn get_peer_addresses(&self, pubkey: &Pubkey) -> Vec<Multiaddr> {
38        self.saved_peer_addresses
39            .get(pubkey)
40            .cloned()
41            .unwrap_or_default()
42    }
43
44    /// Save a single peer address to the peer store. If this address for the peer does not exist,
45    /// then return false, otherwise return true.
46    pub fn save_peer_address(&mut self, pubkey: Pubkey, addr: Multiaddr) -> bool {
47        match self.saved_peer_addresses.entry(pubkey) {
48            Entry::Occupied(mut entry) => {
49                if entry.get().contains(&addr) {
50                    false
51                } else {
52                    entry.get_mut().push(addr);
53                    true
54                }
55            }
56            Entry::Vacant(entry) => {
57                entry.insert(vec![addr]);
58                true
59            }
60        }
61    }
62
63    pub fn num_of_saved_nodes(&self) -> usize {
64        self.saved_peer_addresses.len()
65    }
66
67    pub fn sample_n_peers_to_connect(&self, n: usize) -> HashMap<Pubkey, Vec<Multiaddr>> {
68        // TODO: we may need to shuffle the nodes before selecting the first n nodes,
69        // to avoid some malicious nodes from being always selected.
70        self.saved_peer_addresses
71            .iter()
72            .take(n)
73            .map(|(k, v)| (*k, v.clone()))
74            .collect()
75    }
76}