Skip to main content

lexe_common/
constants.rs

1use std::{include_bytes, time::Duration};
2
3use lexe_enclave::enclave::{Measurement, MrShort};
4use lexe_std::{const_assert, const_concat_str};
5
6// --- General --- //
7
8/// If a node release needs to be yanked, add its semver version and measurement
9/// here. See `node::approved_versions` for more info.
10// e.g. "0.1.0", "0.2.1-alpha.1".
11// TODO(max): We could replace these by baking in `releases-archive.json`.
12pub const YANKED_NODE_VERSIONS: [&str; 0] = [];
13pub const YANKED_NODE_MEASUREMENTS: [Measurement; 0] = [];
14lexe_std::const_assert!(
15    YANKED_NODE_VERSIONS.len() == YANKED_NODE_MEASUREMENTS.len()
16);
17
18/// Reject backend requests for payments that are too large.
19pub const MAX_PAYMENTS_BATCH_SIZE: u16 = 100;
20pub const DEFAULT_PAYMENTS_BATCH_SIZE: u16 = 50;
21
22/// Reject payment notes that are too large.
23pub const MAX_PAYMENT_NOTE_BYTES: usize = 512;
24
25/// The amount of time user node tasks have to finish after a graceful shutdown
26/// signal is received before the task is forced to exit.
27pub const USER_NODE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(25);
28
29/// The amount of time user the user runner has to finish after a graceful
30/// shutdown signal is received before the program is forced to exit.
31pub const USER_RUNNER_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(27);
32
33const_assert!(
34    USER_NODE_SHUTDOWN_TIMEOUT.as_secs()
35        < USER_RUNNER_SHUTDOWN_TIMEOUT.as_secs()
36);
37
38/// Computing `max_flow` takes ~30s at 10 iterations and ~50s at 17 iterations.
39/// Set `LayerConfig::handling_timeout` and `reqwest::RequestBuilder::timeout`
40/// to this value to ensure that callers can get a response.
41/// See `compute_max_flow_to_recipient` for more details.
42pub const MAX_FLOW_TIMEOUT: Duration = Duration::from_secs(60);
43
44/// This is both:
45///
46/// - The size of the `ApprovedVersions` window.
47/// - The number of trusted versions that the app will try to keep provisioned.
48///
49/// This strikes a balance between:
50///
51/// 1) having a sufficient number of recent versions approved so that Lexe has
52///    the ability to downgrade users (by yanking versions) if it is discovered
53///    that a node release is broken in some way, and
54/// 2) having so many versions approved that Lexe could downgrade users to an
55///    old version that may contain vulnerabilities.
56pub const RELEASE_WINDOW_SIZE: usize = 3;
57
58// --- Channels and liquidity --- //
59
60/// Our dust limit for e.g. our channel close txo's. If our channel balance,
61/// after paying close fees, is <= this value, we will not get a txo and this
62/// value is lost (goes to fees).
63///
64/// LDK just uses a fixed value here.
65///
66/// See: [`MIN_CHAN_DUST_LIMIT_SATOSHIS`](https://github.com/lightningdevkit/rust-lightning/blob/70add1448b5c36368b8f1c17d672d8871cee14de/lightning/src/ln/channel.rs#L697)
67pub const LDK_DUST_LIMIT_SATS: u32 = 354;
68
69/// The amount of liquidity (in sats) that Lexe supplies to us for free, which
70/// we are not expected to pay interest on. This is also the amount of liquidity
71/// Lexe's LSP will supply to a user in their first JIT zeroconf channel open.
72// 50k sats = 0.0005 BTC = $25 at $50k/BTC or $50 at $100k/BTC
73pub const FREE_LIQUIDITY_SAT: u32 = 50_000;
74
75/// The maximum amount of liquidity that Lexe will supply to a user in one tx.
76pub const MAX_LIQUIDITY_SAT: u32 = 10_000_000; // 0.1 BTC
77
78/// User nodes and the LSP will reject new inbound channels with total channel
79/// value larger than this value in satoshis.
80pub const CHANNEL_MAX_FUNDING_SATS: u32 = 5 * 1_0000_0000; // 5 BTC
81
82/// User nodes require the LSP to reserve this proportion of the channel value
83/// (in millionths) as potential punishment. LDK clamps the actual reserve
84/// amount to at least 1000 sats. Since the LSP can't send this amount to the
85/// user, the user's inbound liquidity is also reduced by this amount. Used for:
86/// [`lightning::util::config::ChannelHandshakeConfig::their_channel_reserve_proportional_millionths`]
87pub const LSP_RESERVE_PROP_PPM: u32 = 10_000; // 1%
88
89/// The LSP will only accept new inbound channels with channel value at or above
90/// this limit in satoshis.
91// 0.00005000 BTC = $2.50 at $50k/BTC or $5 at $100k/BTC
92pub const LSP_USERNODE_CHANNEL_MIN_FUNDING_SATS: u32 = 5_000;
93
94/// See: [`lightning::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis`]
95//
96// 1,000 sats = $1.00 assuming $100k/BTC
97pub const FORCE_CLOSE_AVOIDANCE_MAX_FEE_SATS: u64 = 1_000;
98
99// --- Persistence --- //
100
101/// The default number of persist retries for important objects.
102pub const IMPORTANT_PERSIST_RETRIES: usize = 5;
103
104// --- Networking --- //
105
106/// Fake DNS names used by the reverse proxy to route requests to user nodes.
107/// Provision mode uses "{mr_short}.provision.lexe.app" and run mode uses
108/// "run.lexe.app". These DNS names don't actually resolve.
109pub const NODE_RUN_DNS: &str = "run.lexe.app";
110pub const NODE_RUN_URL: &str = const_concat_str!("https://", NODE_RUN_DNS);
111pub fn node_provision_dns(mr_short: &MrShort) -> String {
112    format!("{mr_short}{NODE_PROVISION_DNS_SUFFIX}")
113}
114pub const NODE_PROVISION_DNS_SUFFIX: &str = ".provision.lexe.app";
115
116// --- Esplora --- //
117// Quickly test these by appending /fee-estimates and opening in browser,
118// e.g. "https://testnet.ltbl.io/api/fee-estimates"
119
120pub const MAINNET_LEXE_MEMPOOL_ESPLORA: &str = "https://lexe.mempool.space/api";
121// Introduced in node-v0.6.8, lsp-v0.6.28
122pub const MAINNET_LEXE_BLOCKSTREAM_ESPLORA: &str =
123    "https://ipwl.blockstream.info/api";
124pub const MAINNET_PUBLIC_BLOCKSTREAM_ESPLORA: &str =
125    "https://blockstream.info/api";
126pub const MAINNET_ESPLORA_WHITELIST: [&str; 3] = [
127    MAINNET_LEXE_MEMPOOL_ESPLORA,
128    MAINNET_LEXE_BLOCKSTREAM_ESPLORA,
129    MAINNET_PUBLIC_BLOCKSTREAM_ESPLORA,
130];
131
132// Introduced in node-v0.7.12
133pub const TESTNET3_LEXE_MEMPOOL_ESPLORA: &str =
134    "https://lexe.mempool.space/testnet/api";
135// Introduced in node-v0.6.8, lsp-v0.6.28
136// NOTE: our ipwl doesn't currently work for testnet3
137pub const TESTNET3_LEXE_BLOCKSTREAM_ESPLORA: &str =
138    "https://ipwl.blockstream.info/testnet/api";
139pub const TESTNET3_PUBLIC_BLOCKSTREAM_ESPLORA: &str =
140    "https://blockstream.info/testnet/api";
141pub const TESTNET3_LTBL_ESPLORA: &str = "https://testnet.ltbl.io/api";
142pub const TESTNET3_LEXE_ESPLORA: &str = "https://esplora.staging.lexe.app/api";
143pub const TESTNET3_ESPLORA_WHITELIST: [&str; 5] = [
144    TESTNET3_LEXE_BLOCKSTREAM_ESPLORA,
145    TESTNET3_PUBLIC_BLOCKSTREAM_ESPLORA,
146    TESTNET3_LEXE_ESPLORA,
147    TESTNET3_LEXE_MEMPOOL_ESPLORA,
148    TESTNET3_LTBL_ESPLORA,
149];
150
151// --- Root CA certs --- //
152//
153// This section contains DER-encoded TLS certs for the root CAs used by various
154// websites that we make requests to, including Lexe itself. For security, we
155// only allow using reqwest with `rustls-tls-manual-roots`, which trusts 0 roots
156// by default. Thus, it is necessary to manually include a root CA cert in our
157// TLS config whenever we make a request to Lexe or an external site. For
158// extra security, once a `reqwest::Client` has been configured to trust a CA
159// root, it should not be reused for requests to sites with different roots.
160//
161// ### Instructions for adding or updating an external root cert
162// (written for Brave / Chrome)
163//
164// - Visit the website in your browser via HTTPS.
165// - Click the HTTPS lock icon and view certificate details.
166// - Navigate up the certificate chain until you have selected the root cert.
167// - Press "Export..."
168// - When prompted for the format, use "DER-encoded binary, single certificate".
169// - Save it to "lexe-common/data/<root_ca_name>_root-ca-cert.der"
170// - Add a `include_bytes!()` entry below with a corresponding test.
171// - Tip: You can see the full human-readable cert info with macOS Quick Look.
172//
173// ### Inspecting a DER-encoded certificate
174//
175// macOS Finder's "Quick Look" works for some certificates.
176// Alternatively, view the cert from the command line:
177//
178// ```bash
179// openssl x509 -inform der -in <certificate-name>.der -text -noout
180// ```
181
182/// The Lexe CA responsible for `lexe.app` and `.lx`.
183// Serial Number : 73:bb:2d:b0:13:58:d7:1c:ca:a5:d3:56:a7:f3:33:5b:4c:3c:60:8e
184//    Not Before : Nov 27 21:44:46 2024 GMT
185//     Not After : Dec  4 21:44:46 2034 GMT
186pub const LEXE_PROD_CA_CERT_DER: &[u8] =
187    include_bytes!("../data/lexe-prod-root-ca-cert.der");
188
189/// The Lexe CA responsible for `staging.lexe.app` and `staging.lx`.
190// Serial Number : 30:ef:fb:a0:ba:ca:82:0b:7f:49:9a:46:b7:8d:05:18:23:91:62:17
191//    Not Before : Jul 30 02:15:24 2024 GMT
192//     Not After : Aug  6 02:15:24 2034 GMT
193pub const LEXE_STAGING_CA_CERT_DER: &[u8] =
194    include_bytes!("../data/lexe-staging-root-ca-cert.der");
195
196/// The Lexe dummy CA used in local testing and development.
197// Serial Number : 37:80:43:1e:b3:5c:74:e0:c4:1a:3d:45:2a:be:d0:bb:83:14:f3:6a
198//    Not Before : Jan  1 00:00:00 1975 GMT
199//     Not After : Jan  1 00:00:00 4096 GMT
200pub const LEXE_DUMMY_CA_CERT_DER: &[u8] =
201    include_bytes!("../data/lexe-dummy-root-ca-cert.der");
202
203/// Google Trust Services Root R1 (RSA), used by `googleapis.com` and
204/// `dns.google`.
205// `curl https://i.pki.goog/r1.crt -o lexe-common/data/google-trust-services-root-r1-ca-cert.der`
206// Serial Number : 02:03:E5:93:6F:31:B0:13:49:88:6B:A2:17
207//    Not Before : Jun 22 00:00:00 2016 GMT
208//     Not After : Jun 22 00:00:00 2036 GMT
209pub const GTS_ROOT_R1_CA_CERT_DER: &[u8] =
210    include_bytes!("../data/google-trust-services-root-r1-ca-cert.der");
211
212/// Google Trust Services Root R2 (RSA), used by `googleapis.com` and
213/// `dns.google`.
214// `curl https://i.pki.goog/r2.crt -o lexe-common/data/google-trust-services-root-r2-ca-cert.der`
215// Serial Number : 02:03:E5:AE:C5:8D:04:25:1A:AB:11:25:AA
216//    Not Before : Jun 22 00:00:00 2016 GMT
217//    Not After  : Jun 22 00:00:00 2036 GMT
218pub const GTS_ROOT_R2_CA_CERT_DER: &[u8] =
219    include_bytes!("../data/google-trust-services-root-r2-ca-cert.der");
220
221/// Google Trust Services Root R3 (ECDSA), used by `googleapis.com` and
222/// `dns.google`.
223// `curl https://i.pki.goog/r3.crt -o lexe-common/data/google-trust-services-root-r3-ca-cert.der`
224// Serial Number : 02:03:E5:B8:82:EB:20:F8:25:27:6D:3D:66
225//    Not Before : Jun 22 00:00:00 2016 GMT
226//    Not After  : Jun 22 00:00:00 2036 GMT
227pub const GTS_ROOT_R3_CA_CERT_DER: &[u8] =
228    include_bytes!("../data/google-trust-services-root-r3-ca-cert.der");
229
230/// Google Trust Services Root R4 (ECDSA), used by `googleapis.com` and
231/// `dns.google`.
232// `curl https://i.pki.goog/r4.crt -o lexe-common/data/google-trust-services-root-r4-ca-cert.der`
233// Serial Number : 02:03:E5:C0:68:EF:63:1A:9C:72:90:50:52
234//    Not Before : Jun 22 00:00:00 2016 GMT
235//    Not After  : Jun 22 00:00:00 2036 GMT
236pub const GTS_ROOT_R4_CA_CERT_DER: &[u8] =
237    include_bytes!("../data/google-trust-services-root-r4-ca-cert.der");
238
239/// GlobalSign Root R4 (ECDSA), used by `googleapis.com` and `dns.google`.
240// `curl https://i.pki.goog/gsr4.crt -o lexe-common/data/globalsign-root-r4-ca-cert.der`
241// Serial Number : 02:03:E5:7E:F5:3F:93:FD:A5:09:21:B2:A6
242//    Not Before : Nov 13 00:00:00 2012 GMT
243//    Not After  : Jan 19 03:14:07 2038 GMT
244pub const GS_ROOT_R4_CA_CERT_DER: &[u8] =
245    include_bytes!("../data/globalsign-root-r4-ca-cert.der");
246
247#[cfg(test)]
248mod test {
249    use asn1_rs::FromDer;
250    use x509_parser::prelude::X509Certificate;
251
252    use super::*;
253
254    #[test]
255    fn test_parse_ca_certs() {
256        X509Certificate::from_der(LEXE_PROD_CA_CERT_DER).unwrap();
257        X509Certificate::from_der(LEXE_STAGING_CA_CERT_DER).unwrap();
258        X509Certificate::from_der(GTS_ROOT_R1_CA_CERT_DER).unwrap();
259        X509Certificate::from_der(GTS_ROOT_R2_CA_CERT_DER).unwrap();
260        X509Certificate::from_der(GTS_ROOT_R3_CA_CERT_DER).unwrap();
261        X509Certificate::from_der(GTS_ROOT_R4_CA_CERT_DER).unwrap();
262    }
263}