Skip to content

Commit 0008baf

Browse files
committed
feat: implement 'BlockRangeRootRetriever' for 'CardanoTransactionsRepository' in signer
1 parent a7eeff9 commit 0008baf

File tree

3 files changed

+79
-5
lines changed

3 files changed

+79
-5
lines changed

mithril-signer/src/database/provider/block_range_root/get_block_range_root.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use mithril_persistence::sqlite::{Provider, SourceAlias, SqLiteEntity, SqliteConnection};
1+
use mithril_common::entities::BlockNumber;
2+
use mithril_persistence::sqlite::{
3+
Provider, SourceAlias, SqLiteEntity, SqliteConnection, WhereCondition,
4+
};
5+
use sqlite::Value;
26

37
use crate::database::record::BlockRangeRootRecord;
48

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

1014
impl<'client> GetBlockRangeRootProvider<'client> {
11-
#[cfg(test)]
1215
/// Create a new instance
1316
pub fn new(connection: &'client SqliteConnection) -> Self {
1417
Self { connection }
1518
}
19+
20+
pub fn get_up_to_block_number_condition(&self, block_number: BlockNumber) -> WhereCondition {
21+
WhereCondition::new("end <= ?*", vec![Value::Integer(block_number as i64)])
22+
}
1623
}
1724

1825
#[cfg(test)]

mithril-signer/src/database/provider/block_range_root/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ mod get_block_range_root;
22
mod get_interval_without_block_range_provider;
33
mod insert_block_range;
44

5-
#[cfg(test)]
65
pub use get_block_range_root::*;
76
pub use get_interval_without_block_range_provider::*;
87
pub use insert_block_range::*;

mithril-signer/src/database/repository/cardano_transaction_repository.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ use mithril_common::entities::{
99
BlockHash, BlockNumber, BlockRange, CardanoTransaction, ImmutableFileNumber, SlotNumber,
1010
TransactionHash,
1111
};
12+
use mithril_common::signable_builder::BlockRangeRootRetriever;
1213
use mithril_common::StdResult;
1314
use mithril_persistence::sqlite::{Provider, SqliteConnection, WhereCondition};
15+
use sqlite::Value;
1416

1517
use crate::database::provider::{
16-
GetCardanoTransactionProvider, GetIntervalWithoutBlockRangeRootProvider,
17-
InsertBlockRangeRootProvider, InsertCardanoTransactionProvider,
18+
GetBlockRangeRootProvider, GetCardanoTransactionProvider,
19+
GetIntervalWithoutBlockRangeRootProvider, InsertBlockRangeRootProvider,
20+
InsertCardanoTransactionProvider,
1821
};
1922
use crate::database::record::{BlockRangeRootRecord, CardanoTransactionRecord};
2023
use crate::TransactionStore;
@@ -130,6 +133,48 @@ impl CardanoTransactionRepository {
130133

131134
Ok(cursor.collect())
132135
}
136+
137+
// TODO: remove this function when the Cardano transaction signature is based on block number instead of immutable number
138+
async fn get_highest_block_number_for_immutable_number(
139+
&self,
140+
immutable_file_number: ImmutableFileNumber,
141+
) -> StdResult<Option<BlockNumber>> {
142+
let sql =
143+
"select max(block_number) as highest from cardano_tx where immutable_file_number <= $1;";
144+
match self
145+
.connection
146+
.prepare(sql)
147+
.with_context(|| {
148+
format!(
149+
"Prepare query error: SQL=`{}`",
150+
&sql.replace('\n', " ").trim()
151+
)
152+
})?
153+
.iter()
154+
.bind::<&[(_, Value)]>(&[(1, Value::Integer(immutable_file_number as i64))])?
155+
.next()
156+
{
157+
None => Ok(None),
158+
Some(row) => {
159+
let highest = row?.read::<Option<i64>, _>(0);
160+
highest
161+
.map(u64::try_from)
162+
.transpose()
163+
.with_context(||
164+
format!("Integer field max(block_number) (value={highest:?}) is incompatible with u64 representation.")
165+
)
166+
}
167+
}
168+
}
169+
170+
#[cfg(test)]
171+
pub(crate) async fn get_all(&self) -> StdResult<Vec<CardanoTransaction>> {
172+
let provider = GetCardanoTransactionProvider::new(&self.connection);
173+
let filters = WhereCondition::default();
174+
let transactions = provider.find(filters)?;
175+
176+
Ok(transactions.map(|record| record.into()).collect::<Vec<_>>())
177+
}
133178
}
134179

135180
#[cfg(test)]
@@ -234,6 +279,29 @@ impl TransactionStore for CardanoTransactionRepository {
234279
}
235280
}
236281

282+
#[async_trait]
283+
impl BlockRangeRootRetriever for CardanoTransactionRepository {
284+
async fn retrieve_block_range_roots(
285+
&self,
286+
up_to_beacon: ImmutableFileNumber,
287+
) -> StdResult<Box<dyn Iterator<Item = (BlockRange, MKTreeNode)>>> {
288+
let block_number = self
289+
.get_highest_block_number_for_immutable_number(up_to_beacon)
290+
.await?
291+
.unwrap_or(0);
292+
let provider = GetBlockRangeRootProvider::new(&self.connection);
293+
let filters = provider.get_up_to_block_number_condition(block_number);
294+
let block_range_roots = provider.find(filters)?;
295+
let iterator = block_range_roots
296+
.into_iter()
297+
.map(|record| -> (BlockRange, MKTreeNode) { record.into() })
298+
.collect::<Vec<_>>() // TODO: remove this collect when we should ba able return the iterator directly
299+
.into_iter();
300+
301+
Ok(Box::new(iterator))
302+
}
303+
}
304+
237305
#[cfg(test)]
238306
mod tests {
239307
use mithril_persistence::sqlite::GetAllProvider;

0 commit comments

Comments
 (0)