Skip to content

Commit c898a12

Browse files
committed
f Move into individual sync methods
1 parent 7d465ee commit c898a12

File tree

1 file changed

+128
-115
lines changed

1 file changed

+128
-115
lines changed

src/access.rs

Lines changed: 128 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use bdk::{SignOptions, SyncOptions};
1717
use bitcoin::{BlockHash, Script, Transaction, Txid};
1818

1919
use std::collections::HashSet;
20-
use std::sync::{Arc, Mutex};
20+
use std::sync::{Arc, Mutex, MutexGuard};
2121

2222
/// The minimum feerate we are allowed to send, as specify by LDK.
2323
const MIN_FEERATE: u32 = 253;
@@ -80,143 +80,156 @@ where
8080

8181
let mut locked_last_sync_height = self.last_sync_height.lock().unwrap();
8282
if cur_height >= locked_last_sync_height.unwrap_or(0) {
83-
{
84-
// First, inform the interface of the new block.
85-
let cur_block_header = client.get_header(cur_height)?;
86-
for c in &confirmables {
87-
c.best_block_updated(&cur_block_header, cur_height);
88-
}
83+
self.sync_best_block_updated(confirmables.clone(), cur_height, &mut locked_last_sync_height)?;
84+
self.sync_transactions_confirmed(confirmables.clone())?;
85+
self.sync_transaction_unconfirmed(confirmables.clone())?;
86+
}
87+
// TODO: check whether new outputs have been registered by now and process them
88+
Ok(())
89+
}
8990

90-
*locked_last_sync_height = Some(cur_height);
91-
}
91+
fn sync_best_block_updated(&self, confirmables: Vec<&(dyn Confirm + Sync)>, cur_height: u32, locked_last_sync_height: &mut MutexGuard<Option<u32>>) -> Result<(), Error> {
92+
let client = &*self.blockchain;
9293

93-
{
94-
// First, check the confirmation status of registered transactions as well as the
95-
// status of dependent transactions of registered outputs.
96-
let mut locked_queued_transactions = self.queued_transactions.lock().unwrap();
97-
let mut locked_queued_outputs = self.queued_outputs.lock().unwrap();
98-
let mut locked_watched_transactions = self.watched_transactions.lock().unwrap();
99-
let mut locked_watched_outputs = self.watched_outputs.lock().unwrap();
100-
101-
let mut confirmed_txs = Vec::new();
102-
103-
// Check in the current queue, as well as in registered transactions leftover from
104-
// previous iterations.
105-
let registered_txs: HashSet<Txid> = locked_watched_transactions
106-
.iter()
107-
.chain(locked_queued_transactions.iter())
108-
.cloned()
109-
.collect();
110-
111-
// Remember all registered but unconfirmed transactions for future processing.
112-
let mut unconfirmed_registered_txs = Vec::new();
113-
114-
for txid in registered_txs {
115-
if let Some(tx_status) = client.get_tx_status(&txid)? {
116-
if tx_status.confirmed {
117-
if let Some(tx) = client.get_tx(&txid)? {
118-
if let Some(block_height) = tx_status.block_height {
119-
let block_header = client.get_header(block_height)?;
120-
if let Some(merkle_proof) = client.get_merkle_proof(&txid)? {
121-
confirmed_txs.push((
122-
tx,
123-
block_height,
124-
block_header,
125-
merkle_proof.pos,
94+
// Inform the interface of the new block.
95+
let cur_block_header = client.get_header(cur_height)?;
96+
for c in &confirmables {
97+
c.best_block_updated(&cur_block_header, cur_height);
98+
}
99+
100+
**locked_last_sync_height = Some(cur_height);
101+
Ok(())
102+
}
103+
104+
fn sync_transactions_confirmed(&self, confirmables: Vec<&(dyn Confirm + Sync)>) -> Result<(), Error> {
105+
let client = &*self.blockchain;
106+
107+
// First, check the confirmation status of registered transactions as well as the
108+
// status of dependent transactions of registered outputs.
109+
let mut locked_queued_transactions = self.queued_transactions.lock().unwrap();
110+
let mut locked_queued_outputs = self.queued_outputs.lock().unwrap();
111+
let mut locked_watched_transactions = self.watched_transactions.lock().unwrap();
112+
let mut locked_watched_outputs = self.watched_outputs.lock().unwrap();
113+
114+
let mut confirmed_txs = Vec::new();
115+
116+
// Check in the current queue, as well as in registered transactions leftover from
117+
// previous iterations.
118+
let registered_txs: HashSet<Txid> = locked_watched_transactions
119+
.iter()
120+
.chain(locked_queued_transactions.iter())
121+
.cloned()
122+
.collect();
123+
124+
// Remember all registered but unconfirmed transactions for future processing.
125+
let mut unconfirmed_registered_txs = Vec::new();
126+
127+
for txid in registered_txs {
128+
if let Some(tx_status) = client.get_tx_status(&txid)? {
129+
if tx_status.confirmed {
130+
if let Some(tx) = client.get_tx(&txid)? {
131+
if let Some(block_height) = tx_status.block_height {
132+
let block_header = client.get_header(block_height)?;
133+
if let Some(merkle_proof) = client.get_merkle_proof(&txid)? {
134+
confirmed_txs.push((
135+
tx,
136+
block_height,
137+
block_header,
138+
merkle_proof.pos,
126139
));
127-
continue;
128-
}
129-
}
140+
continue;
130141
}
131142
}
132143
}
133-
unconfirmed_registered_txs.push(txid);
134144
}
145+
}
146+
unconfirmed_registered_txs.push(txid);
147+
}
135148

136-
// Check all registered outputs for dependent spending transactions.
137-
let registered_outputs: Vec<WatchedOutput> = locked_watched_outputs
138-
.iter()
139-
.chain(locked_queued_outputs.iter())
140-
.cloned()
141-
.collect();
142-
143-
// Remember all registered outputs that haven't been spent for future processing.
144-
let mut unspent_registered_outputs = Vec::new();
145-
146-
for output in registered_outputs {
147-
if let Some(output_status) = client
148-
.get_output_status(&output.outpoint.txid, output.outpoint.index as u64)?
149-
{
150-
if output_status.spent {
151-
if let Some(spending_tx_status) = output_status.status {
152-
if spending_tx_status.confirmed {
153-
let spending_txid = output_status.txid.unwrap();
154-
if let Some(spending_tx) = client.get_tx(&spending_txid)? {
155-
let block_height = spending_tx_status.block_height.unwrap();
156-
let block_header = client.get_header(block_height)?;
157-
if let Some(merkle_proof) =
158-
client.get_merkle_proof(&spending_txid)?
149+
// Check all registered outputs for dependent spending transactions.
150+
let registered_outputs: Vec<WatchedOutput> = locked_watched_outputs
151+
.iter()
152+
.chain(locked_queued_outputs.iter())
153+
.cloned()
154+
.collect();
155+
156+
// Remember all registered outputs that haven't been spent for future processing.
157+
let mut unspent_registered_outputs = Vec::new();
158+
159+
for output in registered_outputs {
160+
if let Some(output_status) = client
161+
.get_output_status(&output.outpoint.txid, output.outpoint.index as u64)?
162+
{
163+
if output_status.spent {
164+
if let Some(spending_tx_status) = output_status.status {
165+
if spending_tx_status.confirmed {
166+
let spending_txid = output_status.txid.unwrap();
167+
if let Some(spending_tx) = client.get_tx(&spending_txid)? {
168+
let block_height = spending_tx_status.block_height.unwrap();
169+
let block_header = client.get_header(block_height)?;
170+
if let Some(merkle_proof) =
171+
client.get_merkle_proof(&spending_txid)?
159172
{
160173
confirmed_txs.push((
161-
spending_tx,
162-
block_height,
163-
block_header,
164-
merkle_proof.pos,
165-
));
174+
spending_tx,
175+
block_height,
176+
block_header,
177+
merkle_proof.pos,
178+
));
166179
continue;
167180
}
168-
}
169181
}
170182
}
171183
}
172184
}
173-
unspent_registered_outputs.push(output);
174-
}
175-
176-
// Sort all confirmed transactions first by block height, then by in-block
177-
// position, and finally feed them to the interface in order.
178-
confirmed_txs.sort_unstable_by(
179-
|(_, block_height1, _, pos1), (_, block_height2, _, pos2)| {
180-
block_height1.cmp(&block_height2).then_with(|| pos1.cmp(&pos2))
181-
},
182-
);
183-
for (tx, block_height, block_header, pos) in confirmed_txs {
184-
for c in &confirmables {
185-
c.transactions_confirmed(&block_header, &[(pos, &tx)], block_height);
186-
}
187185
}
186+
unspent_registered_outputs.push(output);
187+
}
188188

189-
*locked_watched_transactions = unconfirmed_registered_txs;
190-
*locked_queued_transactions = Vec::new();
191-
*locked_watched_outputs = unspent_registered_outputs;
192-
*locked_queued_outputs = Vec::new();
189+
// Sort all confirmed transactions first by block height, then by in-block
190+
// position, and finally feed them to the interface in order.
191+
confirmed_txs.sort_unstable_by(
192+
|(_, block_height1, _, pos1), (_, block_height2, _, pos2)| {
193+
block_height1.cmp(&block_height2).then_with(|| pos1.cmp(&pos2))
194+
},
195+
);
196+
for (tx, block_height, block_header, pos) in confirmed_txs {
197+
for c in &confirmables {
198+
c.transactions_confirmed(&block_header, &[(pos, &tx)], block_height);
193199
}
200+
}
194201

195-
{
196-
// Query the interface for relevant txids and check whether they have been
197-
// reorged-out of the chain.
198-
let unconfirmed_txids = confirmables
199-
.iter()
200-
.flat_map(|c| c.get_relevant_txids())
201-
.filter(|txid| {
202-
client
203-
.get_tx_status(txid)
204-
.ok()
205-
.unwrap_or(None)
206-
.map_or(true, |status| !status.confirmed)
207-
})
208-
.collect::<Vec<Txid>>();
209-
210-
// Mark all relevant unconfirmed transactions as unconfirmed.
211-
for txid in &unconfirmed_txids {
212-
for c in &confirmables {
213-
c.transaction_unconfirmed(txid);
214-
}
215-
}
202+
*locked_watched_transactions = unconfirmed_registered_txs;
203+
*locked_queued_transactions = Vec::new();
204+
*locked_watched_outputs = unspent_registered_outputs;
205+
*locked_queued_outputs = Vec::new();
206+
207+
Ok(())
208+
}
209+
210+
fn sync_transaction_unconfirmed(&self, confirmables: Vec<&(dyn Confirm + Sync)>) -> Result<(), Error> {
211+
let client = &*self.blockchain;
212+
// Query the interface for relevant txids and check whether they have been
213+
// reorged-out of the chain.
214+
let unconfirmed_txids = confirmables
215+
.iter()
216+
.flat_map(|c| c.get_relevant_txids())
217+
.filter(|txid| {
218+
client
219+
.get_tx_status(txid)
220+
.ok()
221+
.unwrap_or(None)
222+
.map_or(true, |status| !status.confirmed)
223+
})
224+
.collect::<Vec<Txid>>();
225+
226+
// Mark all relevant unconfirmed transactions as unconfirmed.
227+
for txid in &unconfirmed_txids {
228+
for c in &confirmables {
229+
c.transaction_unconfirmed(txid);
216230
}
217231
}
218232

219-
// TODO: check whether new outputs have been registered by now and process them
220233
Ok(())
221234
}
222235

0 commit comments

Comments
 (0)