message: Properly initialize `completed_blocks` in storage component constructor
diff: @@ -87,6 +87,7 @@ use crate::{
  fatal,
  protocol::Message,
  reactor::ReactorEvent,
  + storage::disjoint_sequences::Sequence,
  types::{
  AvailableBlockRange, Block, BlockAndDeploys, BlockBody, BlockHash, BlockHashAndHeight,
  BlockHeader, BlockHeaderWithMetadata, BlockHeadersBatch, BlockHeadersBatchId,
  @@ -521,8 +522,23 @@ impl Storage {
  component.completed_blocks = sequences;
  }
  None => {
  - // No state so far. Leave empty.
  - // TODO: Reconstruct state from contract runtime?
  + // No state so far. We can make the following observations:
  + //
  + // 1. Any block already in storage from versions prior to 1.5 (no fast-sync) MUST
  + // have the corresponding global state in contract runtime, due to the way sync
  + // worked previously.
  + // 2. Any block acquired from that point onwards was subject to the insertion of the
  + // appropriate announcements (`BlockCompletedAnnouncement`), which would have
  + // caused the creation of the completed blocks index, thus would not have
  + // resulted in a `None` value here.
  + //
  + // For this reason, it is safe to assume that, when handling the `None` case, all
  + // blocks in storage are complete blocks.
  + if let Some(&highest_block) = component.block_height_index.keys().last() {
  + component.completed_blocks =
  + DisjointSequences::new(Sequence::new(0, highest_block));
  + component.persist_completed_blocks()?;
  + } // the `else` case here would mean genesis, so no change.
  }
  }
  @@ -1148,19 +1164,24 @@ impl Storage {
  })
  }
  + /// Handles a [`BlockCompletedAnnouncement`].
  fn handle_block_completed_announcement(
  &mut self,
  BlockCompletedAnnouncement { block_height }: BlockCompletedAnnouncement,
  ) -> Result<Effects<Event>, FatalStorageError> {
  self.completed_blocks.insert(block_height);
  + self.persist_completed_blocks()?;
  + Ok(Default::default())
  + }
  +
  + /// Persists the completed blocks disjoint sequences state to the database.
  + fn persist_completed_blocks(&mut self) -> Result<(), FatalStorageError> {
  let serialized = self
  .completed_blocks
  .to_bytes()
  .map_err(FatalStorageError::UnexpectedSerializationFailure)?;
  - self.write_state_store(&Cow::Borrowed(COMPLETED_BLOCKS_STORAGE_KEY), &serialized)?;
  -
  - Ok(Default::default())
  + self.write_state_store(&Cow::Borrowed(COMPLETED_BLOCKS_STORAGE_KEY), &serialized)
  }
  /// Put a single deploy into storage.
  