fedimint_wallet_client/
client_db.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
use core::fmt;
use std::ops;
use std::time::SystemTime;

use fedimint_client::module::init::recovery::RecoveryFromHistoryCommon;
use fedimint_core::core::OperationId;
use fedimint_core::encoding::{Decodable, Encodable};
use fedimint_core::{impl_db_lookup, impl_db_record, TransactionId};
use serde::{Deserialize, Serialize};
use strum_macros::EnumIter;

use crate::backup::WalletRecoveryState;

#[derive(Clone, EnumIter, Debug)]
pub enum DbKeyPrefix {
    NextPegInTweakIndex = 0x2c,
    PegInTweakIndex = 0x2d,
    ClaimedPegIn = 0x2e,
    RecoveryFinalized = 0x2f,
    RecoveryState = 0x30,
    /// Prefixes between 0xb0..=0xcf shall all be considered allocated for
    /// historical and future external use
    ExternalReservedStart = 0xb0,
    /// Prefixes between 0xd0..=0xff shall all be considered allocated for
    /// historical and future internal use
    CoreInternalReservedStart = 0xd0,
    /// Prefixes between 0xd0..=0xff shall all be considered allocated for
    /// historical and future internal use
    CoreInternalReservedEnd = 0xff,
}

impl std::fmt::Display for DbKeyPrefix {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{self:?}")
    }
}

/// An index of a deposit address
///
/// Under the hood it's similar to `ChildId`, but in a wallet module
/// it's used often enough to deserve own newtype.
#[derive(
    Copy,
    Clone,
    Debug,
    Encodable,
    Decodable,
    Serialize,
    Deserialize,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
)]
pub struct TweakIdx(pub u64);

impl fmt::Display for TweakIdx {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("TweakIdx({})", self.0))
    }
}

impl TweakIdx {
    #[must_use]
    pub fn next(self) -> Self {
        Self(self.0 + 1)
    }

    #[must_use]
    pub fn prev(self) -> Option<Self> {
        self.0.checked_sub(1).map(Self)
    }

    #[must_use]
    pub fn advance(self, i: u64) -> Self {
        Self(self.0 + i)
    }

    pub fn saturating_sub(&self, rhs: TweakIdx) -> u64 {
        self.0.saturating_sub(rhs.0)
    }
}

impl ops::Sub for TweakIdx {
    type Output = u64;

    fn sub(self, rhs: Self) -> Self::Output {
        self.0 - rhs.0
    }
}

/// A counter tracking next index to use to derive a peg-in address
#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct NextPegInTweakIndexKey;

impl_db_record!(
    key = NextPegInTweakIndexKey,
    value = TweakIdx,
    db_prefix = DbKeyPrefix::NextPegInTweakIndex,
);

/// Peg in index that was already allocated and is being tracked for deposits to
/// claim
#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct PegInTweakIndexKey(pub TweakIdx);

#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct PegInTweakIndexPrefix;

#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct PegInTweakIndexData {
    pub operation_id: OperationId,
    pub creation_time: SystemTime,
    pub last_check_time: Option<SystemTime>,
    pub next_check_time: Option<SystemTime>,
    pub claimed: Vec<bitcoin::OutPoint>,
}

impl_db_record!(
    key = PegInTweakIndexKey,
    value = PegInTweakIndexData,
    db_prefix = DbKeyPrefix::PegInTweakIndex,
);

impl_db_lookup!(
    key = PegInTweakIndexKey,
    query_prefix = PegInTweakIndexPrefix
);

#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct ClaimedPegInKey {
    pub peg_in_index: TweakIdx,
    pub btc_out_point: bitcoin::OutPoint,
}

#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct ClaimedPegInPrefix;

#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
pub struct ClaimedPegInData {
    pub claim_txid: TransactionId,
    pub change: Vec<fedimint_core::OutPoint>,
}

impl_db_record!(
    key = ClaimedPegInKey,
    value = ClaimedPegInData,
    db_prefix = DbKeyPrefix::ClaimedPegIn,
    notify_on_modify = true,
);
impl_db_lookup!(key = ClaimedPegInKey, query_prefix = ClaimedPegInPrefix);

#[derive(Debug, Clone, Encodable, Decodable, Serialize)]
pub struct RecoveryFinalizedKey;

#[derive(Debug, Clone, Encodable, Decodable)]
pub struct RecoveryFinalizedKeyPrefix;

impl_db_record!(
    key = RecoveryFinalizedKey,
    value = bool,
    db_prefix = DbKeyPrefix::RecoveryFinalized,
);

#[derive(Debug, Clone, Encodable, Decodable, Serialize)]
pub struct RecoveryStateKey;

#[derive(Debug, Clone, Encodable, Decodable)]
pub struct RestoreStateKeyPrefix;

impl_db_record!(
    key = RecoveryStateKey,
    value = (WalletRecoveryState, RecoveryFromHistoryCommon),
    db_prefix = DbKeyPrefix::RecoveryState,
);