Use Vec<u8> instead of string for digest bytes and add roomid_statehash

This commit is contained in:
Devin Ragotzy 2020-08-19 19:29:39 -04:00
parent d73c6aa8ad
commit 64fb0374b6

View file

@ -33,7 +33,7 @@ use std::{
/// ///
/// This is created when a state group is added to the database by /// This is created when a state group is added to the database by
/// hashing the entire state. /// hashing the entire state.
pub type StateHashId = String; pub type StateHashId = Vec<u8>;
/// This identifier consists of roomId + count. It represents a /// This identifier consists of roomId + count. It represents a
/// unique event, it will never be overwritten or removed. /// unique event, it will never be overwritten or removed.
@ -100,7 +100,7 @@ impl Rooms {
/// with `state_hash`, this gives the full state at event "x". /// with `state_hash`, this gives the full state at event "x".
pub fn get_statemap_by_hash(&self, state_hash: StateHashId) -> Result<StateMap<EventId>> { pub fn get_statemap_by_hash(&self, state_hash: StateHashId) -> Result<StateMap<EventId>> {
self.stateid_pduid self.stateid_pduid
.scan_prefix(state_hash.as_bytes()) .scan_prefix(&state_hash)
.values() .values()
.map(|pduid| { .map(|pduid| {
self.pduid_pdu.get(&pduid?)?.map_or_else( self.pduid_pdu.get(&pduid?)?.map_or_else(
@ -123,12 +123,12 @@ impl Rooms {
pub fn prev_state_hash(&self, current: StateHashId) -> Option<StateHashId> { pub fn prev_state_hash(&self, current: StateHashId) -> Option<StateHashId> {
let mut found = false; let mut found = false;
for pair in self.pduid_statehash.iter().rev() { for pair in self.pduid_statehash.iter().rev() {
let prev = utils::string_from_bytes(&pair.ok()?.1).ok()?; let prev = pair.ok()?.1;
if current == prev { if current == prev.as_ref() {
found = true; found = true;
} }
if current != prev && found { if current != prev.as_ref() && found {
return Some(prev); return Some(prev.to_vec());
} }
} }
None None
@ -172,17 +172,14 @@ impl Rooms {
// We must check here because this method is called outside and before // We must check here because this method is called outside and before
// `append_state_pdu` so the DB can be empty // `append_state_pdu` so the DB can be empty
if self.pduid_statehash.scan_prefix(prefix).next().is_none() { if self.pduid_statehash.scan_prefix(prefix).next().is_none() {
// TODO use ring crate to hash // return the hash of the room_id, this represents a room with no state
return Ok(room_id.as_str().to_owned()); return self.new_state_hash_id(room_id);
} }
self.pduid_statehash self.pduid_statehash
.iter() .iter()
.next_back() .next_back()
.map(|pair| { .map(|pair| Ok(pair?.1.to_vec()))
utils::string_from_bytes(&pair?.1)
.map_err(|_| Error::bad_database("Invalid state hash string in db."))
})
.ok_or_else(|| Error::bad_database("No PDU's found for this room."))? .ok_or_else(|| Error::bad_database("No PDU's found for this room."))?
} }
@ -255,10 +252,9 @@ impl Rooms {
.next() .next()
.is_none() .is_none()
{ {
return utils::string_from_bytes( return Ok(digest::digest(&digest::SHA256, room_id.as_bytes())
digest::digest(&digest::SHA256, room_id.as_bytes()).as_ref(), .as_ref()
) .to_vec());
.map_err(|_| Error::bad_database("Empty state generated invalid string from hash."));
} }
let pdu_ids_to_hash = self let pdu_ids_to_hash = self
@ -280,9 +276,7 @@ impl Rooms {
&digest::SHA256, &digest::SHA256,
&pdu_ids_to_hash.into_iter().flatten().collect::<Vec<u8>>(), &pdu_ids_to_hash.into_iter().flatten().collect::<Vec<u8>>(),
); );
// TODO not sure how you want to hash this Ok(hash.as_ref().to_vec())
utils::string_from_bytes(hash.as_ref())
.map_err(|_| Error::bad_database("State generated invalid string from hash."))
} }
/// Checks if a room exists. /// Checks if a room exists.
@ -604,7 +598,7 @@ impl Rooms {
let state_hash = self.new_state_hash_id(room_id)?; let state_hash = self.new_state_hash_id(room_id)?;
let state = self.current_state_pduids(room_id)?; let state = self.current_state_pduids(room_id)?;
let mut key = state_hash.as_bytes().to_vec(); let mut key = state_hash.to_vec();
key.push(0xff); key.push(0xff);
// TODO eventually we could avoid writing to the DB so much on every event // TODO eventually we could avoid writing to the DB so much on every event
@ -622,9 +616,10 @@ impl Rooms {
// This event's state does not include the event itself. `current_state_pduids` // This event's state does not include the event itself. `current_state_pduids`
// uses `roomstateid_pduid` before the current event is inserted to the tree so the state // uses `roomstateid_pduid` before the current event is inserted to the tree so the state
// will be everything up to but not including the incoming event. // will be everything up to but not including the incoming event.
self.pduid_statehash.insert(pdu_id, state_hash.as_bytes())?; self.pduid_statehash.insert(pdu_id, state_hash.as_slice())?;
self.roomid_statehash.insert(room_id.as_bytes(), state_hash.as_bytes())?; self.roomid_statehash
.insert(room_id.as_bytes(), state_hash.as_slice())?;
let mut key = room_id.as_bytes().to_vec(); let mut key = room_id.as_bytes().to_vec();
key.push(0xff); key.push(0xff);