Skip to content

Commit

Permalink
Remove all references in signer to the `mithril_persistence::adapte…
Browse files Browse the repository at this point in the history
…r` module
  • Loading branch information
sfauvel committed Nov 18, 2024
1 parent e7f2282 commit 970f71a
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
};
use mithril_common::{crypto_helper::ProtocolInitializer, entities::Epoch, StdResult};
use mithril_persistence::sqlite::ConnectionExtensions;
use mithril_persistence::{sqlite::SqliteConnection, store::adapter::StoreAdapter};
use mithril_persistence::{sqlite::SqliteConnection /*store::adapter::StoreAdapter*/};

/// Implementation of the ProtocolInitializerStorer
pub struct ProtocolInitializerRepository {
Expand Down Expand Up @@ -95,13 +95,9 @@ impl ProtocolInitializerStorer for ProtocolInitializerRepository {

#[cfg(test)]
mod tests {
use crate::database::test_helper::{main_db_connection, FakeStoreAdapter};
use mithril_common::test_utils::fake_data;
use mithril_persistence::{
sqlite::{ConnectionBuilder, ConnectionOptions},
store::adapter::SQLiteAdapter,
};

use crate::database::test_helper::main_db_connection;
use mithril_persistence::sqlite::{ConnectionBuilder, ConnectionOptions};

use super::*;

Expand Down Expand Up @@ -263,29 +259,25 @@ mod tests {
.with_options(&[ConnectionOptions::ForceDisableForeignKeys])
}
let connection = Arc::new(create_connection_builder().build().unwrap());

let protocol_initializer_adapter =
FakeStoreAdapter::new(connection.clone(), "protocol_initializer");
// The adapter will create the table.
let mut adapter = SQLiteAdapter::<Epoch, ProtocolInitializer>::new(
"protocol_initializer",
connection.clone(),
)
.unwrap();
protocol_initializer_adapter.create_table();

assert!(connection
.prepare("select key_hash from protocol_initializer;")
.is_ok());
assert!(connection.prepare("select * from db_version;").is_err());

// Here we can add some data with the old schema.
let (_, protocol_initializer_to_retrieve) = &setup_protocol_initializers(1)[0];

// If we don't want to use the adapter anymore, we can execute request directly.
assert!(adapter.get_record(&Epoch(5)).await.unwrap().is_none());
adapter
.store_record(&Epoch(5), &protocol_initializer_to_retrieve)
.await
assert!(!protocol_initializer_adapter.is_key_hash_exist("HashEpoch5"));

protocol_initializer_adapter
.store_record("HashEpoch5", &Epoch(5), protocol_initializer_to_retrieve)
.unwrap();
assert!(adapter.get_record(&Epoch(5)).await.unwrap().is_some());

assert!(protocol_initializer_adapter.is_key_hash_exist("HashEpoch5"));

// We finish the migration
create_connection_builder()
Expand Down
48 changes: 12 additions & 36 deletions mithril-signer/src/database/repository/stake_pool_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use mithril_common::entities::{Epoch, StakeDistribution};
use mithril_common::signable_builder::StakeDistributionRetriever;
use mithril_common::StdResult;
use mithril_persistence::sqlite::{ConnectionExtensions, SqliteConnection};
use mithril_persistence::store::adapter::AdapterError;
use mithril_persistence::store::StakeStorer;

use crate::database::query::{
Expand Down Expand Up @@ -51,8 +50,7 @@ impl StakeStorer for StakePoolStore {
.map(|(pool_id, stake)| (pool_id, epoch, stake))
.collect(),
))
.with_context(|| format!("persist stakes failure, epoch: {epoch}"))
.map_err(AdapterError::GeneralError)?;
.with_context(|| format!("persist stakes failure, epoch: {epoch}"))?;

Ok(Some(StakeDistribution::from_iter(
pools.into_iter().map(|p| (p.stake_pool_id, p.stake)),
Expand All @@ -63,8 +61,7 @@ impl StakeStorer for StakePoolStore {
let cursor = self
.connection
.fetch(GetStakePoolQuery::by_epoch(epoch)?)
.with_context(|| format!("get stakes failure, epoch: {epoch}"))
.map_err(AdapterError::GeneralError)?;
.with_context(|| format!("get stakes failure, epoch: {epoch}"))?;
let mut stake_distribution = StakeDistribution::new();

for stake_pool in cursor {
Expand Down Expand Up @@ -96,24 +93,18 @@ impl EpochPruningTask for StakePoolStore {
self.connection
.apply(DeleteStakePoolQuery::below_epoch_threshold(
epoch - threshold,
))
.map_err(AdapterError::QueryError)?;
))?;
}
Ok(())
}
}

#[cfg(test)]
mod tests {
use mithril_persistence::{
database::SqlMigration,
sqlite::{ConnectionBuilder, ConnectionOptions},
store::adapter::SQLiteAdapter,
};
use mithril_persistence::sqlite::{ConnectionBuilder, ConnectionOptions};

use super::*;
use crate::database::test_helper::{insert_stake_pool, main_db_connection};
use mithril_persistence::store::adapter::StoreAdapter;
use crate::database::test_helper::{insert_stake_pool, main_db_connection, FakeStoreAdapter};

#[tokio::test]
async fn prune_epoch_settings_older_than_threshold() {
Expand Down Expand Up @@ -200,39 +191,24 @@ mod tests {
let connection = Arc::new(create_connection_builder().build().unwrap());

// The adapter will create the table.
let mut adapter =
SQLiteAdapter::<Epoch, StakeDistribution>::new("stake", connection.clone()).unwrap();
let stake_adapter = FakeStoreAdapter::new(connection.clone(), "stake");
// The adapter will create the table.
stake_adapter.create_table();

assert!(connection.prepare("select * from stake;").is_ok());
assert!(connection.prepare("select * from db_version;").is_err());
assert!(connection.prepare("select * from stake_pool;").is_err());

// TODO: We recreate a Builder (because it was consume by the build) to have same option but we don't use a new connection.
// builder is needed for options, base_logger and node_type.
create_connection_builder()
.apply_migrations(
&connection.clone(),
migrations
.clone()
.into_iter()
.filter(|migration| migration.version <= 1)
.collect::<Vec<SqlMigration>>(),
)
.unwrap();
assert!(connection.prepare("select * from db_version;").is_ok());
assert!(connection.prepare("select * from stake_pool;").is_err());

// Here we can add some data with the old schema.
let stake_distribution_to_retrieve =
StakeDistribution::from([("pool-123".to_string(), 123)]);

// If we don't want to use the adapter anymore, we can execute request directly.
assert!(adapter.get_record(&Epoch(5)).await.unwrap().is_none());
adapter
.store_record(&Epoch(5), &stake_distribution_to_retrieve)
.await
assert!(!stake_adapter.is_key_hash_exist("HashEpoch5"));
stake_adapter
.store_record("HashEpoch5", &Epoch(5), &stake_distribution_to_retrieve)
.unwrap();
assert!(adapter.get_record(&Epoch(5)).await.unwrap().is_some());
assert!(stake_adapter.is_key_hash_exist("HashEpoch5"));

// We finish the migration
create_connection_builder()
Expand Down
51 changes: 51 additions & 0 deletions mithril-signer/src/database/test_helper.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::path::Path;
use std::sync::Arc;

use chrono::Utc;
use mithril_common::entities::Epoch;
use mithril_common::StdResult;
use mithril_persistence::sqlite::{
ConnectionBuilder, ConnectionExtensions, ConnectionOptions, Query, SqliteConnection,
};
use serde::Serialize;
use sqlite::Value;

use crate::database::query::{InsertOrReplaceStakePoolQuery, InsertSignedBeaconRecordQuery};
Expand Down Expand Up @@ -102,3 +104,52 @@ pub fn insert_stake_pool(

Ok(())
}

/// A simple struct that help to initialize database with the old adapter behavior for testing purposes.
pub struct FakeStoreAdapter {
connection: Arc<SqliteConnection>,
table: &'static str,
}

impl FakeStoreAdapter {
pub fn new(connection: Arc<SqliteConnection>, table: &'static str) -> Self {
Self { connection, table }
}

pub fn create_table(&self) {
let sql = format!(
"create table {} (key_hash text primary key, key json not null, value json not null)",
self.table
);
self.connection.execute(sql).unwrap();
}

pub fn is_key_hash_exist(&self, key_hash: &str) -> bool {
let sql = format!(
"select exists(select 1 from {} where key_hash = ?1) as record_exists",
self.table
);
let parameters = [Value::String(key_hash.to_string())];
let result: i64 = self.connection.query_single_cell(sql, &parameters).unwrap();
result == 1
}

pub fn store_record<K: Serialize, V: Serialize>(
&self,
key_hash: &str,
key: &K,
record: &V,
) -> StdResult<()> {
let sql = format!(
"insert into {} (key_hash, key, value) values (?1, ?2, ?3) on conflict (key_hash) do update set value = excluded.value",
self.table
);
let mut statement = self.connection.prepare(sql)?;
statement.bind((1, key_hash))?;
statement.bind((2, serde_json::to_string(&key)?.as_str()))?;
statement.bind((3, serde_json::to_string(record)?.as_str()))?;
let _ = statement.next()?;

Ok(())
}
}

0 comments on commit 970f71a

Please sign in to comment.