Skip to content

Commit a1b3de1

Browse files
block-sync: poll: make best known chain tip optional
1 parent e77b160 commit a1b3de1

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

lightning-block-sync/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ impl<'a, P: Poll, C: Cache, L: Deref> SpvClient<'a, P, C, L> where L::Target: ch
235235
/// Returns the best polled chain tip relative to the previous best known tip and whether any
236236
/// blocks were indeed connected or disconnected.
237237
pub async fn poll_best_tip(&mut self) -> BlockSourceResult<(ChainTip, bool)> {
238-
let chain_tip = self.chain_poller.poll_chain_tip(self.chain_tip).await?;
238+
let chain_tip = self.chain_poller.poll_chain_tip(Some(self.chain_tip)).await?;
239239
let blocks_connected = match chain_tip {
240240
ChainTip::Common => false,
241241
ChainTip::Better(chain_tip) => {

lightning-block-sync/src/poll.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::ops::DerefMut;
1515
/// [`ChainPoller`]: ../struct.ChainPoller.html
1616
pub trait Poll {
1717
/// Returns a chain tip in terms of its relationship to the provided chain tip.
18-
fn poll_chain_tip<'a>(&'a mut self, best_known_chain_tip: ValidatedBlockHeader) ->
18+
fn poll_chain_tip<'a>(&'a mut self, best_known_chain_tip: Option<ValidatedBlockHeader>) ->
1919
AsyncBlockSourceResult<'a, ChainTip>;
2020

2121
/// Returns the header that preceded the given header in the chain.
@@ -174,22 +174,28 @@ impl<B: DerefMut<Target=T> + Sized + Sync + Send, T: BlockSource> ChainPoller<B,
174174
}
175175

176176
impl<B: DerefMut<Target=T> + Sized + Sync + Send, T: BlockSource> Poll for ChainPoller<B, T> {
177-
fn poll_chain_tip<'a>(&'a mut self, best_known_chain_tip: ValidatedBlockHeader) ->
177+
fn poll_chain_tip<'a>(&'a mut self, best_known_chain_tip: Option<ValidatedBlockHeader>) ->
178178
AsyncBlockSourceResult<'a, ChainTip>
179179
{
180180
Box::pin(async move {
181181
let (block_hash, height) = self.block_source.get_best_block().await?;
182-
if block_hash == best_known_chain_tip.header.block_hash() {
183-
return Ok(ChainTip::Common);
182+
if let Some(curr_tip) = best_known_chain_tip {
183+
if block_hash == curr_tip.header.block_hash() {
184+
return Ok(ChainTip::Common);
185+
}
184186
}
185187

186188
let chain_tip = self.block_source
187189
.get_header(&block_hash, height).await?
188190
.validate(block_hash)?;
189-
if chain_tip.chainwork > best_known_chain_tip.chainwork {
190-
Ok(ChainTip::Better(chain_tip))
191+
if let Some(curr_tip) = best_known_chain_tip {
192+
if chain_tip.chainwork > curr_tip.chainwork {
193+
Ok(ChainTip::Better(chain_tip))
194+
} else {
195+
Ok(ChainTip::Worse(chain_tip))
196+
}
191197
} else {
192-
Ok(ChainTip::Worse(chain_tip))
198+
Ok(ChainTip::Better(chain_tip))
193199
}
194200
})
195201
}
@@ -234,7 +240,7 @@ mod tests {
234240
#[tokio::test]
235241
async fn poll_empty_chain() {
236242
let mut chain = Blockchain::default().with_height(0);
237-
let best_known_chain_tip = chain.tip();
243+
let best_known_chain_tip = Some(chain.tip());
238244
chain.disconnect_tip();
239245

240246
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
@@ -250,7 +256,7 @@ mod tests {
250256
#[tokio::test]
251257
async fn poll_chain_without_headers() {
252258
let mut chain = Blockchain::default().with_height(1).without_headers();
253-
let best_known_chain_tip = chain.at_height(0);
259+
let best_known_chain_tip = Some(chain.at_height(0));
254260

255261
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
256262
match poller.poll_chain_tip(best_known_chain_tip).await {
@@ -265,7 +271,7 @@ mod tests {
265271
#[tokio::test]
266272
async fn poll_chain_with_invalid_pow() {
267273
let mut chain = Blockchain::default().with_height(1);
268-
let best_known_chain_tip = chain.at_height(0);
274+
let best_known_chain_tip = Some(chain.at_height(0));
269275

270276
// Invalidate the tip by changing its target.
271277
chain.blocks.last_mut().unwrap().header.bits =
@@ -284,7 +290,7 @@ mod tests {
284290
#[tokio::test]
285291
async fn poll_chain_with_malformed_headers() {
286292
let mut chain = Blockchain::default().with_height(1).malformed_headers();
287-
let best_known_chain_tip = chain.at_height(0);
293+
let best_known_chain_tip = Some(chain.at_height(0));
288294

289295
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
290296
match poller.poll_chain_tip(best_known_chain_tip).await {
@@ -299,7 +305,7 @@ mod tests {
299305
#[tokio::test]
300306
async fn poll_chain_with_common_tip() {
301307
let mut chain = Blockchain::default().with_height(0);
302-
let best_known_chain_tip = chain.tip();
308+
let best_known_chain_tip = Some(chain.tip());
303309

304310
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
305311
match poller.poll_chain_tip(best_known_chain_tip).await {
@@ -319,7 +325,7 @@ mod tests {
319325
assert_eq!(best_known_chain_tip.chainwork, worse_chain_tip.chainwork);
320326

321327
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
322-
match poller.poll_chain_tip(best_known_chain_tip).await {
328+
match poller.poll_chain_tip(Some(best_known_chain_tip)).await {
323329
Err(e) => panic!("Unexpected error: {:?}", e),
324330
Ok(tip) => assert_eq!(tip, ChainTip::Worse(worse_chain_tip)),
325331
}
@@ -328,7 +334,7 @@ mod tests {
328334
#[tokio::test]
329335
async fn poll_chain_with_worse_tip() {
330336
let mut chain = Blockchain::default().with_height(1);
331-
let best_known_chain_tip = chain.tip();
337+
let best_known_chain_tip = Some(chain.tip());
332338

333339
chain.disconnect_tip();
334340
let worse_chain_tip = chain.tip();
@@ -348,9 +354,20 @@ mod tests {
348354
let better_chain_tip = chain.tip();
349355

350356
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
351-
match poller.poll_chain_tip(best_known_chain_tip).await {
357+
match poller.poll_chain_tip(Some(best_known_chain_tip)).await {
352358
Err(e) => panic!("Unexpected error: {:?}", e),
353359
Ok(tip) => assert_eq!(tip, ChainTip::Better(better_chain_tip)),
354360
}
355361
}
362+
363+
#[tokio::test]
364+
async fn poll_chain_no_best_tip() {
365+
let mut chain = Blockchain::default().with_height(1);
366+
let chain_tip = chain.tip();
367+
let mut poller = ChainPoller::new(&mut chain, Network::Bitcoin);
368+
match poller.poll_chain_tip(None).await {
369+
Err(e) => panic!("Unexpected error: {:?}", e),
370+
Ok(tip) => assert_eq!(tip, ChainTip::Better(chain_tip)),
371+
}
372+
}
356373
}

0 commit comments

Comments
 (0)