github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/journal/block_manager.rs (about)

     1  /*
     2   * Copyright 2018 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ------------------------------------------------------------------------------
    16   */
    17  
    18  use std::collections::HashMap;
    19  use std::collections::HashSet;
    20  
    21  use block::Block;
    22  use journal::block_store::{BlockStore, BlockStoreError};
    23  use journal::NULL_BLOCK_IDENTIFIER;
    24  
    25  #[derive(Debug, PartialEq)]
    26  pub enum BlockManagerError {
    27      MissingPredecessor(String),
    28      MissingPredecessorInBranch(String),
    29      MissingInput,
    30      UnknownBlock,
    31      UnknownBlockStore,
    32      BlockStoreError,
    33  }
    34  
    35  impl From<BlockStoreError> for BlockManagerError {
    36      fn from(_other: BlockStoreError) -> Self {
    37          BlockManagerError::BlockStoreError
    38      }
    39  }
    40  
    41  /// Anchors hold reference count information for blocks that are just on the inside edge
    42  /// of a blockstore. This includes the head block in a blockstore.
    43  #[derive(Default)]
    44  struct Anchors {
    45      anchors_by_blockstore_name: HashMap<String, HashSet<String>>,
    46  
    47      anchors_by_block_id: HashMap<String, Anchor>,
    48  }
    49  
    50  impl Anchors {
    51      fn add_anchor(
    52          &mut self,
    53          block_id: &str,
    54          blockstore_name: &str,
    55          block_num: u64,
    56          external_ref_count: u64,
    57          internal_ref_count: u64,
    58      ) {
    59          let anchor = Anchor {
    60              blockstore_name: blockstore_name.into(),
    61              external_ref_count,
    62              internal_ref_count,
    63              block_id: block_id.into(),
    64              block_num,
    65          };
    66          self.anchors_by_block_id.insert(block_id.into(), anchor);
    67  
    68          if self.anchors_by_blockstore_name
    69              .get_mut(blockstore_name)
    70              .map(|ref mut anchors| anchors.insert(block_id.into()))
    71              .is_none()
    72          {
    73              let mut set = HashSet::new();
    74              set.insert(block_id.into());
    75  
    76              self.anchors_by_blockstore_name
    77                  .insert(blockstore_name.into(), set);
    78          }
    79      }
    80  
    81      fn get_blockstore_name(&self, block_id: &str) -> Option<&str> {
    82          self.anchors_by_block_id
    83              .get(block_id)
    84              .map(|anchor| anchor.blockstore_name.as_str())
    85      }
    86  
    87      fn convert(&mut self, blocks: Vec<Block>) -> Vec<RefBlock> {
    88          blocks
    89              .into_iter()
    90              .map(|block| {
    91                  let anchor = self.anchors_by_block_id
    92                      .remove(block.header_signature.as_str())
    93                      .unwrap();
    94                  let anchors = self.anchors_by_blockstore_name
    95                      .get_mut(anchor.blockstore_name.as_str())
    96                      .expect("Anchors in anchor_by_block_id and anchors_by_blockstore_name lost integrity");
    97                  anchors.remove(block.header_signature.as_str());
    98                  RefBlock::new(block, anchor.external_ref_count, anchor.internal_ref_count)
    99              })
   100              .collect()
   101      }
   102  
   103      fn iter_by_blockstore<'a>(
   104          &'a self,
   105          blockstore_name: &str,
   106      ) -> Box<Iterator<Item = &Anchor> + 'a> {
   107          let anchors_by_block_id = &self.anchors_by_block_id;
   108  
   109          match self.anchors_by_blockstore_name.get(blockstore_name) {
   110              Some(anchors) => {
   111                  let iter = anchors
   112                      .iter()
   113                      .map(move |block_id| anchors_by_block_id.get(block_id).unwrap());
   114                  Box::new(iter)
   115              }
   116              None => Box::new(::std::iter::empty()),
   117          }
   118      }
   119  
   120      fn contains(&self, block_id: &str) -> bool {
   121          self.anchors_by_block_id.contains_key(block_id)
   122      }
   123  
   124      fn increase_internal_ref_count(&mut self, block_id: &str) {
   125          if let Some(anchor) = self.anchors_by_block_id.get_mut(block_id) {
   126              anchor.internal_ref_count += 1;
   127          }
   128      }
   129  
   130      fn decrease_internal_ref_count(&mut self, block_id: &str) {
   131          if let Some(anchor) = self.anchors_by_block_id.get_mut(block_id) {
   132              match anchor.internal_ref_count.checked_sub(1) {
   133                  Some(ref_count) => anchor.internal_ref_count = ref_count,
   134                  None => panic!("The internal ref-count on an anchor dropped below 0"),
   135              }
   136          }
   137      }
   138  
   139      fn get_internal_ref_count(&self, block_id: &str) -> Option<u64> {
   140          self.anchors_by_block_id
   141              .get(block_id)
   142              .map(|anchor| anchor.internal_ref_count)
   143      }
   144  
   145      fn increase_external_ref_count(&mut self, block_id: &str) {
   146          if let Some(anchor) = self.anchors_by_block_id.get_mut(block_id) {
   147              anchor.external_ref_count += 1;
   148          }
   149      }
   150  
   151      fn decrease_external_ref_count(&mut self, block_id: &str) {
   152          if let Some(anchor) = self.anchors_by_block_id.get_mut(block_id) {
   153              match anchor.external_ref_count.checked_sub(1) {
   154                  Some(ref_count) => anchor.external_ref_count = ref_count,
   155                  None => panic!("The external ref-count on an anchor dropped below 0"),
   156              }
   157          }
   158      }
   159  
   160      fn get_external_ref_count(&self, block_id: &str) -> Option<u64> {
   161          self.anchors_by_block_id
   162              .get(block_id)
   163              .map(|anchor| anchor.external_ref_count)
   164      }
   165  }
   166  
   167  struct Anchor {
   168      pub blockstore_name: String,
   169      pub external_ref_count: u64,
   170      pub internal_ref_count: u64,
   171      pub block_num: u64,
   172      pub block_id: String,
   173  }
   174  
   175  struct RefBlock {
   176      pub block: Block,
   177      pub external_ref_count: u64,
   178      pub internal_ref_count: u64,
   179  }
   180  
   181  impl RefBlock {
   182      fn new_reffed_block(block: Block) -> Self {
   183          RefBlock {
   184              block,
   185              external_ref_count: 0,
   186              internal_ref_count: 1,
   187          }
   188      }
   189  
   190      fn new_unreffed_block(block: Block) -> Self {
   191          RefBlock {
   192              block,
   193              external_ref_count: 1,
   194              internal_ref_count: 0,
   195          }
   196      }
   197  
   198      fn new(block: Block, external_ref_count: u64, internal_ref_count: u64) -> Self {
   199          RefBlock {
   200              block,
   201              external_ref_count,
   202              internal_ref_count,
   203          }
   204      }
   205  
   206      fn increase_internal_ref_count(&mut self) {
   207          self.internal_ref_count += 1;
   208      }
   209  
   210      fn decrease_internal_ref_count(&mut self) {
   211          match self.internal_ref_count.checked_sub(1) {
   212              Some(ref_count) => self.internal_ref_count = ref_count,
   213              None => panic!("The internal ref-count fell below zero, its lowest possible value"),
   214          }
   215      }
   216  
   217      fn increase_external_ref_count(&mut self) {
   218          self.external_ref_count += 1;
   219      }
   220  
   221      fn decrease_external_ref_count(&mut self) {
   222          match self.external_ref_count.checked_sub(1) {
   223              Some(ref_count) => self.external_ref_count = ref_count,
   224              None => panic!("The external ref-count fell below zero, its lowest possible value"),
   225          }
   226      }
   227  }
   228  
   229  #[derive(Default)]
   230  pub struct BlockManager {
   231      block_by_block_id: HashMap<String, RefBlock>,
   232  
   233      blockstore_by_name: HashMap<String, Box<BlockStore>>,
   234  
   235      anchors: Anchors,
   236  }
   237  
   238  /// The BlockManager maintains integrity of all the blocks it contains,
   239  /// such that for any Block within the BlockManager,
   240  /// that Block's predecessor is also within the BlockManager.
   241  impl BlockManager {
   242      pub fn new() -> Self {
   243          BlockManager::default()
   244      }
   245  
   246      fn contains(&self, block_id: &str) -> bool {
   247          let in_memory = self.block_by_block_id.contains_key(block_id);
   248  
   249          let in_any_blockstore = self.blockstore_by_name
   250              .values()
   251              .any(|blockstore| blockstore.get(vec![block_id.into()]).count() > 0);
   252          let is_root = block_id == NULL_BLOCK_IDENTIFIER;
   253  
   254          in_memory || in_any_blockstore || is_root
   255      }
   256  
   257      /// Checks that every block is preceded by the block referenced by block.previous_block_id except the
   258      /// zeroth block in tail, which references head.
   259      fn check_predecessor_relationship(
   260          &self,
   261          tail: &[Block],
   262          head: &Block,
   263      ) -> Result<(), BlockManagerError> {
   264          let mut previous = None;
   265          for block in tail {
   266              match previous {
   267                  Some(previous_block_id) => {
   268                      if block.previous_block_id != previous_block_id {
   269                          return Err(BlockManagerError::MissingPredecessorInBranch(format!(
   270                              "During Put, missing predecessor of block {}: {}",
   271                              block.header_signature, block.previous_block_id
   272                          )));
   273                      }
   274                      previous = Some(block.header_signature.as_str());
   275                  }
   276                  None => {
   277                      if block.previous_block_id != head.header_signature {
   278                          return Err(BlockManagerError::MissingPredecessorInBranch(format!(
   279                              "During Put, missing predecessor of block {}: {}",
   280                              block.previous_block_id, head.header_signature
   281                          )));
   282                      }
   283  
   284                      previous = Some(block.header_signature.as_str());
   285                  }
   286              }
   287          }
   288          Ok(())
   289      }
   290  
   291      /// Put is idempotent, making the guarantee that after put is called with a
   292      /// block in the vector argument, that block is in the BlockManager
   293      /// whether or not it was already in the BlockManager.
   294      /// Put makes three other guarantees
   295      ///     - If the zeroth block in branch does not have its predecessor
   296      ///       in the BlockManager an error is returned
   297      ///     - If any block after the zeroth block in branch
   298      ///       does not have its predecessor as the block to its left in
   299      ///       branch, an error is returned.
   300      ///     - If branch is empty, an error is returned
   301      pub fn put(&mut self, branch: Vec<Block>) -> Result<(), BlockManagerError> {
   302          match branch.split_first() {
   303              Some((head, tail)) => {
   304                  if !self.contains(head.previous_block_id.as_str()) {
   305                      return Err(BlockManagerError::MissingPredecessor(format!(
   306                          "During Put, missing predecessor of block {}: {}",
   307                          head.header_signature, head.previous_block_id
   308                      )));
   309                  }
   310  
   311                  self.check_predecessor_relationship(tail, head)?;
   312  
   313                  match self.block_by_block_id
   314                      .get_mut(head.previous_block_id.as_str())
   315                  {
   316                      Some(ref mut ref_block) => ref_block.increase_internal_ref_count(),
   317                      None => {
   318                          self.anchors
   319                              .increase_internal_ref_count(head.previous_block_id.as_str());
   320                      }
   321                  }
   322              }
   323              None => return Err(BlockManagerError::MissingInput),
   324          }
   325          let blocks_not_added_yet: Vec<Block> = branch
   326              .into_iter()
   327              .filter(|block| !self.contains(block.header_signature.as_str()))
   328              .collect();
   329  
   330          if let Some((last_block, blocks_with_references)) = blocks_not_added_yet.split_last() {
   331              self.block_by_block_id.insert(
   332                  last_block.header_signature.clone(),
   333                  RefBlock::new_unreffed_block(last_block.clone()),
   334              );
   335  
   336              blocks_with_references.into_iter().for_each(|block| {
   337                  self.block_by_block_id.insert(
   338                      block.header_signature.clone(),
   339                      RefBlock::new_reffed_block(block.clone()),
   340                  );
   341              });
   342          };
   343          Ok(())
   344      }
   345  
   346      pub fn get<'a>(&'a self, block_ids: &'a [&'a str]) -> Box<Iterator<Item = &'a Block> + 'a> {
   347          Box::new(GetBlockIterator::new(self, block_ids))
   348      }
   349  
   350      fn get_block_by_block_id(&self, block_id: &str) -> Option<&Block> {
   351          self.block_by_block_id
   352              .get(block_id)
   353              .map(|ref ref_block| &ref_block.block)
   354      }
   355  
   356      fn insert_block_by_block_id(&mut self, block: RefBlock) {
   357          self.block_by_block_id
   358              .insert(block.block.header_signature.clone(), block);
   359      }
   360  
   361      fn get_block_from_main_cache_or_blockstore_name(
   362          &self,
   363          block_id: &str,
   364      ) -> (Option<&Block>, Option<&str>) {
   365          let block = self.get_block_by_block_id(block_id);
   366          if block.is_some() {
   367              (block, None)
   368          } else {
   369              (None, self.anchors.get_blockstore_name(block_id))
   370          }
   371      }
   372  
   373      fn get_block_from_blockstore<'a>(
   374          &'a self,
   375          block_id: String,
   376          store_name: &str,
   377      ) -> Result<Option<&'a Block>, BlockManagerError> {
   378          Ok(self.blockstore_by_name
   379              .get(store_name)
   380              .ok_or(BlockManagerError::UnknownBlockStore)?
   381              .get(vec![block_id])
   382              .nth(0))
   383      }
   384  
   385      fn get_block_from_any_blockstore(&self, block_id: String) -> Option<&Block> {
   386          self.blockstore_by_name
   387              .values()
   388              .find(|blockstore| blockstore.get(vec![block_id.clone()]).count() > 0)
   389              .map(|blockstore| blockstore.get(vec![block_id]).nth(0).unwrap())
   390      }
   391  
   392      pub fn branch<'a>(&'a self, tip: &str) -> Box<Iterator<Item = &Block> + 'a> {
   393          Box::new(BranchIterator::new(self, tip.into()))
   394      }
   395  
   396      pub fn branch_diff<'a>(
   397          &'a self,
   398          tip: &str,
   399          exclude: &str,
   400      ) -> Box<Iterator<Item = &Block> + 'a> {
   401          Box::new(BranchDiffIterator::new(self, tip, exclude))
   402      }
   403  
   404      pub fn ref_block(&mut self, block_id: &str) -> Result<(), BlockManagerError> {
   405          match self.block_by_block_id.get_mut(block_id) {
   406              Some(ref mut ref_block) => {
   407                  ref_block.increase_external_ref_count();
   408                  Ok(())
   409              }
   410              None => {
   411                  if self.anchors.contains(block_id) {
   412                      self.anchors.increase_external_ref_count(block_id);
   413                      Ok(())
   414                  } else {
   415                      Err(BlockManagerError::UnknownBlock)
   416                  }
   417              }
   418          }
   419      }
   420  
   421      /// Starting at a tip block, if the tip block's ref-count drops to 0,
   422      /// remove all blocks until a ref-count of 2 is found.
   423      pub fn unref_block(&mut self, tip: &str) -> Result<(), BlockManagerError> {
   424          let (external_ref_count, internal_ref_count, block_id) =
   425              self.lower_tip_blocks_refcount(tip)?;
   426  
   427          let mut blocks_to_remove = vec![];
   428  
   429          let mut optional_new_tip = None;
   430  
   431          if external_ref_count == 0 && internal_ref_count == 0 {
   432              if let Some(block_id) = block_id {
   433                  let (mut predecesors_to_remove, new_tip) =
   434                      self.find_block_ids_for_blocks_with_refcount_1_or_less(&block_id);
   435                  blocks_to_remove.append(&mut predecesors_to_remove);
   436                  self.block_by_block_id.remove(tip);
   437                  optional_new_tip = new_tip;
   438              }
   439          }
   440  
   441          blocks_to_remove.iter().for_each(|block_id| {
   442              self.block_by_block_id.remove(block_id.as_str());
   443          });
   444  
   445          if let Some(block_id) = optional_new_tip {
   446              if let Some(ref mut new_tip) = self.block_by_block_id.get_mut(block_id.as_str()) {
   447                  new_tip.decrease_internal_ref_count();
   448              };
   449          };
   450  
   451          Ok(())
   452      }
   453  
   454      fn lower_tip_blocks_refcount(
   455          &mut self,
   456          tip: &str,
   457      ) -> Result<(u64, u64, Option<String>), BlockManagerError> {
   458          match self.block_by_block_id.get_mut(tip) {
   459              Some(ref mut ref_block) => {
   460                  if ref_block.external_ref_count > 0 {
   461                      ref_block.decrease_external_ref_count();
   462                  }
   463                  Ok((
   464                      ref_block.external_ref_count,
   465                      ref_block.internal_ref_count,
   466                      Some(ref_block.block.previous_block_id.clone()),
   467                  ))
   468              }
   469              None => {
   470                  if self.anchors.contains(tip) {
   471                      self.anchors.decrease_external_ref_count(tip);
   472  
   473                      Ok((
   474                          self.anchors.get_external_ref_count(tip).unwrap(),
   475                          self.anchors.get_internal_ref_count(tip).unwrap(),
   476                          None,
   477                      ))
   478                  } else {
   479                      Err(BlockManagerError::UnknownBlock)
   480                  }
   481              }
   482          }
   483      }
   484  
   485      /// Starting from some `tip` block_id, walk back until finding a block that has a
   486      /// internal ref_count >= 2 or an external_ref_count > 0.
   487      fn find_block_ids_for_blocks_with_refcount_1_or_less(
   488          &mut self,
   489          tip: &str,
   490      ) -> (Vec<String>, Option<String>) {
   491          let mut blocks_to_remove = vec![];
   492          let mut block_id = tip;
   493          let pointed_to;
   494          loop {
   495              if let Some(ref ref_block) = self.block_by_block_id.get(block_id) {
   496                  if ref_block.internal_ref_count >= 2 || ref_block.external_ref_count >= 1 {
   497                      pointed_to = Some(block_id.into());
   498                      break;
   499                  } else if ref_block.block.previous_block_id == NULL_BLOCK_IDENTIFIER {
   500                      blocks_to_remove.push(block_id.into());
   501                      pointed_to = None;
   502                      break;
   503                  } else {
   504                      blocks_to_remove.push(block_id.into());
   505                  }
   506                  block_id = &ref_block.block.previous_block_id;
   507              } else {
   508                  self.anchors.decrease_internal_ref_count(block_id);
   509                  pointed_to = None;
   510                  break;
   511              }
   512          }
   513          (blocks_to_remove, pointed_to)
   514      }
   515  
   516      pub fn add_store(
   517          &mut self,
   518          store_name: &str,
   519          store: Box<BlockStore>,
   520      ) -> Result<(), BlockManagerError> {
   521          self.blockstore_by_name.insert(store_name.into(), store);
   522          Ok(())
   523      }
   524  
   525      fn remove_blocks_from_blockstore(
   526          &mut self,
   527          head: &str,
   528          other: &str,
   529          store_name: &str,
   530      ) -> Result<(), BlockManagerError> {
   531          let to_be_removed: Vec<Block> = self.branch_diff(other, head).cloned().collect();
   532  
   533          {
   534              let blockstore = self.blockstore_by_name
   535                  .get_mut(store_name)
   536                  .ok_or(BlockManagerError::UnknownBlockStore)?;
   537  
   538              blockstore.delete(
   539                  to_be_removed
   540                      .iter()
   541                      .map(|b| b.header_signature.clone())
   542                      .collect(),
   543              )?;
   544          }
   545  
   546          let (have_anchors, no_anchors) = to_be_removed
   547              .into_iter()
   548              .partition(|b| self.anchors.contains(b.header_signature.as_str()));
   549  
   550          for ref_block in self.anchors.convert(have_anchors) {
   551              self.insert_block_by_block_id(ref_block);
   552          }
   553  
   554          for block in no_anchors {
   555              self.insert_block_by_block_id(RefBlock::new_reffed_block(block));
   556          }
   557  
   558          Ok(())
   559      }
   560  
   561      fn insert_blocks_in_blockstore(
   562          &mut self,
   563          head: &str,
   564          other: &str,
   565          store_name: &str,
   566      ) -> Result<(), BlockManagerError> {
   567          let to_be_inserted: Vec<Block> = self.branch_diff(head, other).cloned().collect();
   568  
   569          let block_by_block_id = &self.block_by_block_id;
   570          if let Some((head, tail)) = to_be_inserted.split_first() {
   571              let ref_block = block_by_block_id
   572                  .get(head.header_signature.as_str())
   573                  .expect("A block that is being inserted in the blockstore will already be in the main cache.");
   574  
   575              self.anchors.add_anchor(
   576                  head.header_signature.as_str(),
   577                  store_name,
   578                  head.block_num,
   579                  ref_block.external_ref_count,
   580                  ref_block.internal_ref_count,
   581              );
   582  
   583              for block in tail {
   584                  let ref_block = block_by_block_id
   585                      .get(block.header_signature.as_str())
   586                      .expect("A block that is being inserted in the blockstore will already be in the main cache.");
   587                  if ref_block.external_ref_count > 0 || ref_block.internal_ref_count > 0 {
   588                      self.anchors.add_anchor(
   589                          block.header_signature.as_str(),
   590                          store_name,
   591                          block.block_num,
   592                          ref_block.external_ref_count,
   593                          ref_block.internal_ref_count,
   594                      );
   595                  }
   596              }
   597          }
   598  
   599          let blockstore = self.blockstore_by_name
   600              .get_mut(store_name)
   601              .ok_or(BlockManagerError::UnknownBlockStore)?;
   602          blockstore.put(to_be_inserted)?;
   603          Ok(())
   604      }
   605  
   606      pub fn persist(&mut self, head: &str, store_name: &str) -> Result<(), BlockManagerError> {
   607          if !self.blockstore_by_name.contains_key(store_name) {
   608              return Err(BlockManagerError::UnknownBlockStore);
   609          }
   610  
   611          let head_block_in_blockstore = self.anchors
   612              .iter_by_blockstore(store_name)
   613              .max_by_key(|anchor| anchor.block_num)
   614              .map(|anchor| anchor.block_id.clone());
   615  
   616          if let Some(head_block_in_blockstore) = head_block_in_blockstore {
   617              let other = head_block_in_blockstore.as_str();
   618  
   619              self.remove_blocks_from_blockstore(head, other, store_name)?;
   620  
   621              self.insert_blocks_in_blockstore(head, other, store_name)?;
   622          } else {
   623              // There are no other blocks in the blockstore and so
   624              // we would like to insert all of the blocks
   625              self.insert_blocks_in_blockstore(head, "NULL", store_name)?;
   626          }
   627  
   628          Ok(())
   629      }
   630  }
   631  
   632  struct GetBlockIterator<'a> {
   633      block_manager: &'a BlockManager,
   634      block_ids: &'a [&'a str],
   635      index: usize,
   636  }
   637  
   638  impl<'a> GetBlockIterator<'a> {
   639      pub fn new(block_manager: &'a BlockManager, block_ids: &'a [&'a str]) -> Self {
   640          GetBlockIterator {
   641              block_manager,
   642              block_ids,
   643              index: 0,
   644          }
   645      }
   646  }
   647  
   648  impl<'a> Iterator for GetBlockIterator<'a> {
   649      type Item = &'a Block;
   650  
   651      fn next(&mut self) -> Option<Self::Item> {
   652          let block = match self.block_ids.get(self.index) {
   653              Some(block_id) => {
   654                  let (optional_block, optional_blockstore_name) = self.block_manager
   655                      .get_block_from_main_cache_or_blockstore_name(block_id);
   656                  match optional_block {
   657                      Some(block) => Some(block),
   658                      None => {
   659                          if let Some(blockstore_name) = optional_blockstore_name {
   660                              self.block_manager
   661                                  .get_block_from_blockstore((*block_id).into(), blockstore_name)
   662                                  .expect("An anchor pointed to a blockstore that does not exist")
   663                          } else {
   664                              self.block_manager
   665                                  .get_block_from_any_blockstore((*block_id).into())
   666                          }
   667                      }
   668                  }
   669              }
   670              None => None,
   671          };
   672          self.index += 1;
   673          block
   674      }
   675  }
   676  
   677  struct BranchIterator<'a> {
   678      block_manager: &'a BlockManager,
   679      next_block_id: String,
   680      blockstore: Option<String>,
   681  }
   682  
   683  impl<'a> BranchIterator<'a> {
   684      pub fn new(block_manager: &'a BlockManager, first_block_id: String) -> Self {
   685          BranchIterator {
   686              block_manager,
   687              next_block_id: first_block_id,
   688              blockstore: None,
   689          }
   690      }
   691  }
   692  
   693  impl<'a> Iterator for BranchIterator<'a> {
   694      type Item = &'a Block;
   695  
   696      fn next(&mut self) -> Option<Self::Item> {
   697          if self.next_block_id == NULL_BLOCK_IDENTIFIER {
   698              None
   699          } else if self.blockstore.is_none() {
   700              let (block_option, blockstore_name_option) = self.block_manager
   701                  .get_block_from_main_cache_or_blockstore_name(self.next_block_id.as_str());
   702              let block = block_option.or_else(|| {
   703                  blockstore_name_option
   704                      .map(|blockstore_name| {
   705                          self.blockstore = Some(blockstore_name.into());
   706                          self.block_manager
   707                              .get_block_from_blockstore(self.next_block_id.clone(), blockstore_name)
   708                              .expect("Blockstore referenced by anchor does not exist")
   709                      })
   710                      .unwrap_or(None)
   711              });
   712              if let Some(block) = block {
   713                  self.next_block_id = block.previous_block_id.clone();
   714              }
   715              block
   716          } else {
   717              let blockstore_id = self.blockstore.as_ref().unwrap();
   718              let block = self.block_manager
   719                  .get_block_from_blockstore(self.next_block_id.clone(), blockstore_id)
   720                  .expect("The Blockmanager has lost a blockstore that is referenced by an anchor")
   721                  .expect(
   722                      "The block was not in the blockstore referenced by a successor block's anchor",
   723                  );
   724              Some(block)
   725          }
   726      }
   727  }
   728  
   729  struct BranchDiffIterator<'a> {
   730      block_manager: &'a BlockManager,
   731  
   732      left_block: Option<&'a Block>,
   733      right_block: Option<&'a Block>,
   734  
   735      blockstore: Option<String>,
   736  
   737      has_reached_common_ancestor: bool,
   738  }
   739  
   740  impl<'a> BranchDiffIterator<'a> {
   741      fn new(block_manager: &'a BlockManager, tip: &str, exclude: &str) -> Self {
   742          let mut iterator = BranchDiffIterator {
   743              block_manager,
   744              left_block: None,
   745              right_block: None,
   746  
   747              blockstore: None,
   748              has_reached_common_ancestor: false,
   749          };
   750  
   751          iterator.left_block = iterator.get_block_by_block_id(tip.into());
   752          iterator.right_block = iterator.get_block_by_block_id(exclude.into());
   753  
   754          if let Some(left) = iterator.left_block {
   755              if let Some(right) = iterator.right_block {
   756                  let difference = iterator.block_num_difference(left, right);
   757                  if difference < 0 {
   758                      iterator.right_block = iterator.get_nth_previous_block(
   759                          right.header_signature.clone(),
   760                          difference.abs() as u64,
   761                      );
   762                  }
   763              }
   764          }
   765  
   766          iterator
   767      }
   768  
   769      fn block_num_difference(&self, left: &Block, right: &Block) -> i64 {
   770          left.block_num as i64 - right.block_num as i64
   771      }
   772  
   773      fn get_previous_block(&mut self, block_id: String) -> Option<&'a Block> {
   774          let block = self.get_block_by_block_id(block_id);
   775          block
   776              .map(|b| self.get_block_by_block_id(b.previous_block_id.clone()))
   777              .unwrap_or(None)
   778      }
   779  
   780      fn get_nth_previous_block(&mut self, block_id: String, n: u64) -> Option<&'a Block> {
   781          if n == 0 {
   782              return None;
   783          }
   784  
   785          let mut current_block_id = block_id;
   786  
   787          let mut block = self.get_previous_block(current_block_id.clone());
   788          if let Some(b) = block {
   789              current_block_id = b.header_signature.clone();
   790          }
   791  
   792          for _ in 1..n {
   793              block = self.get_previous_block(current_block_id.clone());
   794              if let Some(b) = block {
   795                  current_block_id = b.header_signature.clone();
   796              }
   797          }
   798          block
   799      }
   800  
   801      fn get_block_by_block_id(&mut self, block_id: String) -> Option<&'a Block> {
   802          if block_id == NULL_BLOCK_IDENTIFIER {
   803              None
   804          } else if self.blockstore.is_none() {
   805              let (block_option, blockstore_name_option) = self.block_manager
   806                  .get_block_from_main_cache_or_blockstore_name(block_id.as_str());
   807              block_option.or_else(|| {
   808                  blockstore_name_option
   809                      .map(|blockstore_name| {
   810                          self.blockstore = Some(blockstore_name.into());
   811                          self.block_manager
   812                              .get_block_from_blockstore(block_id, blockstore_name)
   813                              .expect("Blockstore referenced by anchor does not exist")
   814                      })
   815                      .unwrap_or(None)
   816              })
   817          } else {
   818              let blockstore_id = self.blockstore.as_ref().unwrap();
   819              let block = self.block_manager
   820                  .get_block_from_blockstore(block_id.clone(), blockstore_id)
   821                  .expect("The Blockmanager has lost a blockstore that is referenced by an anchor")
   822                  .expect(
   823                      "The block was not in the blockstore referenced by a successor block's anchor",
   824                  );
   825              Some(block)
   826          }
   827      }
   828  }
   829  
   830  impl<'a> Iterator for BranchDiffIterator<'a> {
   831      type Item = &'a Block;
   832  
   833      fn next(&mut self) -> Option<Self::Item> {
   834          if self.has_reached_common_ancestor {
   835              None
   836          } else if let Some(left) = self.left_block {
   837              if let Some(right) = self.right_block {
   838                  if left.header_signature == NULL_BLOCK_IDENTIFIER {
   839                      return None;
   840                  }
   841                  if left.header_signature == right.header_signature
   842                      && left.block_num == right.block_num
   843                  {
   844                      self.has_reached_common_ancestor = true;
   845                      return None;
   846                  }
   847                  let difference = self.block_num_difference(left, right);
   848                  if difference > 0 {
   849                      self.left_block = self.get_previous_block(left.header_signature.clone());
   850                  } else {
   851                      self.left_block = self.get_previous_block(left.header_signature.clone());
   852                      self.right_block = self.get_previous_block(right.header_signature.clone());
   853                  }
   854                  Some(left)
   855              } else {
   856                  self.left_block = self.get_previous_block(left.header_signature.clone());
   857                  Some(left)
   858              }
   859          } else {
   860              None
   861          }
   862      }
   863  }
   864  
   865  #[cfg(test)]
   866  mod tests {
   867  
   868      use super::{BlockManager, BlockManagerError};
   869      use block::Block;
   870      use journal::block_store::InMemoryBlockStore;
   871      use journal::NULL_BLOCK_IDENTIFIER;
   872  
   873      fn create_block(header_signature: &str, previous_block_id: &str, block_num: u64) -> Block {
   874          Block {
   875              header_signature: header_signature.into(),
   876              batches: vec![],
   877              state_root_hash: "".into(),
   878              consensus: vec![],
   879              batch_ids: vec![],
   880              signer_public_key: "".into(),
   881              previous_block_id: previous_block_id.into(),
   882              block_num,
   883              header_bytes: vec![],
   884          }
   885      }
   886  
   887      #[test]
   888      fn test_put_ref_then_unref() {
   889          let a = create_block("A", NULL_BLOCK_IDENTIFIER, 0);
   890          let b = create_block("B", "A", 1);
   891          let b_block_id = b.header_signature.clone();
   892          let c = create_block("C", "B", 2);
   893          let c_block_id = c.header_signature.clone();
   894  
   895          let mut block_manager = BlockManager::new();
   896          assert_eq!(block_manager.put(vec![a, b]), Ok(()));
   897  
   898          assert_eq!(block_manager.put(vec![c]), Ok(()));
   899  
   900          block_manager.ref_block(b_block_id.as_str()).unwrap();
   901          block_manager.unref_block(c_block_id.as_str()).unwrap();
   902  
   903          let d = create_block("D", "C", 3);
   904  
   905          assert_eq!(
   906              block_manager.put(vec![d]),
   907              Err(BlockManagerError::MissingPredecessor(format!(
   908                  "During Put, missing predecessor of block D: C"
   909              )))
   910          );
   911  
   912          let e = create_block("E", "B", 2);
   913  
   914          block_manager.put(vec![e]).unwrap();
   915      }
   916  
   917      #[test]
   918      fn test_multiple_branches_put_ref_then_unref() {
   919          let a = create_block("A", NULL_BLOCK_IDENTIFIER, 0);
   920          let b = create_block("B", "A", 1);
   921          let c = create_block("C", "B", 2);
   922          let c_block_id = &c.header_signature.clone();
   923          let d = create_block("D", "C", 3);
   924          let d_block_id = &d.header_signature.clone();
   925          let e = create_block("E", "C", 3);
   926  
   927          let f = create_block("F", "E", 4);
   928          let f_block_id = &f.header_signature.clone();
   929  
   930          let mut block_manager = BlockManager::new();
   931          block_manager.put(vec![a.clone(), b, c]).unwrap();
   932          block_manager.put(vec![d]).unwrap();
   933          block_manager.put(vec![e, f]).unwrap();
   934  
   935          block_manager.unref_block(d_block_id).unwrap();
   936  
   937          block_manager.unref_block(f_block_id).unwrap();
   938  
   939          let q = create_block("Q", "C", 3);
   940          let q_block_id = &q.header_signature.clone();
   941          block_manager.put(vec![q]).unwrap();
   942          block_manager.unref_block(c_block_id).unwrap();
   943          block_manager.unref_block(q_block_id).unwrap();
   944  
   945          let g = create_block("G", "A", 1);
   946          assert_eq!(
   947              block_manager.put(vec![g]),
   948              Err(BlockManagerError::MissingPredecessor(format!(
   949                  "During Put, missing predecessor of block G: A"
   950              )))
   951          );
   952      }
   953  
   954      #[test]
   955      fn test_put_empty_vec() {
   956          let mut block_manager = BlockManager::new();
   957          assert_eq!(
   958              block_manager.put(vec![]),
   959              Err(BlockManagerError::MissingInput)
   960          );
   961      }
   962  
   963      #[test]
   964      fn test_put_missing_predecessor() {
   965          let mut block_manager = BlockManager::new();
   966          let a = create_block("A", "o", 54);
   967          let b = create_block("B", "A", 55);
   968          assert_eq!(
   969              block_manager.put(vec![a, b]),
   970              Err(BlockManagerError::MissingPredecessor(format!(
   971                  "During Put, missing predecessor of block A: o"
   972              )))
   973          );
   974      }
   975  
   976      #[test]
   977      fn test_get_blocks() {
   978          let mut block_manager = BlockManager::new();
   979          let a = create_block("A", NULL_BLOCK_IDENTIFIER, 0);
   980          let b = create_block("B", "A", 1);
   981          let c = create_block("C", "B", 2);
   982  
   983          block_manager
   984              .put(vec![a.clone(), b.clone(), c.clone()])
   985              .unwrap();
   986  
   987          let mut get_block_iter = block_manager.get(&["A", "C", "D"]);
   988  
   989          assert_eq!(get_block_iter.next(), Some(&a));
   990          assert_eq!(get_block_iter.next(), Some(&c));
   991          assert_eq!(get_block_iter.next(), None);
   992          assert_eq!(get_block_iter.next(), None);
   993      }
   994  
   995      #[test]
   996      fn test_branch_in_memory() {
   997          let mut block_manager = BlockManager::new();
   998          let a = create_block("A", NULL_BLOCK_IDENTIFIER, 0);
   999          let b = create_block("B", "A", 1);
  1000          let c = create_block("C", "B", 2);
  1001  
  1002          block_manager
  1003              .put(vec![a.clone(), b.clone(), c.clone()])
  1004              .unwrap();
  1005  
  1006          let mut branch_iter = block_manager.branch("C");
  1007  
  1008          assert_eq!(branch_iter.next(), Some(&c));
  1009          assert_eq!(branch_iter.next(), Some(&b));
  1010          assert_eq!(branch_iter.next(), Some(&a));
  1011          assert_eq!(branch_iter.next(), None);
  1012  
  1013          let mut empty_iter = block_manager.branch("P");
  1014  
  1015          assert_eq!(empty_iter.next(), None);
  1016      }
  1017  
  1018      #[test]
  1019      fn test_branch_diff() {
  1020          let mut block_manager = BlockManager::new();
  1021  
  1022          let a = create_block("A", NULL_BLOCK_IDENTIFIER, 0);
  1023          let b = create_block("B", "A", 1);
  1024          let c = create_block("C", "A", 1);
  1025          let d = create_block("D", "C", 2);
  1026          let e = create_block("E", "D", 3);
  1027  
  1028          block_manager.put(vec![a.clone(), b.clone()]).unwrap();
  1029          block_manager.put(vec![c.clone()]).unwrap();
  1030          block_manager.put(vec![d.clone(), e.clone()]).unwrap();
  1031  
  1032          let mut branch_diff_iter = block_manager.branch_diff("C", "B");
  1033  
  1034          assert_eq!(branch_diff_iter.next(), Some(&c));
  1035          assert_eq!(branch_diff_iter.next(), None);
  1036  
  1037          let mut branch_diff_iter2 = block_manager.branch_diff("B", "E");
  1038  
  1039          assert_eq!(branch_diff_iter2.next(), Some(&b));
  1040          assert_eq!(branch_diff_iter2.next(), None);
  1041  
  1042          let mut branch_diff_iter3 = block_manager.branch_diff("C", "E");
  1043  
  1044          assert_eq!(branch_diff_iter3.next(), None);
  1045  
  1046          let mut branch_diff_iter4 = block_manager.branch_diff("E", "C");
  1047  
  1048          assert_eq!(branch_diff_iter4.next(), Some(&e));
  1049          assert_eq!(branch_diff_iter4.next(), Some(&d));
  1050          assert_eq!(branch_diff_iter4.next(), None);
  1051      }
  1052  
  1053      #[test]
  1054      fn test_persist_ref_unref() {
  1055          let mut block_manager = BlockManager::new();
  1056  
  1057          let a = create_block("A", NULL_BLOCK_IDENTIFIER, 0);
  1058          let b = create_block("B", "A", 1);
  1059          let c = create_block("C", "A", 1);
  1060          let d = create_block("D", "C", 2);
  1061          let e = create_block("E", "D", 3);
  1062          let f = create_block("F", "C", 2);
  1063  
  1064          let q = create_block("Q", "F", 3);
  1065          let p = create_block("P", "E", 4);
  1066  
  1067          block_manager.put(vec![a.clone(), b.clone()]).unwrap();
  1068          block_manager
  1069              .put(vec![c.clone(), d.clone(), e.clone()])
  1070              .unwrap();
  1071          block_manager.put(vec![f.clone()]).unwrap();
  1072  
  1073          let blockstore = Box::new(InMemoryBlockStore::new());
  1074          block_manager.add_store("commit", blockstore).unwrap();
  1075  
  1076          block_manager.persist("C", "commit").unwrap();
  1077          block_manager.persist("B", "commit").unwrap();
  1078  
  1079          block_manager.ref_block("D").unwrap();
  1080  
  1081          block_manager.persist("C", "commit").unwrap();
  1082          block_manager.unref_block("B").unwrap();
  1083  
  1084          block_manager.persist("F", "commit").unwrap();
  1085          block_manager.persist("E", "commit").unwrap();
  1086  
  1087          block_manager.unref_block("F").unwrap();
  1088          block_manager.unref_block("D").unwrap();
  1089  
  1090          block_manager.persist("A", "commit").unwrap();
  1091  
  1092          block_manager.unref_block("E").unwrap();
  1093  
  1094          assert_eq!(
  1095              block_manager.put(vec![q]),
  1096              Err(BlockManagerError::MissingPredecessor(format!(
  1097                  "During Put, missing predecessor of block Q: F"
  1098              )))
  1099          );
  1100  
  1101          assert_eq!(
  1102              block_manager.put(vec![p]),
  1103              Err(BlockManagerError::MissingPredecessor(format!(
  1104                  "During Put, missing predecessor of block P: E"
  1105              )))
  1106          );
  1107      }
  1108  }