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 }