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