Skip to content

Commit a1b7d29

Browse files
committed
Implement check method
1 parent a47c347 commit a1b7d29

1 file changed

Lines changed: 133 additions & 6 deletions

File tree

repository/src/lib.rs

Lines changed: 133 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use simperby_common::verify::CommitSequenceVerifier;
1414
use simperby_common::*;
1515
use simperby_network::{NetworkConfig, Peer, SharedKnownPeers};
1616
use std::{collections::HashSet, fmt};
17+
use utils::*;
1718

1819
pub type Branch = String;
1920
pub type Tag = String;
@@ -226,13 +227,139 @@ impl<T: RawRepository> DistributedRepository<T> {
226227
/// Checks the validity of the repository, starting from the given height.
227228
///
228229
/// It checks
229-
/// 1. all the reserved branches and tags
230-
/// 2. the finalization proof in the `fp` branch.
231-
/// 3. the existence of merge commits
232-
/// 4. the canonical history of the `finalized` branch.
230+
/// 1. all the reserved branches and tags,
231+
/// 2. the finalization proof in the `fp` branch,
232+
/// 3. the existence of merge commits,
233+
/// 4. the canonical history of the `finalized` branch,
233234
/// 5. the reserved state in a valid format.
234-
pub async fn check(&self, _starting_height: BlockHeight) -> Result<bool, Error> {
235-
unimplemented!()
235+
pub async fn check(&self, starting_height: BlockHeight) -> Result<bool, Error> {
236+
let last_header = self.get_last_finalized_block_header().await?;
237+
if last_header.height < starting_height {
238+
return Err(anyhow!(
239+
"starting height {} is higher than the last finalized block height {}",
240+
starting_height,
241+
last_header.height
242+
));
243+
}
244+
245+
// Construct a commit list starting from the block commit of the `starting_height`
246+
// to the `last_header_commit`(the most recent commit of the `finalized` branch)
247+
let inital_commit_hash = self.raw.get_initial_commit().await?;
248+
let last_header_commit = self.raw.locate_branch(FINALIZED_BRANCH_NAME.into()).await?;
249+
let all_commits = read_commits(self, inital_commit_hash, last_header_commit).await?;
250+
let starting_block_commit_position = all_commits
251+
.iter()
252+
.position(|(commit, _)| {
253+
if let Commit::Block(block_header) = commit {
254+
block_header.height == starting_height
255+
} else {
256+
false
257+
}
258+
})
259+
.ok_or_else(|| {
260+
anyhow!(
261+
"cannot find the commit of the block at height {}",
262+
starting_height
263+
)
264+
})?;
265+
let commits = all_commits
266+
.into_iter()
267+
.skip(starting_block_commit_position)
268+
.collect::<Vec<_>>();
269+
270+
// TODO: Get the reserved state of the `starting_height` block and verify.
271+
// to check the canonical history of the `finalized` branch
272+
// Note that whether the reserved state in a valid format is also checked
273+
// by the `CommitSequenceVerifier`. (See #166)
274+
// TODO: Check the existence of merge commits
275+
for (commit, commit_hash) in commits {
276+
// Check all the reserved branches
277+
let branches = self.raw.get_branches(commit_hash).await?;
278+
for branch in branches {
279+
match commit {
280+
Commit::Agenda(_) => {
281+
if branch
282+
!= format!(
283+
"a-{:?}",
284+
commit
285+
.to_hash256()
286+
.to_string()
287+
.truncate(TAG_NAME_HASH_DIGITS)
288+
)
289+
{
290+
return Ok(false);
291+
}
292+
}
293+
Commit::AgendaProof(_) => {
294+
if branch
295+
!= format!(
296+
"a-{:?}",
297+
commit
298+
.to_hash256()
299+
.to_string()
300+
.truncate(TAG_NAME_HASH_DIGITS)
301+
)
302+
{
303+
return Ok(false);
304+
}
305+
}
306+
Commit::Block(_) => {
307+
if branch
308+
!= format!(
309+
"b-{:?}",
310+
commit
311+
.to_hash256()
312+
.to_string()
313+
.truncate(TAG_NAME_HASH_DIGITS)
314+
)
315+
{
316+
return Ok(false);
317+
}
318+
}
319+
_ => {
320+
return Ok(false);
321+
}
322+
}
323+
}
324+
325+
// Check all the reserved tags
326+
let tags = self.raw.get_tag(commit_hash).await?;
327+
for tag in tags {
328+
match commit {
329+
Commit::Agenda(_) => {
330+
if tag
331+
!= format!(
332+
"vote-{:?}",
333+
commit
334+
.to_hash256()
335+
.to_string()
336+
.truncate(TAG_NAME_HASH_DIGITS)
337+
)
338+
{
339+
return Ok(false);
340+
}
341+
}
342+
Commit::Block(_) => {
343+
if tag
344+
!= format!(
345+
"veto-{:?}",
346+
commit
347+
.to_hash256()
348+
.to_string()
349+
.truncate(TAG_NAME_HASH_DIGITS)
350+
)
351+
{
352+
return Ok(false);
353+
}
354+
}
355+
_ => {
356+
return Ok(false);
357+
}
358+
}
359+
}
360+
}
361+
362+
Ok(true)
236363
}
237364

238365
/// Synchronizes the `finalized` branch to the given commit.

0 commit comments

Comments
 (0)