devimint/vars/
net_overrides.rs1use std::collections::{BTreeMap, BTreeSet};
2use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
3
4use fedimint_core::envs::{FM_GW_IROH_CONNECT_OVERRIDES_ENV, FM_IROH_CONNECT_OVERRIDES_ENV};
5use fedimint_core::{NumPeers, PeerId};
6use iroh_base::NodeAddr;
7use iroh_base::ticket::{NodeTicket, Ticket};
8
9use super::ToEnvVar;
10use crate::federation::{
11 FEDIMINTD_API_PORT_OFFSET, FEDIMINTD_P2P_PORT_OFFSET, PORTS_PER_FEDIMINTD,
12};
13
14#[derive(Debug, Clone)]
15pub struct FedimintIrohEndpoint {
16 node_id: iroh_base::NodeId,
17 secret_key: iroh_base::SecretKey,
18 port: u16,
19}
20
21impl FedimintIrohEndpoint {
22 fn new(port: u16) -> Self {
23 let secret_key = iroh_base::SecretKey::generate(&mut rand::thread_rng());
24
25 Self {
26 node_id: secret_key.public(),
27 secret_key,
28 port,
29 }
30 }
31
32 pub fn secret_key(&self) -> String {
33 self.secret_key.to_string()
34 }
35
36 pub fn port(&self) -> u16 {
37 self.port
38 }
39
40 pub fn node_id(&self) -> iroh_base::NodeId {
41 self.node_id
42 }
43
44 fn to_override(&self) -> String {
45 let node_addr = NodeAddr {
46 node_id: self.node_id,
47 relay_url: None,
48 direct_addresses: BTreeSet::from([SocketAddr::V4(SocketAddrV4::new(
49 Ipv4Addr::LOCALHOST,
50 self.port,
51 ))]),
52 };
53 format!(
54 "{}={},",
55 self.node_id,
56 Ticket::serialize(&NodeTicket::from(node_addr))
57 )
58 }
59}
60
61#[derive(Debug, Clone)]
62pub struct FedimintdPeerOverrides {
63 pub p2p: FedimintIrohEndpoint,
64 pub api: FedimintIrohEndpoint,
65 pub base_port: u16,
66}
67
68impl FedimintdPeerOverrides {
69 fn new(base_port: u16) -> Self {
70 Self {
71 p2p: FedimintIrohEndpoint::new(base_port + FEDIMINTD_P2P_PORT_OFFSET),
72 api: FedimintIrohEndpoint::new(base_port + FEDIMINTD_API_PORT_OFFSET),
73 base_port,
74 }
75 }
76}
77
78#[derive(Debug, Clone)]
79pub struct FederationNetOverrides {
80 pub base_port: u16,
81 pub num_peers: NumPeers,
82 pub peers: BTreeMap<PeerId, FedimintdPeerOverrides>,
83}
84
85impl FederationNetOverrides {
86 pub fn new(base_port: u16, num_peers: NumPeers) -> Self {
87 let peers = num_peers
88 .peer_ids()
89 .map(|peer_id| {
90 (peer_id, {
91 FedimintdPeerOverrides::new(
92 base_port
93 + u16::try_from(peer_id.to_usize()).expect("Can't fail")
94 * PORTS_PER_FEDIMINTD,
95 )
96 })
97 })
98 .collect();
99 Self {
100 base_port,
101 num_peers,
102 peers,
103 }
104 }
105
106 pub fn peer_expect(&self, peer_id: PeerId) -> &FedimintdPeerOverrides {
107 self.peers.get(&peer_id).expect("Wrong peer_id?")
108 }
109}
110
111#[derive(Debug, Clone)]
112pub struct FederationsNetOverrides {
113 federations: Vec<FederationNetOverrides>,
114}
115
116impl FederationsNetOverrides {
117 pub fn new(base_port: u16, num_federations: usize, num_peers: NumPeers) -> Self {
118 Self {
119 federations: (0..num_federations)
120 .map(|fed_i| {
121 FederationNetOverrides::new(
122 base_port + fed_i as u16 * PORTS_PER_FEDIMINTD * num_peers.total() as u16,
123 num_peers,
124 )
125 })
126 .collect(),
127 }
128 }
129
130 pub fn fed_expect(&self, fed_i: usize) -> &FederationNetOverrides {
131 self.federations.get(fed_i).expect("Wrong fed_i")
132 }
133
134 pub fn peer_expect(&self, fed_i: usize, peer_id: PeerId) -> &FedimintdPeerOverrides {
135 self.federations
136 .get(fed_i)
137 .expect("Wrong fed_i")
138 .peers
139 .get(&peer_id)
140 .expect("Wrong peer_id?")
141 }
142}
143
144impl ToEnvVar for FederationsNetOverrides {
145 fn to_env_values(&self, _base_env: &str) -> impl Iterator<Item = (String, String)> {
146 vec![(
147 FM_IROH_CONNECT_OVERRIDES_ENV.to_string(),
148 self.federations
149 .iter()
150 .flat_map(|f| f.peers.values())
151 .map(|peer| format!("{},{}", peer.p2p.to_override(), peer.api.to_override(),))
152 .collect::<Vec<String>>()
153 .join(","),
154 )]
155 .into_iter()
156 }
157}
158
159#[derive(Debug, Clone)]
160pub struct GatewaydNetOverrides {
161 pub gateway_iroh_endpoints: Vec<FedimintIrohEndpoint>,
162}
163
164impl GatewaydNetOverrides {
165 pub fn new(base_port: u16, num_gateways: usize) -> Self {
166 Self {
167 gateway_iroh_endpoints: (0..num_gateways)
168 .map(|gw_i| FedimintIrohEndpoint::new(base_port + gw_i as u16))
169 .collect(),
170 }
171 }
172}
173
174impl ToEnvVar for GatewaydNetOverrides {
175 fn to_env_values(&self, _base_env: &str) -> impl Iterator<Item = (String, String)> {
176 vec![(
177 FM_GW_IROH_CONNECT_OVERRIDES_ENV.to_string(),
178 self.gateway_iroh_endpoints
179 .iter()
180 .map(|gw| gw.to_override().to_string())
181 .collect::<Vec<String>>()
182 .join(","),
183 )]
184 .into_iter()
185 }
186}