suins_indexer/
lib.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4pub mod indexer;
5pub mod models;
6pub mod schema;
7
8use dotenvy::dotenv;
9use std::env;
10
11use diesel::{ConnectionError, ConnectionResult};
12use diesel_async::AsyncPgConnection;
13use diesel_async::pooled_connection::AsyncDieselConnectionManager;
14use diesel_async::pooled_connection::ManagerConfig;
15use diesel_async::pooled_connection::bb8::Pool;
16use futures_util::FutureExt;
17use futures_util::future::BoxFuture;
18use std::time::Duration;
19
20pub type PgConnectionPool =
21    diesel_async::pooled_connection::bb8::Pool<diesel_async::AsyncPgConnection>;
22pub type PgPoolConnection<'a> =
23    diesel_async::pooled_connection::bb8::PooledConnection<'a, AsyncPgConnection>;
24
25pub async fn get_connection_pool() -> PgConnectionPool {
26    dotenv().ok();
27
28    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
29
30    let mut config = ManagerConfig::default();
31    config.custom_setup = Box::new(establish_connection);
32
33    let manager = AsyncDieselConnectionManager::<diesel_async::AsyncPgConnection>::new_with_config(
34        database_url,
35        config,
36    );
37
38    Pool::builder()
39        .connection_timeout(Duration::from_secs(30))
40        .build(manager)
41        .await
42        .expect("Could not build Postgres DB connection pool")
43}
44
45fn establish_connection(config: &str) -> BoxFuture<'_, ConnectionResult<AsyncPgConnection>> {
46    let fut = async {
47        // We first set up the way we want rustls to work.
48        let rustls_config = rustls::ClientConfig::builder()
49            .dangerous()
50            .with_custom_certificate_verifier(std::sync::Arc::new(SkipServerCertCheck))
51            .with_no_client_auth();
52        let tls = tokio_postgres_rustls::MakeRustlsConnect::new(rustls_config);
53        let (client, conn) = tokio_postgres::connect(config, tls)
54            .await
55            .map_err(|e| ConnectionError::BadConnection(e.to_string()))?;
56        tokio::spawn(async move {
57            if let Err(e) = conn.await {
58                eprintln!("Database connection: {e}");
59            }
60        });
61        AsyncPgConnection::try_from(client).await
62    };
63    fut.boxed()
64}
65
66fn root_certs() -> rustls::RootCertStore {
67    rustls::RootCertStore {
68        roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(),
69    }
70}
71
72/// Skip performing any verification of a server's cert in order to temporarily match the default
73/// behavior of libpq
74#[derive(Debug)]
75struct SkipServerCertCheck;
76
77impl rustls::client::danger::ServerCertVerifier for SkipServerCertCheck {
78    fn verify_server_cert(
79        &self,
80        _end_entity: &rustls::pki_types::CertificateDer<'_>,
81        _intermediates: &[rustls::pki_types::CertificateDer<'_>],
82        _server_name: &rustls::pki_types::ServerName<'_>,
83        _ocsp_response: &[u8],
84        _now: rustls::pki_types::UnixTime,
85    ) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
86        Ok(rustls::client::danger::ServerCertVerified::assertion())
87    }
88
89    fn verify_tls12_signature(
90        &self,
91        _message: &[u8],
92        _cert: &rustls::pki_types::CertificateDer<'_>,
93        _dss: &rustls::DigitallySignedStruct,
94    ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
95        Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
96    }
97
98    fn verify_tls13_signature(
99        &self,
100        _message: &[u8],
101        _cert: &rustls::pki_types::CertificateDer<'_>,
102        _dss: &rustls::DigitallySignedStruct,
103    ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
104        Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
105    }
106
107    fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
108        rustls::client::WebPkiServerVerifier::builder(std::sync::Arc::new(root_certs()))
109            .build()
110            .unwrap()
111            .supported_verify_schemes()
112    }
113}