Skip to content

Commit 8578ac3

Browse files
committed
f BDK: Account for persistence changes 1: add serialization logic
1 parent 920877a commit 8578ac3

File tree

2 files changed

+297
-0
lines changed

2 files changed

+297
-0
lines changed

src/wallet/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ use std::ops::{Deref, DerefMut};
4545
use std::sync::{Arc, Mutex};
4646
use std::time::Duration;
4747

48+
pub(crate) mod ser;
49+
4850
enum WalletSyncStatus {
4951
Completed,
5052
InProgress { subscribers: tokio::sync::broadcast::Sender<Result<(), Error>> },

src/wallet/ser.rs

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
// This file is Copyright its original authors, visible in version control history.
2+
//
3+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5+
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
6+
// accordance with one or both of these licenses.
7+
8+
use lightning::ln::msgs::DecodeError;
9+
use lightning::util::ser::{BigSize, FixedLengthReader, Readable, Writeable, Writer};
10+
11+
use bdk_chain::bdk_core::{BlockId, ConfirmationBlockTime};
12+
use bdk_chain::indexer::keychain_txout::ChangeSet as BdkIndexerChangeSet;
13+
use bdk_chain::local_chain::ChangeSet as BdkLocalChainChangeSet;
14+
use bdk_chain::tx_graph::ChangeSet as BdkTxGraphChangeSet;
15+
use bdk_chain::DescriptorId;
16+
17+
use bdk_wallet::descriptor::Descriptor;
18+
use bdk_wallet::keys::DescriptorPublicKey;
19+
20+
use bitcoin::hashes::sha256::Hash as Sha256Hash;
21+
use bitcoin::p2p::Magic;
22+
use bitcoin::{Network, Transaction, Txid};
23+
24+
use std::collections::{BTreeMap, BTreeSet};
25+
use std::str::FromStr;
26+
use std::sync::Arc;
27+
28+
pub(crate) struct ChangeSetSerWrapper<'a, T>(pub &'a T);
29+
pub(crate) struct ChangeSetDeserWrapper<T>(pub T);
30+
31+
impl<'a> Writeable for ChangeSetSerWrapper<'a, Descriptor<DescriptorPublicKey>> {
32+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
33+
self.0.to_string().write(writer)
34+
}
35+
}
36+
37+
impl Readable for ChangeSetDeserWrapper<Descriptor<DescriptorPublicKey>> {
38+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
39+
let descriptor_str: String = Readable::read(reader)?;
40+
let descriptor = Descriptor::<DescriptorPublicKey>::from_str(&descriptor_str)
41+
.map_err(|_| DecodeError::InvalidValue)?;
42+
Ok(Self(descriptor))
43+
}
44+
}
45+
46+
impl<'a> Writeable for ChangeSetSerWrapper<'a, Network> {
47+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
48+
self.0.magic().to_bytes().write(writer)
49+
}
50+
}
51+
52+
impl Readable for ChangeSetDeserWrapper<Network> {
53+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
54+
let buf: [u8; 4] = Readable::read(reader)?;
55+
let magic = Magic::from_bytes(buf);
56+
let network = Network::from_magic(magic).ok_or(DecodeError::InvalidValue)?;
57+
Ok(Self(network))
58+
}
59+
}
60+
61+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BdkLocalChainChangeSet> {
62+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
63+
// We serialize a length header to make sure we can accommodate future changes to the
64+
// BDK types..
65+
let total_len = BigSize(self.0.blocks.serialized_length() as u64);
66+
total_len.write(writer)?;
67+
68+
self.0.blocks.write(writer)
69+
}
70+
}
71+
72+
impl Readable for ChangeSetDeserWrapper<BdkLocalChainChangeSet> {
73+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
74+
let total_len: BigSize = Readable::read(reader)?;
75+
let mut fixed_reader = FixedLengthReader::new(reader, total_len.0);
76+
let blocks = Readable::read(&mut fixed_reader)?;
77+
Ok(Self(BdkLocalChainChangeSet { blocks }))
78+
}
79+
}
80+
81+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BdkTxGraphChangeSet<ConfirmationBlockTime>> {
82+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
83+
// We serialize a length header to make sure we can accommodate future changes to the
84+
// BDK types..
85+
let txs_len = ChangeSetSerWrapper(&self.0.txs).serialized_length() as u64;
86+
let txouts_len = self.0.txouts.serialized_length() as u64;
87+
let anchors_len = ChangeSetSerWrapper(&self.0.anchors).serialized_length() as u64;
88+
let last_seen_len = self.0.last_seen.serialized_length() as u64;
89+
let total_len = BigSize(txs_len + txouts_len + anchors_len + last_seen_len);
90+
total_len.write(writer)?;
91+
92+
ChangeSetSerWrapper(&self.0.txs).write(writer)?;
93+
self.0.txouts.write(writer)?;
94+
ChangeSetSerWrapper(&self.0.anchors).write(writer)?;
95+
self.0.last_seen.write(writer)?;
96+
Ok(())
97+
}
98+
}
99+
100+
impl Readable for ChangeSetDeserWrapper<BdkTxGraphChangeSet<ConfirmationBlockTime>> {
101+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
102+
let total_len: BigSize = Readable::read(reader)?;
103+
let mut fixed_reader = FixedLengthReader::new(reader, total_len.0);
104+
105+
let txs: ChangeSetDeserWrapper<BTreeSet<Arc<Transaction>>> =
106+
Readable::read(&mut fixed_reader)?;
107+
let txouts = Readable::read(&mut fixed_reader)?;
108+
let anchors: ChangeSetDeserWrapper<BTreeSet<(ConfirmationBlockTime, Txid)>> =
109+
Readable::read(&mut fixed_reader)?;
110+
let last_seen = Readable::read(&mut fixed_reader)?;
111+
Ok(Self(BdkTxGraphChangeSet { txs: txs.0, txouts, anchors: anchors.0, last_seen }))
112+
}
113+
}
114+
115+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BTreeSet<(ConfirmationBlockTime, Txid)>> {
116+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
117+
let len = BigSize(self.0.len() as u64);
118+
len.write(writer)?;
119+
for (time, txid) in self.0.iter() {
120+
ChangeSetSerWrapper(time).write(writer)?;
121+
txid.write(writer)?;
122+
}
123+
Ok(())
124+
}
125+
}
126+
127+
impl Readable for ChangeSetDeserWrapper<BTreeSet<(ConfirmationBlockTime, Txid)>> {
128+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
129+
let len: BigSize = Readable::read(reader)?;
130+
let mut set = BTreeSet::new();
131+
for _ in 0..len.0 {
132+
let time: ChangeSetDeserWrapper<ConfirmationBlockTime> = Readable::read(reader)?;
133+
let txid = Readable::read(reader)?;
134+
set.insert((time.0, txid));
135+
}
136+
Ok(Self(set))
137+
}
138+
}
139+
140+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BTreeSet<Arc<Transaction>>> {
141+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
142+
let len = BigSize(self.0.len() as u64);
143+
len.write(writer)?;
144+
for tx in self.0.iter() {
145+
tx.write(writer)?;
146+
}
147+
Ok(())
148+
}
149+
}
150+
151+
impl Readable for ChangeSetDeserWrapper<BTreeSet<Arc<Transaction>>> {
152+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
153+
let len: BigSize = Readable::read(reader)?;
154+
let mut set = BTreeSet::new();
155+
for _ in 0..len.0 {
156+
let tx = Arc::new(Readable::read(reader)?);
157+
set.insert(tx);
158+
}
159+
Ok(Self(set))
160+
}
161+
}
162+
163+
impl<'a> Writeable for ChangeSetSerWrapper<'a, ConfirmationBlockTime> {
164+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
165+
// We serialize a length header to make sure we can accommodate future changes to the
166+
// BDK types..
167+
let block_id_len = ChangeSetSerWrapper(&self.0.block_id).serialized_length() as u64;
168+
let confirmation_time_len = self.0.confirmation_time.serialized_length() as u64;
169+
let total_len = BigSize(block_id_len + confirmation_time_len);
170+
total_len.write(writer)?;
171+
172+
ChangeSetSerWrapper(&self.0.block_id).write(writer)?;
173+
self.0.confirmation_time.write(writer)
174+
}
175+
}
176+
177+
impl Readable for ChangeSetDeserWrapper<ConfirmationBlockTime> {
178+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
179+
let total_len: BigSize = Readable::read(reader)?;
180+
let mut fixed_reader = FixedLengthReader::new(reader, total_len.0);
181+
182+
let block_id: ChangeSetDeserWrapper<BlockId> = Readable::read(&mut fixed_reader)?;
183+
let confirmation_time = Readable::read(&mut fixed_reader)?;
184+
185+
Ok(Self(ConfirmationBlockTime { block_id: block_id.0, confirmation_time }))
186+
}
187+
}
188+
189+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BlockId> {
190+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
191+
// We serialize a length header to make sure we can accommodate future changes to the
192+
// BDK types..
193+
let height_len = self.0.height.serialized_length() as u64;
194+
let hash_len = self.0.hash.serialized_length() as u64;
195+
let total_len = BigSize(height_len + hash_len);
196+
total_len.write(writer)?;
197+
198+
self.0.height.write(writer)?;
199+
self.0.hash.write(writer)
200+
}
201+
}
202+
203+
impl Readable for ChangeSetDeserWrapper<BlockId> {
204+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
205+
let total_len: BigSize = Readable::read(reader)?;
206+
let mut fixed_reader = FixedLengthReader::new(reader, total_len.0);
207+
let height = Readable::read(&mut fixed_reader)?;
208+
let hash = Readable::read(&mut fixed_reader)?;
209+
Ok(Self(BlockId { height, hash }))
210+
}
211+
}
212+
213+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BdkIndexerChangeSet> {
214+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
215+
// We serialize a length header to make sure we can accommodate future changes to the
216+
// BDK types..
217+
let last_revealed_len =
218+
ChangeSetSerWrapper(&self.0.last_revealed).serialized_length() as u64;
219+
let total_len = BigSize(last_revealed_len);
220+
total_len.write(writer)?;
221+
222+
ChangeSetSerWrapper(&self.0.last_revealed).write(writer)
223+
}
224+
}
225+
226+
impl Readable for ChangeSetDeserWrapper<BdkIndexerChangeSet> {
227+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
228+
let total_len: BigSize = Readable::read(reader)?;
229+
let mut fixed_reader = FixedLengthReader::new(reader, total_len.0);
230+
let last_revealed: ChangeSetDeserWrapper<BTreeMap<DescriptorId, u32>> =
231+
Readable::read(&mut fixed_reader)?;
232+
Ok(Self(BdkIndexerChangeSet { last_revealed: last_revealed.0 }))
233+
}
234+
}
235+
236+
impl<'a> Writeable for ChangeSetSerWrapper<'a, BTreeMap<DescriptorId, u32>> {
237+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
238+
let len = BigSize(self.0.len() as u64);
239+
len.write(writer)?;
240+
for (descriptor_id, last_index) in self.0.iter() {
241+
ChangeSetSerWrapper(descriptor_id).write(writer)?;
242+
last_index.write(writer)?;
243+
}
244+
Ok(())
245+
}
246+
}
247+
248+
impl Readable for ChangeSetDeserWrapper<BTreeMap<DescriptorId, u32>> {
249+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
250+
let len: BigSize = Readable::read(reader)?;
251+
let mut set = BTreeMap::new();
252+
for _ in 0..len.0 {
253+
let descriptor_id: ChangeSetDeserWrapper<DescriptorId> = Readable::read(reader)?;
254+
let last_index = Readable::read(reader)?;
255+
set.insert(descriptor_id.0, last_index);
256+
}
257+
Ok(Self(set))
258+
}
259+
}
260+
261+
impl<'a> Writeable for ChangeSetSerWrapper<'a, DescriptorId> {
262+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
263+
// We serialize a length header to make sure we can accommodate future changes to the
264+
// BDK types..
265+
let hash_len = ChangeSetSerWrapper(&self.0 .0).serialized_length() as u64;
266+
let total_len = BigSize(hash_len);
267+
total_len.write(writer)?;
268+
269+
ChangeSetSerWrapper(&self.0 .0).write(writer)
270+
}
271+
}
272+
273+
impl Readable for ChangeSetDeserWrapper<DescriptorId> {
274+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
275+
let total_len: BigSize = Readable::read(reader)?;
276+
let mut fixed_reader = FixedLengthReader::new(reader, total_len.0);
277+
let hash: ChangeSetDeserWrapper<Sha256Hash> = Readable::read(&mut fixed_reader)?;
278+
Ok(Self(DescriptorId(hash.0)))
279+
}
280+
}
281+
282+
impl<'a> Writeable for ChangeSetSerWrapper<'a, Sha256Hash> {
283+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
284+
writer.write_all(&self.0[..])
285+
}
286+
}
287+
288+
impl Readable for ChangeSetDeserWrapper<Sha256Hash> {
289+
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
290+
use bitcoin::hashes::Hash;
291+
292+
let buf: [u8; 32] = Readable::read(reader)?;
293+
Ok(Self(Sha256Hash::from_slice(&buf[..]).unwrap()))
294+
}
295+
}

0 commit comments

Comments
 (0)