Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/sigma-db-sql/sql/query/current_height.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- Get current height
SELECT MAX(height) AS height
FROM events;
1 change: 1 addition & 0 deletions crates/sigma-db-sql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub mod query {
decl_const_sql_str!(EVENTS_RANGE, "query/events_range.sql");
decl_const_sql_str!(HASHES_RANGE, "query/hashes_range.sql");
decl_const_sql_str!(PARENT_HASH, "query/parent_hash.sql");
decl_const_sql_str!(CURRENT_HEIGHT, "query/current_height.sql");
}

pub mod table {
Expand Down
38 changes: 27 additions & 11 deletions crates/sigma-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ pub async fn run(
.expect("Failed to create tables");
loop {
let mut i = 0;
let parent_hash = loop {
match get_current_hash(&mut database).await {
Ok(parent_hash) => {
break parent_hash;
let parent_height = loop {
match get_current_height(&mut database).await {
Ok(parent_height) => {
break parent_height;
}
Err(e) => {
tracing::error!(error = %e, "Failed to get current hash. Retry #{}", i + 1);
tracing::error!(error = %e, "Failed to get current height. Retry #{}", i + 1);
if i < MAX_RETRIES {
i += 1;
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
Expand All @@ -66,7 +66,7 @@ pub async fn run(
}
};
for i in 0..MAX_RETRIES {
match set_current_height(&new_height, parent_hash.height) {
match set_current_height(&new_height, parent_height) {
Ok(()) => {
break;
}
Expand Down Expand Up @@ -144,10 +144,18 @@ async fn process_message(database: &mut Database, message: sigma_order::Message)
}
sigma_order::Message::GetParentHash(sender) => {
let current_hash = get_current_hash(database).await;
if let Ok(current_hash) = current_hash {
if let Err(e) = sender.send(current_hash) {
tracing::error!(error = ?e, "Failed to send current hash");
}
if let Ok(current_hash) = current_hash
&& let Err(e) = sender.send(current_hash)
{
tracing::error!(error = ?e, "Failed to send current hash");
}
}
sigma_order::Message::GetParentHeight(sender) => {
let current_height = get_current_height(database).await;
if let Ok(current_height) = current_height
&& let Err(e) = sender.send(current_height)
{
tracing::error!(error = ?e, "Failed to send current height");
}
}
}
Expand Down Expand Up @@ -195,7 +203,7 @@ async fn create_tables(database: &mut Database) -> Result<(), Error> {
async fn add_event_and_hash(
database: &mut Database,
event: Signed<Event>,
hash: Signed<Hash>,
hash: Option<Signed<Hash>>,
) -> Result<(), Error> {
match database {
Database::Memory(db) => {
Expand Down Expand Up @@ -236,3 +244,11 @@ async fn get_current_hash(database: &mut Database) -> Result<Hash, Error> {
Database::Sqlite(db) => Ok(db.get_current_hash().await?),
}
}

async fn get_current_height(database: &mut Database) -> Result<Height, Error> {
match database {
Database::Memory(db) => Ok(db.get_current_height()),
Database::Rqlite(db) => Ok(db.get_current_height().await?),
Database::Sqlite(db) => Ok(db.get_current_height().await?),
}
}
25 changes: 21 additions & 4 deletions crates/sigma-db/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,19 @@ impl MemoryDb {
MemoryDb::default()
}

pub fn add_event_and_hash(&mut self, event: Signed<Event>, hash: Signed<Hash>) {
if (self.hashes.len() as u64) == hash.data.height {
self.hashes.push(hash);
self.events.push(event);
pub fn add_event_and_hash(&mut self, event: Signed<Event>, hash: Option<Signed<Hash>>) {
match hash {
Some(hash) => {
if (self.hashes.len() as u64) == hash.data.height {
self.hashes.push(hash);
self.events.push(event);
}
}
None => {
if (self.events.len() as u64) == event.data.height {
self.events.push(event);
}
}
}
}

Expand All @@ -40,4 +49,12 @@ impl MemoryDb {
.map(|signed_hash| signed_hash.data)
.unwrap_or_else(Hash::big_bang_hash)
}

pub fn get_current_height(&self) -> Height {
if self.events.is_empty() {
Height::MAX
} else {
self.events.last().unwrap().data.height
}
}
}
41 changes: 31 additions & 10 deletions crates/sigma-db/src/rqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use reqwest::{Client, Url};
use serde_json::Value;
use sigma_db_sql::{
insert,
query::{EVENTS_RANGE, HASHES_RANGE, PARENT_HASH},
query::{CURRENT_HEIGHT, EVENTS_RANGE, HASHES_RANGE, PARENT_HASH},
};
use sigma_types::{Event, EventData, Hash, Height, Signed, StreamTypeId};
use thiserror::Error;
Expand Down Expand Up @@ -98,7 +98,7 @@ impl Rqlite {
pub async fn add_event_and_hash(
&self,
event: Signed<Event>,
hash: Signed<Hash>,
hash: Option<Signed<Hash>>,
) -> Result<(), Error> {
let event_sql = include_sql! {
insert::EVENTS,
Expand All @@ -107,14 +107,19 @@ impl Rqlite {
event.data.event_data.stream_type as u64,
event.data.event_data.data
};
let hash_sql = include_sql! {
insert::HASHES,
hash.data.height,
hash.signature,
hash.data.bytes
};

self.execute(&[event_sql, hash_sql]).await
match hash {
Some(hash) => {
let hash_sql = include_sql! {
insert::HASHES,
hash.data.height,
hash.signature,
hash.data.bytes
};

self.execute(&[event_sql, hash_sql]).await
}
None => self.execute(&[event_sql]).await,
}
}

pub async fn get_events_range(
Expand Down Expand Up @@ -192,6 +197,22 @@ impl Rqlite {
.unwrap_or_else(Hash::big_bang_hash))
}

pub async fn get_current_height(&self) -> Result<Height, Error> {
let sql = include_sql! { CURRENT_HEIGHT };
let from_values = |values: Vec<Value>| -> Result<Height, Error> {
let mut iter = values.into_iter();
let height = serde_json::from_value(iter.next().ok_or(Error::FailToDeserialize)?)?;

Ok(height)
};
Ok(self
.query_values_strong(sql, from_values)
.await?
.into_iter()
.next()
.unwrap_or(Height::MAX))
}

async fn query_values_weak<T, F>(
&self,
sql: &[serde_json::Value],
Expand Down
16 changes: 8 additions & 8 deletions crates/sigma-db/src/rqlite/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async fn test_add_events_and_hashes() {
let hash = h(0, [42; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -71,7 +71,7 @@ async fn test_add_events_and_hashes() {
let hash = h(0, [43; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down Expand Up @@ -108,7 +108,7 @@ async fn test_get_events() {
let hash = h(0, [42; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -126,7 +126,7 @@ async fn test_get_events() {
let hash = h(1, [43; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down Expand Up @@ -188,7 +188,7 @@ async fn test_get_hashes() {
let hash = h(0, [42; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -205,7 +205,7 @@ async fn test_get_hashes() {
let hash = h(1, [43; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down Expand Up @@ -263,7 +263,7 @@ async fn test_get_current_hash() {
let hash = h(0, [42; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -279,7 +279,7 @@ async fn test_get_current_hash() {
let hash = h(1, [43; 32]);

rqlite
.add_event_and_hash(event, hash)
.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down
41 changes: 36 additions & 5 deletions crates/sigma-db/src/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl Sqlite {
pub async fn add_event_and_hash(
&mut self,
event: Signed<Event>,
hash: Signed<sigma_types::Hash>,
hash: Option<Signed<sigma_types::Hash>>,
) -> Result<(), Error> {
let mut write = match self.conn.take() {
Some(conn) => conn,
Expand All @@ -95,10 +95,12 @@ impl Sqlite {
],
)?;

tx.execute(
insert::HASHES,
params![hash.data.height, hash.signature, hash.data.bytes],
)?;
if let Some(hash) = hash {
tx.execute(
insert::HASHES,
params![hash.data.height, hash.signature, hash.data.bytes],
)?;
}

tx.commit()?;

Expand Down Expand Up @@ -239,4 +241,33 @@ impl Sqlite {
}
}
}

pub async fn get_current_height(&mut self) -> Result<Height, Error> {
let read = match self.conn.take() {
Some(conn) => conn,
None => new_connection(&self.path)?,
};
let r = tokio::task::spawn_blocking(move || {
let mut stmt = read.prepare_cached(query::CURRENT_HEIGHT)?;
let height = stmt.query_one(params![], |row| row.get(0)).optional()?;

drop(stmt);

let height = height.unwrap_or(Height::MAX);

Ok::<_, Error>((read, height))
})
.await?;

match r {
Ok((conn, height)) => {
self.conn = Some(conn);
Ok(height)
}
Err(e) => {
self.conn = Some(new_connection(&self.path)?);
Err(e)
}
}
}
}
16 changes: 8 additions & 8 deletions crates/sigma-db/src/sqlite/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ async fn test_add_events_and_hashes() {
let event = e(0, &[1, 2, 3]);
let hash = h(0, [42; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

// Double insert at same height should not change the database
let event = e(0, &[4, 5, 6]);
let hash = h(0, [43; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down Expand Up @@ -93,7 +93,7 @@ async fn test_get_events() {
let event = e(0, &[1, 2, 3]);
let hash = h(0, [42; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -110,7 +110,7 @@ async fn test_get_events() {
let event = e(1, &[4, 5, 6]);
let hash = h(1, [43; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down Expand Up @@ -166,7 +166,7 @@ async fn test_get_hashes() {
let event = e(0, &[1, 2, 3]);
let hash = h(0, [42; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -182,7 +182,7 @@ async fn test_get_hashes() {
let event = e(1, &[4, 5, 6]);
let hash = h(1, [43; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down Expand Up @@ -234,7 +234,7 @@ async fn test_get_current_hash() {
let event = e(0, &[1, 2, 3]);
let hash = h(0, [42; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand All @@ -249,7 +249,7 @@ async fn test_get_current_hash() {
let event = e(1, &[4, 5, 6]);
let hash = h(1, [43; 32]);

db.add_event_and_hash(event, hash)
db.add_event_and_hash(event, hash.into())
.await
.expect("Failed to add event and hash");

Expand Down
Loading