fedimint_ln_server/
db.rs

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