Skip to content

Commit adae970

Browse files
committed
feat: implement 'BlockRangeRootRetriever' for 'CardanoTransactionsRepository' in aggregator
1 parent dc174ba commit adae970

File tree

4 files changed

+92
-20
lines changed

4 files changed

+92
-20
lines changed

mithril-aggregator/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-aggregator/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-aggregator/src/database/provider/cardano_transaction/get_cardano_transaction.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::ops::Range;
22

33
use sqlite::Value;
44

5-
use mithril_common::entities::{BlockNumber, ImmutableFileNumber, TransactionHash};
5+
use mithril_common::entities::{BlockNumber, TransactionHash};
66
use mithril_persistence::sqlite::{
77
Provider, SourceAlias, SqLiteEntity, SqliteConnection, WhereCondition,
88
};
@@ -40,16 +40,6 @@ impl<'client> GetCardanoTransactionProvider<'client> {
4040
WhereCondition::where_in("transaction_hash", hashes_values)
4141
}
4242

43-
pub fn get_transaction_up_to_beacon_condition(
44-
&self,
45-
beacon: ImmutableFileNumber,
46-
) -> WhereCondition {
47-
WhereCondition::new(
48-
"immutable_file_number <= ?*",
49-
vec![Value::Integer(beacon as i64)],
50-
)
51-
}
52-
5343
pub fn get_transaction_between_blocks_condition(
5444
&self,
5545
range: Range<BlockNumber>,

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

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ use mithril_common::entities::{
99
BlockHash, BlockNumber, BlockRange, CardanoDbBeacon, CardanoTransaction, ImmutableFileNumber,
1010
SlotNumber, 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::services::{TransactionStore, TransactionsRetriever};
@@ -60,8 +63,14 @@ impl CardanoTransactionRepository {
6063
&self,
6164
beacon: ImmutableFileNumber,
6265
) -> StdResult<Vec<CardanoTransactionRecord>> {
66+
// Get the highest block number for the given immutable number.
67+
// This is a temporary fix that will be removed when the retrieval is based on block number instead of immutable number.
68+
let block_number = self
69+
.get_highest_block_number_for_immutable_number(beacon)
70+
.await?
71+
.unwrap_or(0);
6372
let provider = GetCardanoTransactionProvider::new(&self.connection);
64-
let filters = provider.get_transaction_up_to_beacon_condition(beacon);
73+
let filters = provider.get_transaction_between_blocks_condition(0..block_number);
6574
let transactions = provider.find(filters)?;
6675

6776
Ok(transactions.collect())
@@ -130,6 +139,48 @@ impl CardanoTransactionRepository {
130139

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

135186
#[cfg(test)]
@@ -261,6 +312,31 @@ impl TransactionsRetriever for CardanoTransactionRepository {
261312
}
262313
}
263314

315+
#[async_trait]
316+
impl BlockRangeRootRetriever for CardanoTransactionRepository {
317+
async fn retrieve_block_range_roots(
318+
&self,
319+
up_to_beacon: ImmutableFileNumber,
320+
) -> StdResult<Box<dyn Iterator<Item = (BlockRange, MKTreeNode)>>> {
321+
// Get the highest block number for the given immutable number.
322+
// This is a temporary fix that will be removed when the retrieval is based on block number instead of immutable number.
323+
let block_number = self
324+
.get_highest_block_number_for_immutable_number(up_to_beacon)
325+
.await?
326+
.unwrap_or(0);
327+
let provider = GetBlockRangeRootProvider::new(&self.connection);
328+
let filters = provider.get_up_to_block_number_condition(block_number);
329+
let block_range_roots = provider.find(filters)?;
330+
let block_range_roots = block_range_roots
331+
.into_iter()
332+
.map(|record| -> (BlockRange, MKTreeNode) { record.into() })
333+
.collect::<Vec<_>>() // TODO: remove this collect when we should ba able return the iterator directly
334+
.into_iter();
335+
336+
Ok(Box::new(block_range_roots))
337+
}
338+
}
339+
264340
#[cfg(test)]
265341
mod tests {
266342
use mithril_persistence::sqlite::GetAllProvider;
@@ -413,7 +489,7 @@ mod tests {
413489
let cardano_transactions: Vec<CardanoTransactionRecord> = (20..=40)
414490
.map(|i| CardanoTransactionRecord {
415491
transaction_hash: format!("tx-hash-{i}"),
416-
block_number: i % 10,
492+
block_number: i / 10,
417493
slot_number: i * 100,
418494
block_hash: format!("block-hash-{i}"),
419495
immutable_file_number: i,
@@ -425,10 +501,10 @@ mod tests {
425501
.unwrap();
426502

427503
let transaction_result = repository.get_transactions_up_to(34).await.unwrap();
428-
assert_eq!(cardano_transactions[0..=14].to_vec(), transaction_result);
504+
assert_eq!(cardano_transactions[0..10].to_vec(), transaction_result);
429505

430506
let transaction_result = repository.get_transactions_up_to(300).await.unwrap();
431-
assert_eq!(cardano_transactions.clone(), transaction_result);
507+
assert_eq!(cardano_transactions[0..20].to_vec(), transaction_result);
432508

433509
let transaction_result = repository.get_transactions_up_to(19).await.unwrap();
434510
assert_eq!(Vec::<CardanoTransactionRecord>::new(), transaction_result);

0 commit comments

Comments
 (0)