[chain_redesign] Add LocalChain::insert_block

This commit is contained in:
志宇
2023-05-03 15:01:39 +08:00
parent e413d3e424
commit 085bf9413d
2 changed files with 108 additions and 1 deletions

View File

@@ -173,6 +173,31 @@ impl LocalChain {
pub fn heights(&self) -> BTreeSet<u32> {
self.blocks.keys().cloned().collect()
}
/// Insert a block of [`BlockId`] into the [`LocalChain`].
///
/// # Error
///
/// If the insertion height already contains a block, and the block has a different blockhash,
/// this will result in an [`InsertBlockNotMatchingError`].
pub fn insert_block(
&mut self,
block_id: BlockId,
) -> Result<ChangeSet, InsertBlockNotMatchingError> {
let mut update = Self::from_blocks(self.tip());
if let Some(original_hash) = update.blocks.insert(block_id.height, block_id.hash) {
if original_hash != block_id.hash {
return Err(InsertBlockNotMatchingError {
height: block_id.height,
original_hash,
update_hash: block_id.hash,
});
}
}
Ok(self.apply_update(update).expect("should always connect"))
}
}
/// This is the return value of [`determine_changeset`] and represents changes to [`LocalChain`].
@@ -201,3 +226,24 @@ impl core::fmt::Display for UpdateNotConnectedError {
#[cfg(feature = "std")]
impl std::error::Error for UpdateNotConnectedError {}
/// Represents a failure when trying to insert a checkpoint into [`LocalChain`].
#[derive(Clone, Debug, PartialEq)]
pub struct InsertBlockNotMatchingError {
pub height: u32,
pub original_hash: BlockHash,
pub update_hash: BlockHash,
}
impl core::fmt::Display for InsertBlockNotMatchingError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"failed to insert block at height {} as blockhashes conflict: original={}, update={}",
self.height, self.original_hash, self.update_hash
)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InsertBlockNotMatchingError {}