clementine_core/lib.rs
1//! # Clementine 🍊
2//!
3//! Clementine is Citrea's BitVM-based, trust-minimized two-way peg program.
4//! Please refer to the [whitepaper](https://citrea.xyz/clementine_whitepaper.pdf)
5//! to understand the design of Clementine.
6//!
7//! Clementine Core is the backbone of Clementine. As the name suggests, it
8//! provides the core functionalities for Clementine to operate.
9//!
10//! Most of the modules are self-explanatory and documented. Please refer
11//! to the documentation of each module for more information.
12//!
13//! ## Binaries and Using Clementine
14//!
15//! Clementine's architecture is designed so that every actor is a separate
16//! server. They all communicate with each other via gRPC.
17//!
18//! For this reason, Clementine Core provides a single main binary,
19//! `clementine-core`, which acts as a server starter for every actor. There is
20//! also a helper binary, `clementine-core-cli`, which is a command-line
21//! interface for communicating with these servers. It is located in
22//! `bin/cli.rs`.
23//!
24//! The [`crate::cli`] module provides the command-line interface for Clementine.
25//! It is used in every binary.
26//!
27//! The [`crate::config`] module is also essential for Clementine to operate.
28//! It specifies essential variables for the protocol as well as the user's
29//! environment setup.
30//!
31//! ## Utilizing Actors
32//!
33//! The core behavior of Clementine's actors is defined in the respective
34//! modules:
35//!
36//! - [`crate::operator`]
37//! - [`crate::verifier`]
38//! - [`crate::aggregator`]
39//!
40//! For all these modules, the [`crate::actor`] module provides common utilities.
41//!
42//! ### Servers
43//!
44//! An actor is only meaningful if its server is running. For each actor, there
45//! is a server module, which provides the server implementation.
46//!
47//! The main server architecture is defined in the `rpc/clementine.proto` file.
48//! It is compiled to Rust code by the `tonic` library. Server logic for each
49//! actor is defined in the respective server module in the [`crate::rpc`] module.
50//!
51//! ## Building Transactions and Managing Flow with Tasks
52//!
53//! Clementine operates on Bitcoin transactions. The [`crate::builder`] module
54//! provides utilities for building Bitcoin transactions based on the
55//! specification (detailed in the whitepaper). The [`crate::builder`] module
56//! can create a transaction according to the specification with the required
57//! signatures, addresses, and scripts.
58//!
59//! Clementine requires a few background tasks to be running in order to operate
60//! properly. The task interface is defined in the [`crate::task`] module. These
61//! tasks are:
62//!
63//! - The [`crate::bitcoin_syncer`] module syncs Bitcoin blocks and
64//! transactions.
65//! - The [`crate::tx_sender`] module sends transactions to the Bitcoin network
66//! depending on the transaction type.
67//! - The [`crate::states`] module provides state machine implementations for
68//! managing some of the steps in the specification.
69//!
70//! There are other modules that are not tasks, but they are used in the tasks
71//! and are important for the flow of Clementine:
72//!
73//! - The [`crate::header_chain_prover`] module accepts Bitcoin block headers
74//! and prepares proofs for them.
75//!
76//! ### Communicating with the Outside
77//!
78//! Some steps require communicating with external systems:
79//!
80//! - The [`crate::extended_rpc`] module provides a client that talks with
81//! the Bitcoin node.
82//! - The [`crate::citrea`] module provides a client for interacting with Citrea.
83//! - The [`crate::bitvm_client`] module provides a client for BitVM.
84//! - The [`crate::database`] module provides a database interface for
85//! interacting with the PostgreSQL database.
86//!
87//! ## Development Guidelines
88//!
89//! ### Error Handling
90//!
91//! There are rules about error handling in Clementine. Please refer to the
92//! [`crate::errors`] module for more information.
93//!
94//! ### Testing Clementine
95//!
96//! There are a few quirks about testing Clementine. One of the main ones is
97//! that there is no `tests` directory for integration tests. Rather, there is a
98//! [`crate::test`] module, which is compiled only if `test` is enabled by Cargo
99//! (when running `cargo test`). That module provides common utilities for unit
100//! and integration testing, as well as integration tests themselves. This is a
101//! workaround for having common test utilities between unit and integration
102//! tests.
103//!
104//! Please refer to the [`crate::test`] module to check what utilities are
105//! available for testing and how to use them.
106//!
107//! Also, if a new integration test file is added, it should be guarded by the
108//! `#[cfg(feature = "integration-tests")]` attribute. This ensures that the
109//! integration and unit tests can be run separately.
110
111use bitcoin::{OutPoint, Txid};
112use serde::{Deserialize, Serialize};
113
114pub mod actor;
115pub mod aggregator;
116pub mod bitcoin_syncer;
117pub mod bitvm_client;
118pub mod builder;
119pub mod citrea;
120pub mod cli;
121pub mod compatibility;
122pub mod config;
123pub mod constants;
124pub mod database;
125pub mod deposit;
126pub mod encryption;
127pub mod errors;
128pub mod extended_bitcoin_rpc;
129pub mod header_chain_prover;
130pub mod metrics;
131pub mod musig2;
132pub mod operator;
133pub mod rpc;
134pub mod servers;
135pub mod task;
136pub mod utils;
137pub mod verifier;
138
139#[cfg(feature = "automation")]
140pub mod states;
141#[cfg(feature = "automation")]
142pub mod tx_sender;
143
144#[cfg(test)]
145pub mod test;
146
147macro_rules! impl_try_from_vec_u8 {
148 ($name:ident, $size:expr) => {
149 impl TryFrom<Vec<u8>> for $name {
150 type Error = &'static str;
151
152 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
153 if value.len() == $size {
154 Ok($name(value.try_into().unwrap()))
155 } else {
156 Err(concat!("Expected a Vec<u8> of length ", stringify!($size)))
157 }
158 }
159 }
160 };
161}
162
163pub type ConnectorUTXOTree = Vec<Vec<OutPoint>>;
164// pub type HashTree = Vec<Vec<HashType>>;
165// pub type PreimageTree = Vec<Vec<PreimageType>>;
166pub type InscriptionTxs = (OutPoint, Txid);
167
168/// Type alias for EVM address
169#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
170pub struct EVMAddress(#[serde(with = "hex::serde")] pub [u8; 20]);
171
172impl_try_from_vec_u8!(EVMAddress, 20);
173
174#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
175pub struct UTXO {
176 pub outpoint: OutPoint,
177 pub txout: bitcoin::TxOut,
178}
179
180#[derive(Clone, Debug, Copy, Serialize, Deserialize, PartialEq, sqlx::Type)]
181#[sqlx(type_name = "bytea")]
182pub struct ByteArray66(#[serde(with = "hex::serde")] pub [u8; 66]);
183
184impl_try_from_vec_u8!(ByteArray66, 66);
185
186#[derive(Clone, Debug, Copy, Serialize, Deserialize, PartialEq, sqlx::Type)]
187#[sqlx(type_name = "bytea")]
188pub struct ByteArray32(#[serde(with = "hex::serde")] pub [u8; 32]);
189
190impl_try_from_vec_u8!(ByteArray32, 32);
191
192#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, sqlx::Type)]
193#[sqlx(type_name = "bytea")]
194pub struct ByteArray64(#[serde(with = "hex::serde")] pub [u8; 64]);
195
196impl_try_from_vec_u8!(ByteArray64, 64);