Skip to content

Commit

Permalink
fetch block from unverified tip
Browse files Browse the repository at this point in the history
  • Loading branch information
eval-exec committed Aug 4, 2023
1 parent bbdd63a commit 70663de
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 19 deletions.
60 changes: 46 additions & 14 deletions sync/src/synchronizer/block_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,21 @@ impl<'a> BlockFetcher<'a> {
) -> Option<BlockNumberAndHash> {
// Bootstrap quickly by guessing an ancestor of our best tip is forking point.
// Guessing wrong in either direction is not a problem.
let mut last_common =
if let Some(header) = self.synchronizer.peers().get_last_common_header(self.peer) {
header
let mut last_common = if let Some(header) =
self.synchronizer.peers().get_last_common_header(self.peer)
{
header
} else {
let unverified_tip_header = self.synchronizer.shared().shared().get_unverified_tip();
if best_known.number() < unverified_tip_header.number() {
(best_known.number(), best_known.hash()).into()
} else {
let tip_header = self.active_chain.tip_header();
let guess_number = min(tip_header.number(), best_known.number());
let guess_hash = self.active_chain.get_block_hash(guess_number)?;
(guess_number, guess_hash).into()
};
(unverified_tip_header.number(), unverified_tip_header.hash()).into()
}
// let guess_number = min(tip_header.number(), best_known.number());
// let guess_hash = self.active_chain.get_block_hash(guess_number)?;
// (guess_number, guess_hash).into()
};

// If the peer reorganized, our previous last_common_header may not be an ancestor
// of its current tip anymore. Go back enough to fix that.
Expand All @@ -70,6 +76,8 @@ impl<'a> BlockFetcher<'a> {
}

pub fn fetch(self) -> Option<Vec<Vec<packed::Byte32>>> {
let trace_timecost_now = std::time::Instant::now();

if self.reached_inflight_limit() {
trace!(
"[block_fetcher] inflight count reach limit, can't download any more from peer {}",
Expand Down Expand Up @@ -114,7 +122,7 @@ impl<'a> BlockFetcher<'a> {
// last_common_header, is expected to provide a more realistic picture. Hence here we
// specially advance this peer's last_common_header at the case of both us on the same
// active chain.
if self.active_chain.is_main_chain(&best_known.hash()) {
if self.active_chain.is_unverified_chain(&best_known.hash()) {
self.synchronizer
.peers()
.set_last_common_header(self.peer, best_known.number_and_hash());
Expand Down Expand Up @@ -186,24 +194,48 @@ impl<'a> BlockFetcher<'a> {
fetch.sort_by_key(|header| header.number());

let tip = self.active_chain.tip_number();
let unverified_tip = self.active_chain.unverified_tip_number();
let should_mark = fetch.last().map_or(false, |header| {
header.number().saturating_sub(CHECK_POINT_WINDOW) > tip
header.number().saturating_sub(CHECK_POINT_WINDOW) > unverified_tip
});
if should_mark {
inflight.mark_slow_block(tip);
}

if fetch.is_empty() {
debug!(
"[block fetch empty] fixed_last_common_header = {} \
best_known_header = {}, tip = {}, inflight_len = {}, \
inflight_state = {:?}",
"[block fetch empty] peer-{}, fixed_last_common_header = {} \
best_known_header = {}, tip = {}, unverified_tip = {}, inflight_len = {}, time_cost: {}ms",
self.peer,
last_common.number(),
best_known.number(),
tip,
unverified_tip,
inflight.total_inflight_count(),
trace_timecost_now.elapsed().as_millis(),
);
trace!(
"[block fetch empty] peer-{}, inflight_state = {:?}",
self.peer,
*inflight
)
);
} else {
let fetch_head = fetch.first().map_or(0_u64.into(), |v| v.number());
let fetch_last = fetch.last().map_or(0_u64.into(), |v| v.number());
let inflight_peer_count = inflight.peer_inflight_count(self.peer);
let inflight_total_count = inflight.total_inflight_count();
debug!(
"request peer-{} for batch blocks: [{}-{}], batch len:{} , unverified_tip: {}, [peer/total inflight count]: [{} / {}], timecost: {}ms, blocks: {}",
self.peer,
fetch_head,
fetch_last,
fetch.len(),
self.synchronizer.shared().shared().get_unverified_tip().number(),
inflight_peer_count,
inflight_total_count,
trace_timecost_now.elapsed().as_millis(),
fetch.iter().map(|h| h.number().to_string()).collect::<Vec<_>>().join(","),
);
}

Some(
Expand Down
29 changes: 24 additions & 5 deletions sync/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,8 +1188,8 @@ impl SyncShared {
// So we just simply remove the corresponding in-memory block status,
// and the next time `get_block_status` would acquire the real-time
// status via fetching block_ext from the database.
self.shared().remove_block_status(&block.as_ref().hash());
self.shared().remove_header_view(&block.as_ref().hash());
// self.shared().remove_block_status(&block.as_ref().hash());
// self.shared().remove_header_view(&block.as_ref().hash());
}

ret
Expand Down Expand Up @@ -1794,22 +1794,41 @@ impl ActiveChain {
pub fn is_main_chain(&self, hash: &packed::Byte32) -> bool {
self.snapshot.is_main_chain(hash)
}
pub fn is_unverified_chain(&self, hash: &packed::Byte32) -> bool {
self.shared()
.shared()
.store()
.get_block_epoch_index(hash)
.is_some()
}

pub fn is_initial_block_download(&self) -> bool {
self.shared.shared().is_initial_block_download()
}
pub fn unverified_tip_header(&self) -> HeaderIndex {
self.shared.shared.get_unverified_tip()
}

pub fn unverified_tip_hash(&self) -> Byte32 {
self.unverified_tip_header().hash()
}

pub fn unverified_tip_number(&self) -> BlockNumber {
self.unverified_tip_header().number()
}

pub fn get_ancestor(&self, base: &Byte32, number: BlockNumber) -> Option<HeaderIndexView> {
let tip_number = self.tip_number();
let unverified_tip_number = self.unverified_tip_number();
self.shared
.get_header_index_view(base, false)?
.get_ancestor(
tip_number,
unverified_tip_number,
number,
|hash, store_first| self.shared.get_header_index_view(hash, store_first),
|number, current| {
// shortcut to return an ancestor block
if current.number <= tip_number && self.snapshot().is_main_chain(&current.hash)
if current.number <= unverified_tip_number
&& self.is_unverified_chain(&current.hash)
{
self.get_block_hash(number)
.and_then(|hash| self.shared.get_header_index_view(&hash, true))
Expand Down

0 comments on commit 70663de

Please sign in to comment.