fedimint_lnv2_common/
config.rs1use std::collections::BTreeMap;
2
3pub use bitcoin::Network;
4use fedimint_core::core::ModuleKind;
5use fedimint_core::encoding::{Decodable, Encodable};
6use fedimint_core::envs::BitcoinRpcConfig;
7use fedimint_core::{Amount, PeerId, plugin_types_trait_impl_config};
8use group::Curve;
9use serde::{Deserialize, Serialize};
10use tpe::{AggregatePublicKey, PublicKeyShare, SecretKeyShare};
11
12use crate::LightningCommonInit;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct LightningConfig {
16 pub private: LightningConfigPrivate,
17 pub consensus: LightningConfigConsensus,
18}
19
20#[derive(Clone, Debug, Serialize, Deserialize, Decodable, Encodable)]
21pub struct LightningConfigLocal {
22 pub bitcoin_rpc: BitcoinRpcConfig,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, Encodable, Decodable)]
26pub struct LightningConfigConsensus {
27 pub tpe_agg_pk: AggregatePublicKey,
28 pub tpe_pks: BTreeMap<PeerId, PublicKeyShare>,
29 pub fee_consensus: FeeConsensus,
30 pub network: Network,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct LightningConfigPrivate {
35 pub sk: SecretKeyShare,
36}
37
38#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Encodable, Decodable)]
39pub struct LightningClientConfig {
40 pub tpe_agg_pk: AggregatePublicKey,
41 pub tpe_pks: BTreeMap<PeerId, PublicKeyShare>,
42 pub fee_consensus: FeeConsensus,
43 pub network: Network,
44}
45
46impl std::fmt::Display for LightningClientConfig {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(f, "LightningClientConfig {self:?}")
49 }
50}
51
52plugin_types_trait_impl_config!(
54 LightningCommonInit,
55 LightningConfig,
56 LightningConfigPrivate,
57 LightningConfigConsensus,
58 LightningClientConfig
59);
60
61#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Encodable, Decodable)]
62pub struct FeeConsensus {
63 pub base: Amount,
64 pub parts_per_million: u64,
65}
66
67impl FeeConsensus {
68 pub fn new(parts_per_million: u64) -> anyhow::Result<Self> {
79 anyhow::ensure!(
80 parts_per_million <= 1_000,
81 "Relative fee over one thousand parts per million is excessive"
82 );
83
84 Ok(Self {
85 base: Amount::from_sats(1),
86 parts_per_million,
87 })
88 }
89
90 pub fn zero() -> Self {
91 Self {
92 base: Amount::ZERO,
93 parts_per_million: 0,
94 }
95 }
96
97 pub fn fee(&self, amount: Amount) -> Amount {
98 Amount::from_msats(self.fee_msats(amount.msats))
99 }
100
101 fn fee_msats(&self, msats: u64) -> u64 {
102 msats
103 .saturating_mul(self.parts_per_million)
104 .saturating_div(1_000_000)
105 .checked_add(self.base.msats)
106 .expect("The division creates sufficient headroom to add the base fee")
107 }
108}
109
110#[test]
111fn test_fee_consensus() {
112 let fee_consensus = FeeConsensus::new(1_000).expect("Relative fee is within range");
113
114 assert_eq!(
115 fee_consensus.fee(Amount::from_msats(999)),
116 Amount::from_sats(1)
117 );
118
119 assert_eq!(
120 fee_consensus.fee(Amount::from_sats(1)),
121 Amount::from_msats(1) + Amount::from_sats(1)
122 );
123
124 assert_eq!(
125 fee_consensus.fee(Amount::from_sats(1000)),
126 Amount::from_sats(1) + Amount::from_sats(1)
127 );
128
129 assert_eq!(
130 fee_consensus.fee(Amount::from_bitcoins(1)),
131 Amount::from_sats(100_000) + Amount::from_sats(1)
132 );
133
134 assert_eq!(
135 fee_consensus.fee(Amount::from_bitcoins(100_000)),
136 Amount::from_bitcoins(100) + Amount::from_sats(1)
137 );
138}
139
140#[allow(dead_code)]
141fn migrate_config_consensus(
142 config: &fedimint_ln_common::config::LightningConfigConsensus,
143 peer_count: u16,
144) -> LightningConfigConsensus {
145 LightningConfigConsensus {
146 tpe_agg_pk: AggregatePublicKey(config.threshold_pub_keys.public_key().0.to_affine()),
147 tpe_pks: (0..peer_count)
148 .map(|peer| {
149 (
150 PeerId::from(peer),
151 PublicKeyShare(
152 config
153 .threshold_pub_keys
154 .public_key_share(peer as usize)
155 .0
156 .0
157 .to_affine(),
158 ),
159 )
160 })
161 .collect(),
162 fee_consensus: FeeConsensus::new(1000).expect("Relative fee is within range"),
163 network: config.network.0,
164 }
165}
166
167#[allow(dead_code)]
168fn migrate_config_private(
169 config: &fedimint_ln_common::config::LightningConfigPrivate,
170) -> LightningConfigPrivate {
171 LightningConfigPrivate {
172 sk: SecretKeyShare(config.threshold_sec_key.0.0.0),
173 }
174}
175
176#[allow(dead_code)]
177fn migrate_config_local(
178 config: fedimint_ln_common::config::LightningConfigLocal,
179) -> LightningConfigLocal {
180 LightningConfigLocal {
181 bitcoin_rpc: config.bitcoin_rpc,
182 }
183}