Skip to content

Commit

Permalink
feat: implement 'BlockRangeRootRetriever' for 'CardanoTransactionsRep…
Browse files Browse the repository at this point in the history
…ository' in signer
  • Loading branch information
jpraynaud committed Apr 29, 2024
1 parent 45bc9db commit edaaa72
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use mithril_persistence::sqlite::{Provider, SourceAlias, SqLiteEntity, SqliteConnection};
use mithril_common::entities::BlockNumber;
use mithril_persistence::sqlite::{
Provider, SourceAlias, SqLiteEntity, SqliteConnection, WhereCondition,
};
use sqlite::Value;

use crate::database::record::BlockRangeRootRecord;

Expand All @@ -8,11 +12,14 @@ pub struct GetBlockRangeRootProvider<'client> {
}

impl<'client> GetBlockRangeRootProvider<'client> {
#[cfg(test)]
/// Create a new instance
pub fn new(connection: &'client SqliteConnection) -> Self {
Self { connection }
}

pub fn get_up_to_block_number_condition(&self, block_number: BlockNumber) -> WhereCondition {
WhereCondition::new("end <= ?*", vec![Value::Integer(block_number as i64)])
}
}

#[cfg(test)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ mod get_block_range_root;
mod get_interval_without_block_range_provider;
mod insert_block_range;

#[cfg(test)]
pub use get_block_range_root::*;
pub use get_interval_without_block_range_provider::*;
pub use insert_block_range::*;
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ use mithril_common::entities::{
BlockHash, BlockNumber, BlockRange, CardanoTransaction, ImmutableFileNumber, SlotNumber,
TransactionHash,
};
use mithril_common::signable_builder::BlockRangeRootRetriever;
use mithril_common::StdResult;
use mithril_persistence::sqlite::{Provider, SqliteConnection, WhereCondition};
use sqlite::Value;

use crate::database::provider::{
GetCardanoTransactionProvider, GetIntervalWithoutBlockRangeRootProvider,
InsertBlockRangeRootProvider, InsertCardanoTransactionProvider,
GetBlockRangeRootProvider, GetCardanoTransactionProvider,
GetIntervalWithoutBlockRangeRootProvider, InsertBlockRangeRootProvider,
InsertCardanoTransactionProvider,
};
use crate::database::record::{BlockRangeRootRecord, CardanoTransactionRecord};
use crate::TransactionStore;
Expand Down Expand Up @@ -130,6 +133,48 @@ impl CardanoTransactionRepository {

Ok(cursor.collect())
}

// TODO: remove this function when the Cardano transaction signature is based on block number instead of immutable number
async fn get_highest_block_number_for_immutable_number(
&self,
immutable_file_number: ImmutableFileNumber,
) -> StdResult<Option<BlockNumber>> {
let sql =
"select max(block_number) as highest from cardano_tx where immutable_file_number <= $1;";
match self
.connection
.prepare(sql)
.with_context(|| {
format!(
"Prepare query error: SQL=`{}`",
&sql.replace('\n', " ").trim()
)
})?
.iter()
.bind::<&[(_, Value)]>(&[(1, Value::Integer(immutable_file_number as i64))])?
.next()
{
None => Ok(None),
Some(row) => {
let highest = row?.read::<Option<i64>, _>(0);
highest
.map(u64::try_from)
.transpose()
.with_context(||
format!("Integer field max(block_number) (value={highest:?}) is incompatible with u64 representation.")
)
}
}
}

#[cfg(test)]
pub(crate) async fn get_all(&self) -> StdResult<Vec<CardanoTransaction>> {
let provider = GetCardanoTransactionProvider::new(&self.connection);
let filters = WhereCondition::default();
let transactions = provider.find(filters)?;

Ok(transactions.map(|record| record.into()).collect::<Vec<_>>())
}
}

#[cfg(test)]
Expand Down Expand Up @@ -234,6 +279,29 @@ impl TransactionStore for CardanoTransactionRepository {
}
}

#[async_trait]
impl BlockRangeRootRetriever for CardanoTransactionRepository {
async fn retrieve_block_range_roots(
&self,
up_to_beacon: ImmutableFileNumber,
) -> StdResult<Box<dyn Iterator<Item = (BlockRange, MKTreeNode)>>> {
let block_number = self
.get_highest_block_number_for_immutable_number(up_to_beacon)
.await?
.unwrap_or(0);
let provider = GetBlockRangeRootProvider::new(&self.connection);
let filters = provider.get_up_to_block_number_condition(block_number);
let block_range_roots = provider.find(filters)?;
let iterator = block_range_roots
.into_iter()
.map(|record| -> (BlockRange, MKTreeNode) { record.into() })
.collect::<Vec<_>>() // TODO: remove this collect when we should ba able return the iterator directly
.into_iter();

Ok(Box::new(iterator))
}
}

#[cfg(test)]
mod tests {
use mithril_persistence::sqlite::GetAllProvider;
Expand Down

0 comments on commit edaaa72

Please sign in to comment.