Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/finality-grandpa-warp-sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,6 @@ pub enum HandleRequestError {
InvalidProof(String),
#[display(fmt = "Failed to send response.")]
SendResponse,
#[display(fmt = "Missing required data to be able to answer request.")]
MissingData,
}
5 changes: 4 additions & 1 deletion client/finality-grandpa-warp-sync/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ impl<Block: BlockT> WarpSyncProof<Block> {
let mut proofs_encoded_len = 0;
let mut proof_limit_reached = false;

for (_, last_block) in set_changes.iter_from(begin_number) {
let set_changes = set_changes.iter_from(begin_number)
.ok_or(HandleRequestError::MissingData)?;

for (_, last_block) in set_changes {
let header = blockchain.header(BlockId::Number(*last_block))?.expect(
"header number comes from previously applied set changes; must exist in db; qed.",
);
Expand Down
51 changes: 33 additions & 18 deletions client/finality-grandpa/src/authorities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,18 +730,12 @@ impl<N: Ord + Clone> AuthoritySetChanges<N> {

if idx < self.0.len() {
let (set_id, block_number) = self.0[idx].clone();
// To make sure we have the right set we need to check that the one before it also exists.
if idx > 0 {
let (prev_set_id, _) = self.0[idx - 1usize];
if set_id != prev_set_id + 1u64 {
// Without the preceding set_id we don't have a well-defined start.
return AuthoritySetChangeId::Unknown;
}
} else if set_id != 0 {
// If this is the first index, yet not the first set id then it's not well-defined
// that we are in the right set id.

// if this is the first index but not the first set id then we are missing data.
if idx == 0 && set_id != 0 {
return AuthoritySetChangeId::Unknown;
}

AuthoritySetChangeId::Set(set_id, block_number)
} else {
AuthoritySetChangeId::Unknown
Expand All @@ -751,14 +745,23 @@ impl<N: Ord + Clone> AuthoritySetChanges<N> {
/// Returns an iterator over all historical authority set changes starting at the given block
/// number (excluded). The iterator yields a tuple representing the set id and the block number
/// of the last block in that set.
pub fn iter_from(&self, block_number: N) -> impl Iterator<Item = &(u64, N)> {
pub fn iter_from(&self, block_number: N) -> Option<impl Iterator<Item = &(u64, N)>> {
let idx = self.0.binary_search_by_key(&block_number, |(_, n)| n.clone())
// if there was a change at the given block number then we should start on the next
// index since we want to exclude the current block number
.map(|n| n + 1)
.unwrap_or_else(|b| b);

self.0[idx..].iter()
if idx < self.0.len() {
let (set_id, _) = self.0[idx].clone();

// if this is the first index but not the first set id then we are missing data.
if idx == 0 && set_id != 0 {
return None;
}
}

Some(self.0[idx..].iter())
}
}

Expand Down Expand Up @@ -1710,26 +1713,38 @@ mod tests {
let mut authority_set_changes = AuthoritySetChanges::empty();
authority_set_changes.append(1, 41);
authority_set_changes.append(2, 81);

// we are missing the data for the first set, therefore we should return `None`
assert_eq!(
None,
authority_set_changes.iter_from(40).map(|it| it.collect::<Vec<_>>()),
);

// after adding the data for the first set the same query should work
let mut authority_set_changes = AuthoritySetChanges::empty();
authority_set_changes.append(0, 21);
authority_set_changes.append(1, 41);
authority_set_changes.append(2, 81);
authority_set_changes.append(3, 121);

assert_eq!(
vec![(1, 41), (2, 81), (3, 121)],
authority_set_changes.iter_from(40).cloned().collect::<Vec<_>>(),
Some(vec![(1, 41), (2, 81), (3, 121)]),
authority_set_changes.iter_from(40).map(|it| it.cloned().collect::<Vec<_>>()),
);

assert_eq!(
vec![(2, 81), (3, 121)],
authority_set_changes.iter_from(41).cloned().collect::<Vec<_>>(),
Some(vec![(2, 81), (3, 121)]),
authority_set_changes.iter_from(41).map(|it| it.cloned().collect::<Vec<_>>()),
);

assert_eq!(
0,
authority_set_changes.iter_from(121).count(),
authority_set_changes.iter_from(121).unwrap().count(),
);

assert_eq!(
0,
authority_set_changes.iter_from(200).count(),
authority_set_changes.iter_from(200).unwrap().count(),
);
}
}