github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/state/merkle.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::BTreeMap; 19 use std::collections::HashMap; 20 use std::collections::HashSet; 21 use std::collections::VecDeque; 22 use std::io::Cursor; 23 24 use cbor; 25 use cbor::decoder::GenericDecoder; 26 use cbor::encoder::GenericEncoder; 27 use cbor::value::Bytes; 28 use cbor::value::Key; 29 use cbor::value::Text; 30 use cbor::value::Value; 31 32 use crypto::digest::Digest; 33 use crypto::sha2::Sha512; 34 35 use protobuf; 36 use protobuf::Message; 37 38 use database::database::DatabaseError; 39 use database::lmdb::DatabaseReader; 40 use database::lmdb::LmdbDatabase; 41 use database::lmdb::LmdbDatabaseWriter; 42 43 use proto::merkle::ChangeLogEntry; 44 use proto::merkle::ChangeLogEntry_Successor; 45 46 use state::error::StateDatabaseError; 47 use state::StateReader; 48 49 const TOKEN_SIZE: usize = 2; 50 51 pub const CHANGE_LOG_INDEX: &str = "change_log"; 52 pub const DUPLICATE_LOG_INDEX: &str = "duplicate_log"; 53 pub const INDEXES: [&'static str; 2] = [CHANGE_LOG_INDEX, DUPLICATE_LOG_INDEX]; 54 55 /// Merkle Database 56 #[derive(Clone)] 57 pub struct MerkleDatabase { 58 root_hash: String, 59 db: LmdbDatabase, 60 root_node: Node, 61 } 62 63 impl MerkleDatabase { 64 /// Constructs a new MerkleDatabase, backed by a given Database 65 /// 66 /// An optional starting merkle root may be provided. 67 pub fn new(db: LmdbDatabase, merkle_root: Option<&str>) -> Result<Self, StateDatabaseError> { 68 let root_hash = merkle_root.map_or_else(|| initialize_db(&db), |s| Ok(s.into()))?; 69 let root_node = get_node_by_hash(&db, &root_hash)?; 70 71 Ok(MerkleDatabase { 72 root_hash, 73 root_node, 74 db, 75 }) 76 } 77 78 /// Prunes nodes that are no longer needed under a given state root 79 /// Returns a list of addresses that were deleted 80 pub fn prune(db: &LmdbDatabase, merkle_root: &str) -> Result<Vec<String>, StateDatabaseError> { 81 let root_bytes = ::hex::decode(merkle_root).map_err(|_| { 82 StateDatabaseError::InvalidHash(format!("{} is not a valid hash", merkle_root)) 83 })?; 84 let mut db_writer = db.writer()?; 85 let change_log = get_change_log(&db_writer, &root_bytes)?; 86 87 if change_log.is_none() { 88 // There's no change log for this entry 89 return Ok(vec![]); 90 } 91 92 let mut change_log = change_log.unwrap(); 93 let removed_addresses = if change_log.get_successors().len() > 1 { 94 // Currently, we don't clean up a parent with multiple successors 95 vec![] 96 } else if change_log.get_successors().len() == 0 { 97 // deleting the tip of a trie lineage 98 99 let (deletion_candidates, duplicates): (Vec<Vec<u8>>, Vec<Vec<u8>>) = 100 MerkleDatabase::remove_duplicate_hashes( 101 &mut db_writer, 102 change_log.take_additions(), 103 )?; 104 105 for hash in deletion_candidates.iter() { 106 let hash_hex = ::hex::encode(hash); 107 delete_ignore_missing(&mut db_writer, hash_hex.as_bytes())? 108 } 109 110 for hash in duplicates.iter() { 111 decrement_ref_count(&mut db_writer, hash)?; 112 } 113 114 db_writer.index_delete(CHANGE_LOG_INDEX, &root_bytes)?; 115 let parent_root_bytes = &change_log.get_parent(); 116 117 if let Some(ref mut parent_change_log) = 118 get_change_log(&db_writer, parent_root_bytes)?.as_mut() 119 { 120 let successors = parent_change_log.take_successors(); 121 let new_successors = successors 122 .into_iter() 123 .filter(|successor| root_bytes != successor.get_successor()) 124 .collect::<Vec<_>>(); 125 parent_change_log.set_successors(protobuf::RepeatedField::from_vec(new_successors)); 126 127 write_change_log(&mut db_writer, parent_root_bytes, &parent_change_log)?; 128 } 129 130 deletion_candidates.into_iter().collect() 131 } else { 132 // deleting a parent 133 let mut successor = change_log.take_successors().pop().unwrap(); 134 135 let (deletion_candidates, duplicates): (Vec<Vec<u8>>, Vec<Vec<u8>>) = 136 MerkleDatabase::remove_duplicate_hashes( 137 &mut db_writer, 138 successor.take_deletions(), 139 )?; 140 141 for hash in deletion_candidates.iter() { 142 let hash_hex = ::hex::encode(hash); 143 delete_ignore_missing(&mut db_writer, hash_hex.as_bytes())? 144 } 145 146 for hash in duplicates.iter() { 147 decrement_ref_count(&mut db_writer, hash)?; 148 } 149 150 db_writer.index_delete(CHANGE_LOG_INDEX, &root_bytes)?; 151 152 deletion_candidates.into_iter().collect() 153 }; 154 155 db_writer.commit()?; 156 Ok(removed_addresses.iter().map(::hex::encode).collect()) 157 } 158 159 fn remove_duplicate_hashes( 160 db_writer: &mut LmdbDatabaseWriter, 161 deletions: protobuf::RepeatedField<Vec<u8>>, 162 ) -> Result<(Vec<Vec<u8>>, Vec<Vec<u8>>), StateDatabaseError> { 163 let (deletion_candidates, decrements): (Vec<Vec<u8>>, Vec<Vec<u8>>) = 164 deletions.into_iter().partition(|key| { 165 if let Ok(count) = get_ref_count(db_writer, &key) { 166 count == 0 167 } else { 168 false 169 } 170 }); 171 172 Ok((deletion_candidates, decrements)) 173 } 174 175 /// Returns the current merkle root for this MerkleDatabase 176 pub fn get_merkle_root(&self) -> String { 177 self.root_hash.clone() 178 } 179 180 /// Sets the current merkle root for this MerkleDatabase 181 pub fn set_merkle_root<S: Into<String>>( 182 &mut self, 183 merkle_root: S, 184 ) -> Result<(), StateDatabaseError> { 185 let new_root = merkle_root.into(); 186 self.root_node = get_node_by_hash(&self.db, &new_root)?; 187 self.root_hash = new_root; 188 Ok(()) 189 } 190 191 /// Sets the given data at the given address. 192 /// 193 /// Returns a Result with the new merkle root hash, or an error if the 194 /// address is not in the tree. 195 /// 196 /// Note, continued calls to get, without changing the merkle root to the 197 /// result of this function, will not retrieve the results provided here. 198 pub fn set(&self, address: &str, data: &[u8]) -> Result<String, StateDatabaseError> { 199 let mut updates = HashMap::with_capacity(1); 200 updates.insert(address.to_string(), data.to_vec()); 201 self.update(&updates, &[], false) 202 } 203 204 /// Deletes the value at the given address. 205 /// 206 /// Returns a Result with the new merkle root hash, or an error if the 207 /// address is not in the tree. 208 /// 209 /// Note, continued calls to get, without changing the merkle root to the 210 /// result of this function, will still retrieve the data at the address 211 /// provided 212 pub fn delete(&self, address: &str) -> Result<String, StateDatabaseError> { 213 self.update(&HashMap::with_capacity(0), &[address.to_string()], false) 214 } 215 216 /// Updates the tree with multiple changes. Applies both set and deletes, 217 /// as given. 218 /// 219 /// If the flag `is_virtual` is set, the values are not written to the 220 /// underlying database. 221 /// 222 /// Returns a Result with the new root hash. 223 pub fn update( 224 &self, 225 set_items: &HashMap<String, Vec<u8>>, 226 delete_items: &[String], 227 is_virtual: bool, 228 ) -> Result<String, StateDatabaseError> { 229 let mut path_map = HashMap::new(); 230 231 let mut deletions = HashSet::new(); 232 233 for (set_address, set_value) in set_items { 234 let tokens = tokenize_address(set_address); 235 let mut set_path_map = self.get_path_by_tokens(&tokens, false)?; 236 237 { 238 let node = set_path_map 239 .get_mut(set_address) 240 .expect("Path map not correctly generated"); 241 node.value = Some(set_value.to_vec()); 242 } 243 path_map.extend(set_path_map); 244 } 245 246 for del_address in delete_items.iter() { 247 let tokens = tokenize_address(del_address); 248 let del_path_map = self.get_path_by_tokens(&tokens, true)?; 249 path_map.extend(del_path_map); 250 } 251 252 for del_address in delete_items.iter() { 253 path_map.remove(del_address); 254 let (mut parent_address, mut path_branch) = parent_and_branch(del_address); 255 while parent_address != "" { 256 let remove_parent = { 257 let parent_node = path_map 258 .get_mut(parent_address) 259 .expect("Path map not correctly generated"); 260 261 if let Some(old_hash_key) = parent_node.children.remove(path_branch) { 262 deletions.insert(old_hash_key); 263 } 264 265 parent_node.children.is_empty() 266 }; 267 268 if remove_parent { 269 // empty node delete it. 270 path_map.remove(parent_address); 271 } else { 272 // found a node that is not empty no need to continue 273 break; 274 } 275 276 let (next_parent, next_branch) = parent_and_branch(parent_address); 277 parent_address = next_parent; 278 path_branch = next_branch; 279 280 if parent_address == "" { 281 let parent_node = path_map 282 .get_mut(parent_address) 283 .expect("Path map not correctly generated"); 284 285 if let Some(old_hash_key) = parent_node.children.remove(path_branch) { 286 deletions.insert(old_hash_key); 287 } 288 } 289 } 290 } 291 292 let mut sorted_paths: Vec<_> = path_map.keys().cloned().collect(); 293 // Sort by longest to shortest 294 sorted_paths.sort_by(|a, b| b.len().cmp(&a.len())); 295 296 // initializing this to empty, to make the compiler happy 297 let mut key_hash = Vec::with_capacity(0); 298 let mut batch = Vec::with_capacity(sorted_paths.len()); 299 for path in sorted_paths { 300 let node = path_map 301 .remove(&path) 302 .expect("Path map keys are out of sink"); 303 let (hash_key, packed) = encode_and_hash(node)?; 304 key_hash = hash_key.clone(); 305 306 if path != "" { 307 let (parent_address, path_branch) = parent_and_branch(&path); 308 let mut parent = path_map 309 .get_mut(parent_address) 310 .expect("Path map not correctly generated"); 311 if let Some(old_hash_key) = parent 312 .children 313 .insert(path_branch.to_string(), ::hex::encode(hash_key.clone())) 314 { 315 deletions.insert(old_hash_key); 316 } 317 } 318 319 batch.push((hash_key, packed)); 320 } 321 322 if !is_virtual { 323 let deletions: Vec<Vec<u8>> = deletions 324 .iter() 325 // We expect this to be hex, since we generated it 326 .map(|s| ::hex::decode(s).expect("Improper hex")) 327 .collect(); 328 self.store_changes(&key_hash, &batch, &deletions)?; 329 } 330 331 Ok(::hex::encode(key_hash)) 332 } 333 334 /// Puts all the items into the database. 335 fn store_changes( 336 &self, 337 successor_root_hash: &[u8], 338 batch: &[(Vec<u8>, Vec<u8>)], 339 deletions: &[Vec<u8>], 340 ) -> Result<(), StateDatabaseError> { 341 let mut db_writer = self.db.writer()?; 342 343 // We expect this to be hex, since we generated it 344 let root_hash_bytes = ::hex::decode(&self.root_hash).expect("Improper hex"); 345 346 for &(ref key, ref value) in batch { 347 match db_writer.put(::hex::encode(key).as_bytes(), &value) { 348 Ok(_) => continue, 349 Err(DatabaseError::DuplicateEntry) => { 350 increment_ref_count(&mut db_writer, key); 351 } 352 Err(err) => return Err(StateDatabaseError::from(err)), 353 } 354 } 355 356 let mut current_change_log = get_change_log(&db_writer, &root_hash_bytes)?; 357 if let Some(change_log) = current_change_log.as_mut() { 358 let mut successors = change_log.mut_successors(); 359 let mut successor = ChangeLogEntry_Successor::new(); 360 successor.set_successor(Vec::from(successor_root_hash)); 361 successor.set_deletions(protobuf::RepeatedField::from_slice(deletions)); 362 successors.push(successor); 363 } 364 365 let mut next_change_log = ChangeLogEntry::new(); 366 next_change_log.set_parent(root_hash_bytes.clone()); 367 next_change_log.set_additions(protobuf::RepeatedField::from( 368 batch 369 .iter() 370 .map(|&(ref hash, _)| hash.clone()) 371 .collect::<Vec<Vec<u8>>>(), 372 )); 373 374 if current_change_log.is_some() { 375 write_change_log( 376 &mut db_writer, 377 &root_hash_bytes, 378 ¤t_change_log.unwrap(), 379 )?; 380 } 381 write_change_log(&mut db_writer, successor_root_hash, &next_change_log)?; 382 383 db_writer.commit()?; 384 Ok(()) 385 } 386 387 fn get_by_address(&self, address: &str) -> Result<Node, StateDatabaseError> { 388 let tokens = tokenize_address(address); 389 390 // There's probably a better way to do this than a clone 391 let mut node = self.root_node.clone(); 392 393 for token in tokens.iter() { 394 node = match node.children.get(&token.to_string()) { 395 None => { 396 return Err(StateDatabaseError::NotFound(format!( 397 "invalid address {} from root {}", 398 address, self.root_hash 399 ))) 400 } 401 Some(child_hash) => get_node_by_hash(&self.db, child_hash)?, 402 } 403 } 404 Ok(node) 405 } 406 407 fn get_path_by_tokens( 408 &self, 409 tokens: &[&str], 410 strict: bool, 411 ) -> Result<HashMap<String, Node>, StateDatabaseError> { 412 let mut nodes = HashMap::new(); 413 414 let mut path = String::new(); 415 nodes.insert(path.clone(), self.root_node.clone()); 416 417 let mut new_branch = false; 418 419 for token in tokens { 420 let node = { 421 // this is safe to unwrap, because we've just inserted the path in the previous loop 422 let child_address = &nodes[&path].children.get(&token.to_string()); 423 if !new_branch && child_address.is_some() { 424 get_node_by_hash(&self.db, child_address.unwrap())? 425 } else { 426 if strict { 427 return Err(StateDatabaseError::NotFound(format!( 428 "invalid address {} from root {}", 429 tokens.join(""), 430 self.root_hash 431 ))); 432 } else { 433 new_branch = true; 434 Node::default() 435 } 436 } 437 }; 438 439 path.push_str(token); 440 nodes.insert(path.clone(), node); 441 } 442 Ok(nodes) 443 } 444 } 445 446 impl StateReader for MerkleDatabase { 447 /// Returns true if the given address exists in the MerkleDatabase; 448 /// false, otherwise. 449 fn contains(&self, address: &str) -> Result<bool, StateDatabaseError> { 450 match self.get_by_address(address) { 451 Ok(_) => Ok(true), 452 Err(StateDatabaseError::NotFound(_)) => Ok(false), 453 Err(err) => Err(err), 454 } 455 } 456 457 /// Returns the data for a given address, if they exist at that node. If 458 /// not, returns None. Will return an StateDatabaseError::NotFound, if the 459 /// given address is not in the tree 460 fn get(&self, address: &str) -> Result<Option<Vec<u8>>, StateDatabaseError> { 461 Ok(self.get_by_address(address)?.value) 462 } 463 464 fn leaves( 465 &self, 466 prefix: Option<&str>, 467 ) -> Result< 468 Box<Iterator<Item = Result<(String, Vec<u8>), StateDatabaseError>>>, 469 StateDatabaseError, 470 > { 471 Ok(Box::new(MerkleLeafIterator::new(self.clone(), prefix)?)) 472 } 473 } 474 475 /// A MerkleLeafIterator is fixed to iterate over the state address/value pairs 476 /// the merkle root hash at the time of its creation. 477 pub struct MerkleLeafIterator { 478 merkle_db: MerkleDatabase, 479 visited: VecDeque<(String, Node)>, 480 } 481 482 impl MerkleLeafIterator { 483 fn new(merkle_db: MerkleDatabase, prefix: Option<&str>) -> Result<Self, StateDatabaseError> { 484 let path = prefix.unwrap_or(""); 485 486 let mut visited = VecDeque::new(); 487 let initial_node = merkle_db.get_by_address(path)?; 488 visited.push_front((path.to_string(), initial_node)); 489 490 Ok(MerkleLeafIterator { merkle_db, visited }) 491 } 492 } 493 494 impl Iterator for MerkleLeafIterator { 495 type Item = Result<(String, Vec<u8>), StateDatabaseError>; 496 497 fn next(&mut self) -> Option<Self::Item> { 498 if self.visited.is_empty() { 499 return None; 500 } 501 502 loop { 503 if let Some((path, node)) = self.visited.pop_front() { 504 if node.value.is_some() { 505 return Some(Ok((path, node.value.unwrap()))); 506 } 507 508 // Reverse the list, such that we have an in-order traversal of the 509 // children, based on the natural path order. 510 for (child_path, hash_key) in node.children.iter().rev() { 511 let child = match get_node_by_hash(&self.merkle_db.db, hash_key) { 512 Ok(node) => node, 513 Err(err) => return Some(Err(err)), 514 }; 515 let mut child_address = path.clone(); 516 child_address.push_str(child_path); 517 self.visited.push_front((child_address, child)); 518 } 519 } else { 520 return None; 521 } 522 } 523 } 524 } 525 526 /// Initializes a database with an empty Trie 527 fn initialize_db(db: &LmdbDatabase) -> Result<String, StateDatabaseError> { 528 let (hash, packed) = encode_and_hash(Node::default())?; 529 530 let mut db_writer = db.writer()?; 531 let hex_hash = ::hex::encode(hash); 532 // Ignore ref counts for the default, empty tree 533 db_writer.overwrite(hex_hash.as_bytes(), &packed)?; 534 db_writer.commit()?; 535 536 Ok(hex_hash) 537 } 538 539 /// Returns the change log entry for a given root hash. 540 fn get_change_log<R>( 541 db_reader: &R, 542 root_hash: &[u8], 543 ) -> Result<Option<ChangeLogEntry>, StateDatabaseError> 544 where 545 R: DatabaseReader, 546 { 547 let log_bytes = db_reader.index_get(CHANGE_LOG_INDEX, root_hash)?; 548 549 Ok(match log_bytes { 550 Some(bytes) => Some(protobuf::parse_from_bytes(&bytes)?), 551 None => None, 552 }) 553 } 554 555 /// Writes the given change log entry to the database 556 fn write_change_log( 557 db_writer: &mut LmdbDatabaseWriter, 558 root_hash: &[u8], 559 change_log: &ChangeLogEntry, 560 ) -> Result<(), StateDatabaseError> { 561 Ok(db_writer.index_put(CHANGE_LOG_INDEX, root_hash, &change_log.write_to_bytes()?)?) 562 } 563 564 fn increment_ref_count( 565 db_writer: &mut LmdbDatabaseWriter, 566 key: &[u8], 567 ) -> Result<u64, StateDatabaseError> { 568 let ref_count = get_ref_count(db_writer, key)?; 569 570 db_writer.index_put(DUPLICATE_LOG_INDEX, key, &to_bytes(ref_count + 1))?; 571 572 Ok(ref_count) 573 } 574 575 fn decrement_ref_count( 576 db_writer: &mut LmdbDatabaseWriter, 577 key: &[u8], 578 ) -> Result<u64, StateDatabaseError> { 579 let count = get_ref_count(db_writer, key)?; 580 Ok(if count == 1 { 581 db_writer.index_delete(DUPLICATE_LOG_INDEX, key)?; 582 0 583 } else { 584 db_writer.index_put(DUPLICATE_LOG_INDEX, key, &to_bytes(count - 1))?; 585 count - 1 586 }) 587 } 588 589 fn get_ref_count( 590 db_writer: &mut LmdbDatabaseWriter, 591 key: &[u8], 592 ) -> Result<u64, StateDatabaseError> { 593 Ok( 594 if let Some(ref_count) = db_writer.index_get(DUPLICATE_LOG_INDEX, key)? { 595 from_bytes(ref_count) 596 } else { 597 0 598 }, 599 ) 600 } 601 602 fn to_bytes(num: u64) -> [u8; 8] { 603 unsafe { ::std::mem::transmute(num.to_le()) } 604 } 605 606 fn from_bytes(bytes: Vec<u8>) -> u64 { 607 let mut num_bytes = [0u8; 8]; 608 num_bytes.copy_from_slice(&bytes); 609 u64::from_le(unsafe { ::std::mem::transmute(num_bytes) }) 610 } 611 612 /// This delete ignores any MDB_NOTFOUND errors 613 fn delete_ignore_missing( 614 db_writer: &mut LmdbDatabaseWriter, 615 key: &[u8], 616 ) -> Result<(), StateDatabaseError> { 617 match db_writer.delete(key) { 618 Err(DatabaseError::WriterError(ref s)) 619 if s == "MDB_NOTFOUND: No matching key/data pair found" => 620 { 621 // This can be ignored, as the record doesn't exist 622 debug!( 623 "Attempting to delete a missing entry: {}", 624 ::hex::encode(key) 625 ); 626 Ok(()) 627 } 628 Err(err) => Err(StateDatabaseError::DatabaseError(err)), 629 Ok(_) => Ok(()), 630 } 631 } 632 /// Encodes the given node, and returns the hash of the bytes. 633 fn encode_and_hash(node: Node) -> Result<(Vec<u8>, Vec<u8>), StateDatabaseError> { 634 let packed = node.into_bytes()?; 635 let hash = hash(&packed); 636 Ok((hash, packed)) 637 } 638 639 /// Given a path, split it into its parent's path and the specific branch for 640 /// this path, such that the following assertion is true: 641 /// 642 /// ``` 643 /// let (parent_path, branch) = parent_and_branch(some_path); 644 /// let mut path = String::new(); 645 /// path.push(parent_path); 646 /// path.push(branch); 647 /// assert_eq!(some_path, &path); 648 /// ``` 649 fn parent_and_branch(path: &str) -> (&str, &str) { 650 let parent_address = if !path.is_empty() { 651 &path[..path.len() - TOKEN_SIZE] 652 } else { 653 "" 654 }; 655 656 let path_branch = if !path.is_empty() { 657 &path[(path.len() - TOKEN_SIZE)..] 658 } else { 659 "" 660 }; 661 662 (parent_address, path_branch) 663 } 664 665 /// Splits an address into tokens 666 fn tokenize_address(address: &str) -> Box<[&str]> { 667 let mut tokens: Vec<&str> = Vec::with_capacity(address.len() / TOKEN_SIZE); 668 let mut i = 0; 669 while i < address.len() { 670 tokens.push(&address[i..i + TOKEN_SIZE]); 671 i += TOKEN_SIZE; 672 } 673 tokens.into_boxed_slice() 674 } 675 676 /// Fetch a node by its hash 677 fn get_node_by_hash(db: &LmdbDatabase, hash: &str) -> Result<Node, StateDatabaseError> { 678 match db.reader()?.get(hash.as_bytes()) { 679 Some(bytes) => Node::from_bytes(&bytes), 680 None => Err(StateDatabaseError::NotFound(hash.to_string())), 681 } 682 } 683 684 /// Internal Node structure of the Radix tree 685 #[derive(Default, Debug, PartialEq, Clone)] 686 struct Node { 687 value: Option<Vec<u8>>, 688 children: BTreeMap<String, String>, 689 } 690 691 impl Node { 692 /// Consumes this node and serializes it to bytes 693 fn into_bytes(self) -> Result<Vec<u8>, StateDatabaseError> { 694 let mut e = GenericEncoder::new(Cursor::new(Vec::new())); 695 696 let mut map = BTreeMap::new(); 697 map.insert( 698 Key::Text(Text::Text("v".to_string())), 699 match self.value { 700 Some(bytes) => Value::Bytes(Bytes::Bytes(bytes)), 701 None => Value::Null, 702 }, 703 ); 704 705 let children = self.children 706 .into_iter() 707 .map(|(k, v)| { 708 ( 709 Key::Text(Text::Text(k.to_string())), 710 Value::Text(Text::Text(v.to_string())), 711 ) 712 }) 713 .collect(); 714 715 map.insert(Key::Text(Text::Text("c".to_string())), Value::Map(children)); 716 717 e.value(&Value::Map(map))?; 718 719 Ok(e.into_inner().into_writer().into_inner()) 720 } 721 722 /// Deserializes the given bytes to a Node 723 fn from_bytes(bytes: &[u8]) -> Result<Node, StateDatabaseError> { 724 let input = Cursor::new(bytes); 725 let mut decoder = GenericDecoder::new(cbor::Config::default(), input); 726 let decoder_value = decoder.value()?; 727 let (val, children_raw) = match decoder_value { 728 Value::Map(mut root_map) => ( 729 root_map.remove(&Key::Text(Text::Text("v".to_string()))), 730 root_map.remove(&Key::Text(Text::Text("c".to_string()))), 731 ), 732 _ => return Err(StateDatabaseError::InvalidRecord), 733 }; 734 735 let value = match val { 736 Some(Value::Bytes(Bytes::Bytes(bytes))) => Some(bytes), 737 Some(Value::Null) => None, 738 _ => return Err(StateDatabaseError::InvalidRecord), 739 }; 740 741 let children = match children_raw { 742 Some(Value::Map(mut child_map)) => { 743 let mut result = BTreeMap::new(); 744 for (k, v) in child_map { 745 result.insert(key_to_string(k)?, text_to_string(v)?); 746 } 747 result 748 } 749 None => BTreeMap::new(), 750 _ => return Err(StateDatabaseError::InvalidRecord), 751 }; 752 753 Ok(Node { value, children }) 754 } 755 } 756 757 /// Converts a CBOR Key to its String content 758 fn key_to_string(key_val: Key) -> Result<String, StateDatabaseError> { 759 match key_val { 760 Key::Text(Text::Text(s)) => Ok(s), 761 _ => Err(StateDatabaseError::InvalidRecord), 762 } 763 } 764 765 /// Converts a CBOR Text Value to its String content 766 fn text_to_string(text_val: Value) -> Result<String, StateDatabaseError> { 767 match text_val { 768 Value::Text(Text::Text(s)) => Ok(s), 769 _ => Err(StateDatabaseError::InvalidRecord), 770 } 771 } 772 773 /// Creates a hash of the given bytes 774 fn hash(input: &[u8]) -> Vec<u8> { 775 let mut sha = Sha512::new(); 776 sha.input(input); 777 778 let mut vec: Vec<u8> = vec![0; sha.output_bytes()]; 779 sha.result(vec.as_mut_slice()); 780 781 let (hash, _rest) = vec.split_at(vec.len() / 2); 782 hash.to_vec() 783 } 784 785 #[cfg(test)] 786 mod tests { 787 use super::*; 788 use database::database::DatabaseError; 789 use database::lmdb::DatabaseReader; 790 use database::lmdb::LmdbContext; 791 use database::lmdb::LmdbDatabase; 792 use proto::merkle::ChangeLogEntry; 793 794 use protobuf; 795 use rand::{seq, thread_rng}; 796 use std::env; 797 use std::fs::remove_file; 798 use std::panic; 799 use std::path::Path; 800 use std::str::from_utf8; 801 use std::thread; 802 803 #[test] 804 fn node_serialize() { 805 let n = Node { 806 value: Some(b"hello".to_vec()), 807 children: vec![("ab".to_string(), "123".to_string())] 808 .into_iter() 809 .collect(), 810 }; 811 812 let packed = n.into_bytes() 813 .unwrap() 814 .iter() 815 .map(|b| format!("{:x}", b)) 816 .collect::<Vec<_>>() 817 .join(""); 818 // This expected output was generated using the python structures 819 let output = "a26163a16261626331323361764568656c6c6f"; 820 821 assert_eq!(output, packed); 822 } 823 824 #[test] 825 fn node_deserialize() { 826 let packed = 827 ::hex::decode("a26163a162303063616263617647676f6f64627965").expect("improper hex"); 828 829 let unpacked = Node::from_bytes(&packed).unwrap(); 830 assert_eq!( 831 Node { 832 value: Some(b"goodbye".to_vec()), 833 children: vec![("00".to_string(), "abc".to_string())] 834 .into_iter() 835 .collect(), 836 }, 837 unpacked 838 ); 839 } 840 841 #[test] 842 fn node_roundtrip() { 843 let n = Node { 844 value: Some(b"hello".to_vec()), 845 children: vec![("ab".to_string(), "123".to_string())] 846 .into_iter() 847 .collect(), 848 }; 849 850 let packed = n.into_bytes().unwrap(); 851 let unpacked = Node::from_bytes(&packed).unwrap(); 852 853 assert_eq!( 854 Node { 855 value: Some(b"hello".to_vec()), 856 children: vec![("ab".to_string(), "123".to_string())] 857 .into_iter() 858 .collect(), 859 }, 860 unpacked 861 ) 862 } 863 864 #[test] 865 fn merkle_trie_root_advance() { 866 run_test(|merkle_path| { 867 let db = make_lmdb(&merkle_path); 868 let mut merkle_db = MerkleDatabase::new(db.clone(), None).unwrap(); 869 870 let orig_root = merkle_db.get_merkle_root(); 871 let orig_root_bytes = &::hex::decode(orig_root.clone()).unwrap(); 872 873 { 874 // check that there is no ChangeLogEntry for the initial root 875 let reader = db.reader().unwrap(); 876 assert!( 877 reader 878 .index_get(CHANGE_LOG_INDEX, orig_root_bytes) 879 .expect("A database error occurred") 880 .is_none() 881 ); 882 } 883 884 let new_root = merkle_db.set("abcd", "data_value".as_bytes()).unwrap(); 885 let new_root_bytes = &::hex::decode(new_root.clone()).unwrap(); 886 887 assert_eq!(merkle_db.get_merkle_root(), orig_root, "Incorrect root"); 888 assert_ne!(orig_root, new_root, "root was not changed"); 889 assert!( 890 !merkle_db.contains("abcd").unwrap(), 891 "Should not contain the value" 892 ); 893 894 let change_log: ChangeLogEntry = { 895 // check that we have a change log entry for the new root 896 let reader = db.reader().unwrap(); 897 let entry_bytes = &reader 898 .index_get(CHANGE_LOG_INDEX, new_root_bytes) 899 .expect("A database error occurred") 900 .expect("Did not return a change log entry"); 901 protobuf::parse_from_bytes(entry_bytes).expect("Failed to parse change log entry") 902 }; 903 904 assert_eq!(orig_root_bytes, &change_log.get_parent()); 905 assert_eq!(3, change_log.get_additions().len()); 906 assert_eq!(0, change_log.get_successors().len()); 907 908 merkle_db.set_merkle_root(new_root.clone()).unwrap(); 909 assert_eq!(merkle_db.get_merkle_root(), new_root, "Incorrect root"); 910 911 assert_value_at_address(&merkle_db, "abcd", "data_value"); 912 }) 913 } 914 915 #[test] 916 fn merkle_trie_delete() { 917 run_test(|merkle_path| { 918 let mut merkle_db = make_db(&merkle_path); 919 920 let new_root = merkle_db.set("1234", "deletable".as_bytes()).unwrap(); 921 merkle_db.set_merkle_root(new_root).unwrap(); 922 assert_value_at_address(&merkle_db, "1234", "deletable"); 923 924 // deleting an unknown key should return an error 925 assert!(merkle_db.delete("barf").is_err()); 926 927 let del_root = merkle_db.delete("1234").unwrap(); 928 929 // del_root hasn't been set yet, so address should still have value 930 assert_value_at_address(&merkle_db, "1234", "deletable"); 931 merkle_db.set_merkle_root(del_root).unwrap(); 932 assert!(!merkle_db.contains("1234").unwrap()); 933 }) 934 } 935 936 #[test] 937 fn merkle_trie_update() { 938 run_test(|merkle_path| { 939 let mut merkle_db = make_db(&merkle_path); 940 let init_root = merkle_db.get_merkle_root(); 941 942 let key_hashes = (0..1000) 943 .map(|i| { 944 let key = format!("{:016x}", i); 945 let hash = hex_hash(key.as_bytes()); 946 (key, hash) 947 }) 948 .collect::<Vec<_>>(); 949 950 let mut values = HashMap::new(); 951 for &(ref key, ref hashed) in key_hashes.iter() { 952 let new_root = merkle_db.set(&hashed, key.as_bytes()).unwrap(); 953 values.insert(hashed.clone(), key.to_string()); 954 merkle_db.set_merkle_root(new_root).unwrap(); 955 } 956 957 assert_ne!(init_root, merkle_db.get_merkle_root()); 958 959 let mut rng = thread_rng(); 960 let mut set_items = HashMap::new(); 961 // Perform some updates on the lower keys 962 for i in seq::sample_iter(&mut rng, 0..500, 50).unwrap() { 963 let hash_key = hex_hash(format!("{:016x}", i).as_bytes()); 964 set_items.insert(hash_key.clone(), "5.0".as_bytes().to_vec()); 965 values.insert(hash_key.clone(), "5.0".to_string()); 966 } 967 968 // perform some deletions on the upper keys 969 let delete_items = seq::sample_iter(&mut rng, 500..1000, 50) 970 .unwrap() 971 .into_iter() 972 .map(|i| hex_hash(format!("{:016x}", i).as_bytes())) 973 .collect::<Vec<String>>(); 974 975 for hash in delete_items.iter() { 976 values.remove(hash); 977 } 978 979 let virtual_root = merkle_db.update(&set_items, &delete_items, true).unwrap(); 980 981 // virtual root shouldn't match actual contents of tree 982 assert!(merkle_db.set_merkle_root(virtual_root.clone()).is_err()); 983 984 let actual_root = merkle_db.update(&set_items, &delete_items, false).unwrap(); 985 // the virtual root should be the same as the actual root 986 assert_eq!(virtual_root, actual_root); 987 assert_ne!(actual_root, merkle_db.get_merkle_root()); 988 989 merkle_db.set_merkle_root(actual_root).unwrap(); 990 991 for (address, value) in values { 992 assert_value_at_address(&merkle_db, &address, &value); 993 } 994 995 for address in delete_items { 996 assert!(merkle_db.get(&address).is_err()); 997 } 998 }) 999 } 1000 1001 #[test] 1002 /// This test is similar to the update test except that it will ensure that 1003 /// there are no index errors in path_map within update function in case 1004 /// there are addresses within set_items & delete_items which have a common 1005 /// prefix (of any length). 1006 /// 1007 /// A Merkle trie is created with some initial values which is then updated 1008 /// (set & delete). 1009 fn merkle_trie_update_same_address_space() { 1010 run_test(|merkle_path| { 1011 let mut merkle_db = make_db(merkle_path); 1012 let init_root = merkle_db.get_merkle_root(); 1013 let key_hashes = vec![ 1014 // matching prefix e55420 1015 ( 1016 "asdfg", 1017 "e5542002d3e2892516fa461cde69e05880609fbad3d38ab69435a189e126de672b620c", 1018 ), 1019 ( 1020 "qwert", 1021 "c946ee72d38b8c51328f1a5f31eb5bd3300362ad0ca69dab54eff996775c7069216bda", 1022 ), 1023 ( 1024 "zxcvb", 1025 "487a6a63c71c9b7b63146ef68858e5d010b4978fd70dda0404d4fad5e298ccc9a560eb", 1026 ), 1027 // matching prefix e55420 1028 ( 1029 "yuiop", 1030 "e55420c026596ee643e26fd93927249ea28fb5f359ddbd18bc02562dc7e8dbc93e89b9", 1031 ), 1032 ( 1033 "hjklk", 1034 "cc1370ce67aa16c89721ee947e9733b2a3d2460db5b0ea6410288f426ad8d8040ea641", 1035 ), 1036 ( 1037 "bnmvc", 1038 "d07e69664286712c3d268ca71464f2b3b2604346f833106f3e0f6a72276e57a16f3e0f", 1039 ), 1040 ]; 1041 let mut values = HashMap::new(); 1042 for &(ref key, ref hashed) in key_hashes.iter() { 1043 let new_root = merkle_db.set(&hashed, key.as_bytes()).unwrap(); 1044 values.insert(hashed.to_string(), key.to_string()); 1045 merkle_db.set_merkle_root(new_root).unwrap(); 1046 } 1047 1048 assert_ne!(init_root, merkle_db.get_merkle_root()); 1049 let mut set_items = HashMap::new(); 1050 // Perform some updates on the lower keys 1051 for &(_, ref key_hash) in key_hashes.iter() { 1052 set_items.insert(key_hash.clone().to_string(), "2.0".as_bytes().to_vec()); 1053 values.insert(key_hash.clone().to_string(), "2.0".to_string()); 1054 } 1055 1056 // The first item below(e55420...89b9) shares a common prefix 1057 // with the first in set_items(e55420...620c) 1058 let delete_items = vec![ 1059 "e55420c026596ee643e26fd93927249ea28fb5f359ddbd18bc02562dc7e8dbc93e89b9" 1060 .to_string(), 1061 "cc1370ce67aa16c89721ee947e9733b2a3d2460db5b0ea6410288f426ad8d8040ea641" 1062 .to_string(), 1063 "d07e69664286712c3d268ca71464f2b3b2604346f833106f3e0f6a72276e57a16f3e0f" 1064 .to_string(), 1065 ]; 1066 1067 for hash in delete_items.iter() { 1068 values.remove(hash); 1069 } 1070 1071 let virtual_root = merkle_db.update(&set_items, &delete_items, true).unwrap(); 1072 1073 // virtual root shouldn't match actual contents of tree 1074 assert!(merkle_db.set_merkle_root(virtual_root.clone()).is_err()); 1075 1076 let actual_root = merkle_db.update(&set_items, &delete_items, false).unwrap(); 1077 // the virtual root should be the same as the actual root 1078 assert_eq!(virtual_root, actual_root); 1079 assert_ne!(actual_root, merkle_db.get_merkle_root()); 1080 1081 merkle_db.set_merkle_root(actual_root).unwrap(); 1082 1083 for (address, value) in values { 1084 assert_value_at_address(&merkle_db, &address, &value); 1085 } 1086 1087 for address in delete_items { 1088 assert!(merkle_db.get(&address).is_err()); 1089 } 1090 }) 1091 } 1092 1093 #[test] 1094 /// This test creates a merkle trie with multiple entries, and produces a 1095 /// second trie based on the first where an entry is change. 1096 /// 1097 /// - It verifies that both tries have a ChangeLogEntry 1098 /// - Prunes the parent trie 1099 /// - Verifies that the nodes written are gone 1100 /// - verifies that the parent trie's ChangeLogEntry is deleted 1101 fn merkle_trie_pruning_parent() { 1102 run_test(|merkle_path| { 1103 let db = make_lmdb(&merkle_path); 1104 let mut merkle_db = MerkleDatabase::new(db.clone(), None).expect("No db errors"); 1105 let mut updates: HashMap<String, Vec<u8>> = HashMap::with_capacity(3); 1106 updates.insert("ab0000".to_string(), "0001".as_bytes().to_vec()); 1107 updates.insert("ab0a01".to_string(), "0002".as_bytes().to_vec()); 1108 updates.insert("abff00".to_string(), "0003".as_bytes().to_vec()); 1109 1110 let parent_root = merkle_db 1111 .update(&updates, &[], false) 1112 .expect("Update failed to work"); 1113 merkle_db.set_merkle_root(parent_root.clone()).unwrap(); 1114 1115 let parent_root_bytes = ::hex::decode(parent_root.clone()).expect("Proper hex"); 1116 // check that we have a change log entry for the new root 1117 let mut parent_change_log = expect_change_log(&db, &parent_root_bytes); 1118 assert!(parent_change_log.get_successors().is_empty()); 1119 1120 assert_value_at_address(&merkle_db, "ab0000", "0001"); 1121 assert_value_at_address(&merkle_db, "ab0a01", "0002"); 1122 assert_value_at_address(&merkle_db, "abff00", "0003"); 1123 1124 let successor_root = merkle_db 1125 .set("ab0000", "test".as_bytes()) 1126 .expect("Set failed to work"); 1127 let successor_root_bytes = ::hex::decode(successor_root.clone()).expect("proper hex"); 1128 1129 // Load the parent change log after the change. 1130 parent_change_log = expect_change_log(&db, &parent_root_bytes); 1131 let successor_change_log = expect_change_log(&db, &successor_root_bytes); 1132 1133 assert_has_successors(&parent_change_log, &[&successor_root_bytes]); 1134 assert_eq!(parent_root_bytes, successor_change_log.get_parent()); 1135 1136 merkle_db 1137 .set_merkle_root(successor_root) 1138 .expect("Unable to apply the new merkle root"); 1139 assert_eq!( 1140 parent_change_log 1141 .get_successors() 1142 .first() 1143 .unwrap() 1144 .get_deletions() 1145 .len(), 1146 MerkleDatabase::prune(&db, &parent_root) 1147 .expect("Prune should have no errors") 1148 .len() 1149 ); 1150 1151 let reader = db.reader().unwrap(); 1152 for addition in parent_change_log 1153 .get_successors() 1154 .first() 1155 .unwrap() 1156 .get_deletions() 1157 { 1158 assert!(reader.get(addition).is_none()); 1159 } 1160 1161 assert!( 1162 reader 1163 .index_get(CHANGE_LOG_INDEX, &parent_root_bytes) 1164 .expect("DB query should succeed") 1165 .is_none() 1166 ); 1167 1168 assert!(merkle_db.set_merkle_root(parent_root).is_err()); 1169 }) 1170 } 1171 1172 #[test] 1173 /// This test creates a merkle trie with multiple entries and produces two 1174 /// distinct successor tries from that first. 1175 /// 1176 /// - it verifies that all the tries have a ChangeLogEntry 1177 /// - it prunes one of the successors 1178 /// - it verifies the nodes from that successor are removed 1179 /// - it verifies that the pruned successor's ChangeLogEntry is removed 1180 /// - it verifies the original and the remaining successor still are 1181 /// persisted 1182 fn merkle_trie_pruinng_successors() { 1183 run_test(|merkle_path| { 1184 let db = make_lmdb(&merkle_path); 1185 let mut merkle_db = MerkleDatabase::new(db.clone(), None).expect("No db errors"); 1186 let mut updates: HashMap<String, Vec<u8>> = HashMap::with_capacity(3); 1187 updates.insert("ab0000".to_string(), "0001".as_bytes().to_vec()); 1188 updates.insert("ab0a01".to_string(), "0002".as_bytes().to_vec()); 1189 updates.insert("abff00".to_string(), "0003".as_bytes().to_vec()); 1190 1191 let parent_root = merkle_db 1192 .update(&updates, &[], false) 1193 .expect("Update failed to work"); 1194 let parent_root_bytes = ::hex::decode(parent_root.clone()).expect("Proper hex"); 1195 1196 merkle_db.set_merkle_root(parent_root.clone()).unwrap(); 1197 assert_value_at_address(&merkle_db, "ab0000", "0001"); 1198 assert_value_at_address(&merkle_db, "ab0a01", "0002"); 1199 assert_value_at_address(&merkle_db, "abff00", "0003"); 1200 1201 let successor_root_left = merkle_db 1202 .set("ab0000", "left".as_bytes()) 1203 .expect("Set failed to work"); 1204 let successor_root_left_bytes = 1205 ::hex::decode(successor_root_left.clone()).expect("proper hex"); 1206 1207 let successor_root_right = merkle_db 1208 .set("ab0a01", "right".as_bytes()) 1209 .expect("Set failed to work"); 1210 let successor_root_right_bytes = 1211 ::hex::decode(successor_root_right.clone()).expect("proper hex"); 1212 1213 let mut parent_change_log = expect_change_log(&db, &parent_root_bytes); 1214 let successor_left_change_log = expect_change_log(&db, &successor_root_left_bytes); 1215 expect_change_log(&db, &successor_root_right_bytes); 1216 1217 assert_has_successors( 1218 &parent_change_log, 1219 &[&successor_root_left_bytes, &successor_root_right_bytes], 1220 ); 1221 1222 // Let's prune the left successor: 1223 1224 assert_eq!( 1225 successor_left_change_log.get_additions().len(), 1226 MerkleDatabase::prune(&db, &successor_root_left) 1227 .expect("Prune should have no errors") 1228 .len() 1229 ); 1230 1231 parent_change_log = expect_change_log(&db, &parent_root_bytes); 1232 assert_has_successors(&parent_change_log, &[&successor_root_right_bytes]); 1233 1234 assert!(merkle_db.set_merkle_root(successor_root_left).is_err()); 1235 }) 1236 } 1237 1238 #[test] 1239 /// This test creates a merkle trie with multiple entries and produces a 1240 /// successor with duplicate That changes one new leaf, followed by a second 1241 /// successor that produces a leaf with the same hash. When the pruning the 1242 /// initial root, the duplicate leaf node is not pruned as well. 1243 fn merkle_trie_pruning_duplicate_leaves() { 1244 run_test(|merkle_path| { 1245 let db = make_lmdb(&merkle_path); 1246 let mut merkle_db = MerkleDatabase::new(db.clone(), None).expect("No db errors"); 1247 let updates: HashMap<String, Vec<u8>> = vec![ 1248 ("ab0000".to_string(), "0001".as_bytes().to_vec()), 1249 ("ab0001".to_string(), "0002".as_bytes().to_vec()), 1250 ("ab0002".to_string(), "0003".as_bytes().to_vec()), 1251 ].into_iter() 1252 .collect(); 1253 1254 let parent_root = merkle_db 1255 .update(&updates, &[], false) 1256 .expect("Update failed to work"); 1257 let parent_root_bytes = ::hex::decode(parent_root.clone()).expect("Proper hex"); 1258 1259 // create the middle root 1260 merkle_db.set_merkle_root(parent_root.clone()).unwrap(); 1261 let updates: HashMap<String, Vec<u8>> = vec![ 1262 ("ab0000".to_string(), "change0".as_bytes().to_vec()), 1263 ("ab0001".to_string(), "change1".as_bytes().to_vec()), 1264 ].into_iter() 1265 .collect(); 1266 let successor_root_middle = merkle_db 1267 .update(&updates, &[], false) 1268 .expect("Update failed to work"); 1269 1270 // create the last root 1271 merkle_db 1272 .set_merkle_root(successor_root_middle.clone()) 1273 .unwrap(); 1274 // Set the value back to the original 1275 let successor_root_last = merkle_db 1276 .set("ab0000", "0001".as_bytes()) 1277 .expect("Set failed to work"); 1278 1279 merkle_db.set_merkle_root(successor_root_last).unwrap(); 1280 let parent_change_log = expect_change_log(&db, &parent_root_bytes); 1281 assert_eq!( 1282 parent_change_log 1283 .get_successors() 1284 .first() 1285 .unwrap() 1286 .get_deletions() 1287 .len() - 1, 1288 MerkleDatabase::prune(&db, &parent_root) 1289 .expect("Prune should have no errors") 1290 .len() 1291 ); 1292 1293 assert_value_at_address(&merkle_db, "ab0000", "0001"); 1294 }) 1295 } 1296 #[test] 1297 /// This test creates a merkle trie with multiple entries and produces a 1298 /// successor with duplicate That changes one new leaf, followed by a second 1299 /// successor that produces a leaf with the same hash. When the pruning the 1300 /// last root, the duplicate leaf node is not pruned as well. 1301 fn merkle_trie_pruning_successor_duplicate_leaves() { 1302 run_test(|merkle_path| { 1303 let db = make_lmdb(&merkle_path); 1304 let mut merkle_db = MerkleDatabase::new(db.clone(), None).expect("No db errors"); 1305 let updates: HashMap<String, Vec<u8>> = vec![ 1306 ("ab0000".to_string(), "0001".as_bytes().to_vec()), 1307 ("ab0001".to_string(), "0002".as_bytes().to_vec()), 1308 ("ab0002".to_string(), "0003".as_bytes().to_vec()), 1309 ].into_iter() 1310 .collect(); 1311 1312 let parent_root = merkle_db 1313 .update(&updates, &[], false) 1314 .expect("Update failed to work"); 1315 1316 // create the middle root 1317 merkle_db.set_merkle_root(parent_root.clone()).unwrap(); 1318 let updates: HashMap<String, Vec<u8>> = vec![ 1319 ("ab0000".to_string(), "change0".as_bytes().to_vec()), 1320 ("ab0001".to_string(), "change1".as_bytes().to_vec()), 1321 ].into_iter() 1322 .collect(); 1323 let successor_root_middle = merkle_db 1324 .update(&updates, &[], false) 1325 .expect("Update failed to work"); 1326 1327 // create the last root 1328 merkle_db 1329 .set_merkle_root(successor_root_middle.clone()) 1330 .unwrap(); 1331 // Set the value back to the original 1332 let successor_root_last = merkle_db 1333 .set("ab0000", "0001".as_bytes()) 1334 .expect("Set failed to work"); 1335 let successor_root_bytes = 1336 ::hex::decode(successor_root_last.clone()).expect("Proper hex"); 1337 1338 // set back to the parent root 1339 merkle_db.set_merkle_root(parent_root).unwrap(); 1340 let last_change_log = expect_change_log(&db, &successor_root_bytes); 1341 assert_eq!( 1342 last_change_log.get_additions().len() - 1, 1343 MerkleDatabase::prune(&db, &successor_root_last) 1344 .expect("Prune should have no errors") 1345 .len() 1346 ); 1347 1348 assert_value_at_address(&merkle_db, "ab0000", "0001"); 1349 }) 1350 } 1351 1352 fn expect_change_log(db: &LmdbDatabase, root_hash: &[u8]) -> ChangeLogEntry { 1353 let reader = db.reader().unwrap(); 1354 protobuf::parse_from_bytes(&reader 1355 .index_get(CHANGE_LOG_INDEX, root_hash) 1356 .expect("No db errors") 1357 .expect("A change log entry")) 1358 .expect("The change log entry to have bytes") 1359 } 1360 1361 fn assert_has_successors(change_log: &ChangeLogEntry, successor_roots: &[&[u8]]) { 1362 assert_eq!(successor_roots.len(), change_log.get_successors().len()); 1363 for successor_root in successor_roots { 1364 let mut has_root = false; 1365 for successor in change_log.get_successors() { 1366 if &successor.get_successor() == successor_root { 1367 has_root = true; 1368 break; 1369 } 1370 } 1371 if !has_root { 1372 panic!(format!( 1373 "Root {} not found in change log {:?}", 1374 ::hex::encode(successor_root), 1375 change_log 1376 )); 1377 } 1378 } 1379 } 1380 1381 #[test] 1382 fn leaf_iteration() { 1383 run_test(|merkle_path| { 1384 let mut merkle_db = make_db(merkle_path); 1385 1386 { 1387 let mut leaf_iter = merkle_db.leaves(None).unwrap(); 1388 assert!( 1389 leaf_iter.next().is_none(), 1390 "Empty tree should return no leaves" 1391 ); 1392 } 1393 1394 let addresses = vec!["ab0000", "aba001", "abff02"]; 1395 for (i, key) in addresses.iter().enumerate() { 1396 let new_root = merkle_db 1397 .set(key, format!("{:04x}", i * 10).as_bytes()) 1398 .unwrap(); 1399 merkle_db.set_merkle_root(new_root).unwrap(); 1400 } 1401 1402 assert_value_at_address(&merkle_db, "ab0000", "0000"); 1403 assert_value_at_address(&merkle_db, "aba001", "000a"); 1404 assert_value_at_address(&merkle_db, "abff02", "0014"); 1405 1406 let mut leaf_iter = merkle_db.leaves(None).unwrap(); 1407 1408 assert_eq!( 1409 ("ab0000".into(), "0000".as_bytes().to_vec()), 1410 leaf_iter.next().unwrap().unwrap() 1411 ); 1412 assert_eq!( 1413 ("aba001".into(), "000a".as_bytes().to_vec()), 1414 leaf_iter.next().unwrap().unwrap() 1415 ); 1416 assert_eq!( 1417 ("abff02".into(), "0014".as_bytes().to_vec()), 1418 leaf_iter.next().unwrap().unwrap() 1419 ); 1420 assert!(leaf_iter.next().is_none(), "Iterator should be Exhausted"); 1421 1422 // test that we can start from an prefix: 1423 let mut leaf_iter = merkle_db.leaves(Some("abff")).unwrap(); 1424 assert_eq!( 1425 ("abff02".into(), "0014".as_bytes().to_vec()), 1426 leaf_iter.next().unwrap().unwrap() 1427 ); 1428 assert!(leaf_iter.next().is_none(), "Iterator should be Exhausted"); 1429 }) 1430 } 1431 1432 fn run_test<T>(test: T) -> () 1433 where 1434 T: FnOnce(&str) -> () + panic::UnwindSafe, 1435 { 1436 let dbpath = temp_db_path(); 1437 1438 let testpath = dbpath.clone(); 1439 let result = panic::catch_unwind(move || test(&testpath)); 1440 1441 remove_file(dbpath).unwrap(); 1442 1443 assert!(result.is_ok()) 1444 } 1445 1446 fn assert_value_at_address(merkle_db: &MerkleDatabase, address: &str, expected_value: &str) { 1447 let value = merkle_db.get(address); 1448 assert!(value.is_ok(), format!("Value not returned: {:?}", value)); 1449 assert_eq!(Ok(expected_value), from_utf8(&value.unwrap().unwrap())); 1450 } 1451 1452 fn make_lmdb(merkle_path: &str) -> LmdbDatabase { 1453 let ctx = LmdbContext::new( 1454 Path::new(merkle_path), 1455 INDEXES.len(), 1456 Some(120 * 1024 * 1024), 1457 ).map_err(|err| DatabaseError::InitError(format!("{}", err))) 1458 .unwrap(); 1459 LmdbDatabase::new(ctx, &INDEXES) 1460 .map_err(|err| DatabaseError::InitError(format!("{}", err))) 1461 .unwrap() 1462 } 1463 1464 fn make_db(merkle_path: &str) -> MerkleDatabase { 1465 MerkleDatabase::new(make_lmdb(merkle_path), None).unwrap() 1466 } 1467 1468 fn temp_db_path() -> String { 1469 let mut temp_dir = env::temp_dir(); 1470 1471 let thread_id = thread::current().id(); 1472 temp_dir.push(format!("merkle-{:?}.lmdb", thread_id)); 1473 temp_dir.to_str().unwrap().to_string() 1474 } 1475 1476 fn hex_hash(b: &[u8]) -> String { 1477 ::hex::encode(hash(b)) 1478 } 1479 1480 }