Skip to content

Commit 1bea5eb

Browse files
authored
Merge pull request #1703 from input-output-hk/ensemble/1667/create-test-ctx-builder
Create a test Cardano transactions builder
2 parents 1ef4fb7 + c8342cb commit 1bea5eb

File tree

9 files changed

+509
-104
lines changed

9 files changed

+509
-104
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/mithril-persistence/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-persistence"
3-
version = "0.1.12"
3+
version = "0.1.13"
44
description = "Common types, interfaces, and utilities to persist data for Mithril nodes."
55
authors = { workspace = true }
66
edition = { workspace = true }

internal/mithril-persistence/src/database/repository/cardano_transaction_repository.rs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,19 @@ impl CardanoTransactionRepository {
6868
) -> StdResult<Vec<CardanoTransactionRecord>> {
6969
// Get the highest block number for the given immutable number.
7070
// This is a temporary fix that will be removed when the retrieval is based on block number instead of immutable number.
71-
let block_number = self
71+
72+
if let Some(block_number) = self
7273
.get_highest_block_number_for_immutable_number(beacon)
7374
.await?
74-
.unwrap_or(0);
75-
let provider = GetCardanoTransactionProvider::new(&self.connection);
76-
let filters = provider.get_transaction_between_blocks_condition(0..block_number + 1);
77-
let transactions = provider.find(filters)?;
75+
{
76+
let provider = GetCardanoTransactionProvider::new(&self.connection);
77+
let filters = provider.get_transaction_between_blocks_condition(0..block_number + 1);
78+
let transactions = provider.find(filters)?;
7879

79-
Ok(transactions.collect())
80+
Ok(transactions.collect())
81+
} else {
82+
Ok(vec![])
83+
}
8084
}
8185

8286
/// Return the [CardanoTransactionRecord] for the given transaction hash.
@@ -324,6 +328,8 @@ impl BlockRangeRootRetriever for CardanoTransactionRepository {
324328

325329
#[cfg(test)]
326330
mod tests {
331+
use mithril_common::test_utils::CardanoTransactionsBuilder;
332+
327333
use crate::database::provider::GetBlockRangeRootProvider;
328334
use crate::database::test_helper::cardano_tx_db_connection;
329335
use crate::sqlite::GetAllProvider;
@@ -470,23 +476,20 @@ mod tests {
470476
let connection = Arc::new(cardano_tx_db_connection().unwrap());
471477
let repository = CardanoTransactionRepository::new(connection);
472478

473-
// Build transactions with block numbers from 20 to 40 and immutable file numbers from 12 to 14
474-
let cardano_transactions: Vec<CardanoTransactionRecord> = (20..=40)
475-
.map(|i| CardanoTransactionRecord {
476-
transaction_hash: format!("tx-hash-{i}"),
477-
block_number: i,
478-
slot_number: i * 100,
479-
block_hash: format!("block-hash-{i}"),
480-
immutable_file_number: i / 10 + 10,
481-
})
479+
let cardano_transactions: Vec<CardanoTransactionRecord> = CardanoTransactionsBuilder::new()
480+
.max_transactions_per_immutable_file(10)
481+
.first_immutable_file(120)
482+
.build_transactions(40)
483+
.into_iter()
484+
.map(CardanoTransactionRecord::from)
482485
.collect();
483486

484487
repository
485488
.create_transactions(cardano_transactions.clone())
486489
.await
487490
.unwrap();
488491

489-
let transaction_result = repository.get_transactions_up_to(12).await.unwrap();
492+
let transaction_result = repository.get_transactions_up_to(120).await.unwrap();
490493
let transaction_up_to_immutable_file_number_12 = cardano_transactions[0..10].to_vec();
491494
assert_eq!(
492495
transaction_up_to_immutable_file_number_12,
@@ -497,7 +500,28 @@ mod tests {
497500
let transaction_all = cardano_transactions[..].to_vec();
498501
assert_eq!(transaction_all, transaction_result);
499502

500-
let transaction_result = repository.get_transactions_up_to(9).await.unwrap();
503+
let transaction_result = repository.get_transactions_up_to(90).await.unwrap();
504+
assert_eq!(Vec::<CardanoTransactionRecord>::new(), transaction_result);
505+
}
506+
507+
#[tokio::test]
508+
async fn get_transactions_up_to_return_empty_list_when_no_record_found_with_provided_immutable_file_number(
509+
) {
510+
let connection = Arc::new(cardano_tx_db_connection().unwrap());
511+
let repository = CardanoTransactionRepository::new(connection);
512+
513+
repository
514+
.create_transactions(vec![CardanoTransaction::new(
515+
"tx-hash-123".to_string(),
516+
0,
517+
50,
518+
"block-hash-0",
519+
99,
520+
)])
521+
.await
522+
.unwrap();
523+
524+
let transaction_result = repository.get_transactions_up_to(90).await.unwrap();
501525
assert_eq!(Vec::<CardanoTransactionRecord>::new(), transaction_result);
502526
}
503527

@@ -525,7 +549,7 @@ mod tests {
525549
}
526550

527551
#[tokio::test]
528-
async fn repository_store_transactions_with_existing_hash_doesnt_erase_existing_data() {
552+
async fn repository_store_transactions_doesnt_erase_existing_data() {
529553
let connection = Arc::new(cardano_tx_db_connection().unwrap());
530554
let repository = CardanoTransactionRepository::new(connection);
531555

@@ -871,21 +895,18 @@ mod tests {
871895
let connection = Arc::new(cardano_tx_db_connection().unwrap());
872896
let repository = CardanoTransactionRepository::new(connection);
873897

874-
// Build transactions with block numbers from 20 to 50
875-
let cardano_transactions: Vec<CardanoTransactionRecord> = (20..=50)
876-
.map(|i| CardanoTransactionRecord {
877-
transaction_hash: format!("tx-hash-{i}"),
878-
block_number: i,
879-
slot_number: i * 100,
880-
block_hash: format!("block-hash-{i}"),
881-
immutable_file_number: 1,
882-
})
898+
let cardano_transactions: Vec<CardanoTransactionRecord> = CardanoTransactionsBuilder::new()
899+
.blocks_per_block_range(15)
900+
.build_transactions(53)
901+
.into_iter()
902+
.map(CardanoTransactionRecord::from)
883903
.collect();
884904

885905
repository
886906
.create_transactions(cardano_transactions.clone())
887907
.await
888908
.unwrap();
909+
// Use by 'prune_transaction' to get the block_range of the highest block number
889910
repository
890911
.create_block_range_roots(vec![(
891912
BlockRange::from_block_number(45),
@@ -911,6 +932,12 @@ mod tests {
911932
.await
912933
.unwrap();
913934
assert_eq!(Vec::<CardanoTransactionRecord>::new(), transaction_result);
935+
936+
let transaction_result = repository
937+
.get_transactions_in_range_blocks(25..1000)
938+
.await
939+
.unwrap();
940+
assert_eq!(28, transaction_result.len());
914941
}
915942

916943
#[tokio::test]

mithril-aggregator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.5.8"
3+
version = "0.5.9"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-aggregator/src/services/prover.rs

Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,10 @@ impl ProverService for MithrilProverService {
153153

154154
#[cfg(test)]
155155
mod tests {
156-
use std::cmp::max;
157-
158156
use anyhow::anyhow;
159157
use mithril_common::crypto_helper::{MKMap, MKMapNode, MKTreeNode};
160158
use mithril_common::entities::{CardanoTransaction, ImmutableFileNumber};
159+
use mithril_common::test_utils::CardanoTransactionsBuilder;
161160
use mockall::mock;
162161
use mockall::predicate::eq;
163162

@@ -183,43 +182,6 @@ mod tests {
183182
mod test_data {
184183
use super::*;
185184

186-
// Generate transactions for 'total_block_ranges' consecutive block ranges,
187-
// with 'total_transactions_per_block_range' transactions per block range
188-
pub fn generate_transactions(
189-
total_block_ranges: usize,
190-
total_transactions_per_block_range: usize,
191-
) -> Vec<CardanoTransaction> {
192-
let block_range_length = BlockRange::LENGTH as usize;
193-
let max_transaction_per_block_number =
194-
max(1, total_transactions_per_block_range / block_range_length);
195-
let mut transactions = vec![];
196-
197-
for i in 0..total_block_ranges {
198-
let block_range = BlockRange::from_block_number((i * block_range_length) as u64);
199-
for j in 0..total_transactions_per_block_range {
200-
let transaction_index = i * total_transactions_per_block_range + j;
201-
let block_number =
202-
block_range.start + (j / max_transaction_per_block_number) as u64;
203-
let slot_number = 100 * block_number;
204-
let immutable_file_number = block_number / 5;
205-
let tx_hash = format!(
206-
"tx-br-{}..{}-{}-idx-{}",
207-
block_range.start, block_range.end, j, transaction_index
208-
);
209-
let block_hash = format!("block_hash-{block_number}");
210-
transactions.push(CardanoTransaction::new(
211-
&tx_hash,
212-
block_number,
213-
slot_number,
214-
block_hash,
215-
immutable_file_number,
216-
));
217-
}
218-
}
219-
220-
transactions
221-
}
222-
223185
pub fn filter_transactions_for_indices(
224186
indices: &[usize],
225187
transactions: &[CardanoTransaction],
@@ -232,7 +194,7 @@ mod tests {
232194
.collect()
233195
}
234196

235-
pub fn compute_transaction_hashes_from_transactions(
197+
pub fn map_to_transaction_hashes(
236198
transactions: &[CardanoTransaction],
237199
) -> Vec<TransactionHash> {
238200
transactions
@@ -241,7 +203,7 @@ mod tests {
241203
.collect()
242204
}
243205

244-
pub fn compute_block_ranges_map_from_transactions(
206+
pub fn transactions_group_by_block_range(
245207
transactions: &[CardanoTransaction],
246208
) -> BTreeMap<BlockRange, Vec<CardanoTransaction>> {
247209
let mut block_ranges_map = BTreeMap::new();
@@ -309,11 +271,10 @@ mod tests {
309271
transactions_to_prove: &[CardanoTransaction],
310272
transactions: &[CardanoTransaction],
311273
) -> TestData {
312-
let transaction_hashes_to_prove =
313-
compute_transaction_hashes_from_transactions(transactions_to_prove);
314-
let block_ranges_map = compute_block_ranges_map_from_transactions(transactions);
274+
let transaction_hashes_to_prove = map_to_transaction_hashes(transactions_to_prove);
275+
let block_ranges_map = transactions_group_by_block_range(transactions);
315276
let block_ranges_map_to_prove =
316-
compute_block_ranges_map_from_transactions(transactions_to_prove);
277+
transactions_group_by_block_range(transactions_to_prove);
317278
let block_ranges_to_prove = block_ranges_map_to_prove
318279
.keys()
319280
.cloned()
@@ -355,10 +316,10 @@ mod tests {
355316
async fn compute_proof_for_one_set_of_three_known_transactions() {
356317
let total_block_ranges = 5;
357318
let total_transactions_per_block_range = 3;
358-
let transactions = test_data::generate_transactions(
359-
total_block_ranges,
360-
total_transactions_per_block_range,
361-
);
319+
let transactions = CardanoTransactionsBuilder::new()
320+
.max_transactions_per_block(1)
321+
.blocks_per_block_range(total_transactions_per_block_range)
322+
.build_block_ranges(total_block_ranges);
362323
let transactions_to_prove =
363324
test_data::filter_transactions_for_indices(&[1, 2, 4], &transactions);
364325
let test_data = test_data::build_test_data(&transactions_to_prove, &transactions);
@@ -408,10 +369,10 @@ mod tests {
408369
async fn cant_compute_proof_for_unknown_transaction() {
409370
let total_block_ranges = 5;
410371
let total_transactions_per_block_range = 3;
411-
let transactions = test_data::generate_transactions(
412-
total_block_ranges,
413-
total_transactions_per_block_range,
414-
);
372+
let transactions = CardanoTransactionsBuilder::new()
373+
.max_transactions_per_block(1)
374+
.blocks_per_block_range(total_transactions_per_block_range)
375+
.build_block_ranges(total_block_ranges);
415376
let transactions_to_prove = test_data::filter_transactions_for_indices(&[], &transactions);
416377
let mut test_data = test_data::build_test_data(&transactions_to_prove, &transactions);
417378
test_data.transaction_hashes_to_prove = vec!["tx-unknown-123".to_string()];
@@ -456,10 +417,10 @@ mod tests {
456417
async fn compute_proof_for_one_set_of_three_known_transactions_and_two_unknowns() {
457418
let total_block_ranges = 5;
458419
let total_transactions_per_block_range = 3;
459-
let transactions = test_data::generate_transactions(
460-
total_block_ranges,
461-
total_transactions_per_block_range,
462-
);
420+
let transactions = CardanoTransactionsBuilder::new()
421+
.max_transactions_per_block(1)
422+
.blocks_per_block_range(total_transactions_per_block_range)
423+
.build_block_ranges(total_block_ranges);
463424
let transactions_to_prove =
464425
test_data::filter_transactions_for_indices(&[1, 2, 4], &transactions);
465426
let transaction_hashes_unknown =
@@ -517,10 +478,10 @@ mod tests {
517478
async fn cant_compute_proof_if_transaction_retriever_fails() {
518479
let total_block_ranges = 5;
519480
let total_transactions_per_block_range = 3;
520-
let transactions = test_data::generate_transactions(
521-
total_block_ranges,
522-
total_transactions_per_block_range,
523-
);
481+
let transactions = CardanoTransactionsBuilder::new()
482+
.max_transactions_per_block(1)
483+
.blocks_per_block_range(total_transactions_per_block_range)
484+
.build_block_ranges(total_block_ranges);
524485
let transactions_to_prove =
525486
test_data::filter_transactions_for_indices(&[1, 2, 4], &transactions);
526487
let test_data = test_data::build_test_data(&transactions_to_prove, &transactions);
@@ -547,10 +508,10 @@ mod tests {
547508
async fn cant_compute_proof_if_block_range_root_retriever_fails() {
548509
let total_block_ranges = 5;
549510
let total_transactions_per_block_range = 3;
550-
let transactions = test_data::generate_transactions(
551-
total_block_ranges,
552-
total_transactions_per_block_range,
553-
);
511+
let transactions = CardanoTransactionsBuilder::new()
512+
.max_transactions_per_block(1)
513+
.blocks_per_block_range(total_transactions_per_block_range)
514+
.build_block_ranges(total_block_ranges);
554515
let transactions_to_prove =
555516
test_data::filter_transactions_for_indices(&[1, 2, 4], &transactions);
556517
let test_data = test_data::build_test_data(&transactions_to_prove, &transactions);

mithril-common/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-common"
3-
version = "0.4.6"
3+
version = "0.4.7"
44
description = "Common types, interfaces, and utilities for Mithril nodes."
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-common/src/signable_builder/cardano_transactions.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ impl SignableBuilder<CardanoDbBeacon> for CardanoTransactionsSignableBuilder {
109109
#[cfg(test)]
110110
mod tests {
111111

112-
use crate::{entities::CardanoTransaction, test_utils::TestLogger};
112+
use crate::{
113+
entities::CardanoTransaction,
114+
test_utils::{CardanoTransactionsBuilder, TestLogger},
115+
};
113116

114117
use super::*;
115118

@@ -132,11 +135,7 @@ mod tests {
132135
immutable_file_number: 14,
133136
..CardanoDbBeacon::default()
134137
};
135-
let transactions = vec![
136-
CardanoTransaction::new("tx-hash-123", 10, 1, "block_hash-", 11),
137-
CardanoTransaction::new("tx-hash-456", 20, 2, "block_hash", 12),
138-
CardanoTransaction::new("tx-hash-789", 30, 3, "block_hash", 13),
139-
];
138+
let transactions = CardanoTransactionsBuilder::new().build_transactions(3);
140139
let mk_map = compute_mk_map_from_transactions(transactions.clone());
141140
let mut transaction_importer = MockTransactionsImporter::new();
142141
transaction_importer

0 commit comments

Comments
 (0)