Skip to main content

fedimint_ln_server/
db.rs

1use fedimint_core::encoding::{Decodable, Encodable};
2use fedimint_core::module::ModuleConsensusVersion;
3use fedimint_core::secp256k1::PublicKey;
4use fedimint_core::{Amount, OutPoint, PeerId, impl_db_lookup, impl_db_record};
5use fedimint_ln_common::contracts::incoming::IncomingContractOffer;
6use fedimint_ln_common::contracts::{
7    ContractId, FundedContract, IdentifiableContract, PreimageDecryptionShare,
8};
9use serde::Serialize;
10use strum_macros::EnumIter;
11
12use crate::{ContractAccount, LightningGatewayRegistration, LightningOutputOutcomeV0};
13
14#[repr(u8)]
15#[derive(Clone, EnumIter, Debug)]
16pub enum DbKeyPrefix {
17    Contract = 0x40,
18    Offer = 0x41,
19    ProposeDecryptionShare = 0x42,
20    AgreedDecryptionShare = 0x43,
21    ContractUpdate = 0x44,
22    LightningGateway = 0x45,
23    BlockCountVote = 0x46,
24    EncryptedPreimageIndex = 0x47,
25    LightningAuditItem = 0x48,
26    ConsensusVersionVote = 0x49,
27}
28
29impl std::fmt::Display for DbKeyPrefix {
30    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
31        write!(f, "{self:?}")
32    }
33}
34
35#[derive(Debug, Clone, Copy, Encodable, Decodable, Serialize)]
36pub struct ContractKey(pub ContractId);
37
38#[derive(Debug, Clone, Copy, Encodable, Decodable)]
39pub struct ContractKeyPrefix;
40
41impl_db_record!(
42    key = ContractKey,
43    value = ContractAccount,
44    db_prefix = DbKeyPrefix::Contract,
45    notify_on_modify = true,
46);
47impl_db_lookup!(key = ContractKey, query_prefix = ContractKeyPrefix);
48
49#[derive(Debug, Encodable, Decodable, Serialize)]
50pub struct ContractUpdateKey(pub OutPoint);
51
52#[derive(Debug, Clone, Copy, Encodable, Decodable)]
53pub struct ContractUpdateKeyPrefix;
54
55impl_db_record!(
56    key = ContractUpdateKey,
57    value = LightningOutputOutcomeV0,
58    db_prefix = DbKeyPrefix::ContractUpdate,
59);
60impl_db_lookup!(
61    key = ContractUpdateKey,
62    query_prefix = ContractUpdateKeyPrefix
63);
64
65/// We keep a separate mapping of incoming and outgoing `ContractId`s to
66/// `Amount`s, which allows us to quickly audit the total liabilities in the
67/// Lightning module.
68///
69/// This differs from `MintAuditItemKey`s, since it doesn't include an aggregate
70/// *Total key. The motivation for not including the aggregate key is how the
71/// Amount associated to the contract mutates in the LN module. When a contract
72/// reaches a terminal state, the associated amount updates to 0. The additional
73/// complexity to update both the individual incoming/outgoing contract audit
74/// keys along with the aggregate audit key is not necessary.
75///
76/// In contrast to the mint module, the total number of LN audit keys with a
77/// non-zero amount will not grow linearly, so querying the LN audit keys with a
78/// non-zero amount should remain quick.
79#[derive(Debug, Clone, Encodable, Decodable, Serialize, PartialEq)]
80pub enum LightningAuditItemKey {
81    Incoming(ContractId),
82    Outgoing(ContractId),
83}
84
85impl LightningAuditItemKey {
86    pub fn from_funded_contract(contract: &FundedContract) -> Self {
87        match contract {
88            FundedContract::Outgoing(outgoing) => {
89                LightningAuditItemKey::Outgoing(outgoing.contract_id())
90            }
91            FundedContract::Incoming(incoming) => {
92                LightningAuditItemKey::Incoming(incoming.contract.contract_id())
93            }
94        }
95    }
96}
97
98#[derive(Debug, Encodable, Decodable)]
99pub struct LightningAuditItemKeyPrefix;
100
101impl_db_record!(
102    key = LightningAuditItemKey,
103    value = Amount,
104    db_prefix = DbKeyPrefix::LightningAuditItem,
105);
106impl_db_lookup!(
107    key = LightningAuditItemKey,
108    query_prefix = LightningAuditItemKeyPrefix
109);
110
111/// We save the hash of the encrypted preimage from each accepted offer so that
112/// we can make sure that no preimage is used twice.
113#[derive(Debug, Encodable, Decodable, Serialize)]
114pub struct EncryptedPreimageIndexKey(pub bitcoin_hashes::sha256::Hash);
115
116#[derive(Debug, Encodable, Decodable, Serialize)]
117pub struct EncryptedPreimageIndexKeyPrefix;
118
119impl_db_record!(
120    key = EncryptedPreimageIndexKey,
121    value = (),
122    db_prefix = DbKeyPrefix::EncryptedPreimageIndex,
123);
124impl_db_lookup!(
125    key = EncryptedPreimageIndexKey,
126    query_prefix = EncryptedPreimageIndexKeyPrefix
127);
128
129#[derive(Debug, Encodable, Decodable, Serialize)]
130pub struct OfferKey(pub bitcoin_hashes::sha256::Hash);
131
132#[derive(Debug, Encodable, Decodable)]
133pub struct OfferKeyPrefix;
134
135impl_db_record!(
136    key = OfferKey,
137    value = IncomingContractOffer,
138    db_prefix = DbKeyPrefix::Offer,
139    notify_on_modify = true,
140);
141impl_db_lookup!(key = OfferKey, query_prefix = OfferKeyPrefix);
142
143// TODO: remove redundancy
144#[derive(Debug, Encodable, Decodable, Serialize)]
145pub struct ProposeDecryptionShareKey(pub ContractId);
146
147/// Our preimage decryption shares that still need to be broadcasted
148#[derive(Debug, Encodable)]
149pub struct ProposeDecryptionShareKeyPrefix;
150
151impl_db_record!(
152    key = ProposeDecryptionShareKey,
153    value = PreimageDecryptionShare,
154    db_prefix = DbKeyPrefix::ProposeDecryptionShare,
155);
156impl_db_lookup!(
157    key = ProposeDecryptionShareKey,
158    query_prefix = ProposeDecryptionShareKeyPrefix
159);
160
161/// Preimage decryption shares we received
162#[derive(Debug, Encodable, Decodable, Serialize)]
163pub struct AgreedDecryptionShareKey(pub ContractId, pub PeerId);
164
165/// Preimage decryption shares we received
166#[derive(Debug, Encodable)]
167pub struct AgreedDecryptionShareKeyPrefix;
168
169#[derive(Debug, Encodable)]
170pub struct AgreedDecryptionShareContractIdPrefix(pub ContractId);
171
172impl_db_record!(
173    key = AgreedDecryptionShareKey,
174    value = PreimageDecryptionShare,
175    db_prefix = DbKeyPrefix::AgreedDecryptionShare,
176);
177impl_db_lookup!(
178    key = AgreedDecryptionShareKey,
179    query_prefix = AgreedDecryptionShareKeyPrefix,
180    query_prefix = AgreedDecryptionShareContractIdPrefix
181);
182
183#[derive(Debug, Encodable, Decodable, Serialize)]
184pub struct LightningGatewayKey(pub PublicKey);
185
186#[derive(Debug, Encodable, Decodable)]
187pub struct LightningGatewayKeyPrefix;
188
189impl_db_record!(
190    key = LightningGatewayKey,
191    value = LightningGatewayRegistration,
192    db_prefix = DbKeyPrefix::LightningGateway,
193);
194impl_db_lookup!(
195    key = LightningGatewayKey,
196    query_prefix = LightningGatewayKeyPrefix
197);
198
199#[derive(Debug, Encodable, Decodable, Serialize)]
200pub struct BlockCountVoteKey(pub PeerId);
201
202#[derive(Clone, Debug, Encodable, Decodable)]
203pub struct BlockCountVotePrefix;
204
205impl_db_record!(
206    key = BlockCountVoteKey,
207    value = u64,
208    db_prefix = DbKeyPrefix::BlockCountVote
209);
210
211impl_db_lookup!(key = BlockCountVoteKey, query_prefix = BlockCountVotePrefix);
212
213#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
214pub struct ConsensusVersionVoteKey(pub PeerId);
215
216#[derive(Clone, Debug, Encodable, Decodable)]
217pub struct ConsensusVersionVotePrefix;
218
219impl_db_record!(
220    key = ConsensusVersionVoteKey,
221    value = ModuleConsensusVersion,
222    db_prefix = DbKeyPrefix::ConsensusVersionVote
223);
224
225impl_db_lookup!(
226    key = ConsensusVersionVoteKey,
227    query_prefix = ConsensusVersionVotePrefix
228);