Skip to content

Commit 8d1e1b8

Browse files
Alenarsfauveldlachaume
committed
Make SignableBuilder use a BlockNumber as target
This force to make the same change to the `TransactionImporter`, `TransactionRetriever`,`BlockScanner` and the `CardanoTransactionSnapshot`. When a lower bound was required this is when we use a `ChainPoint`(instead of a block number as before). To do this we added a new condition to the `GetCardanoTransactionQuery` that get the transactions with the highest block number in db (all transaction with a same block number also share their slot number and block hash). Co-authored-by: Sébastien Fauvel <[email protected]> Co-authored-by: Damien Lachaume <[email protected]>
1 parent 686e219 commit 8d1e1b8

36 files changed

+297
-483
lines changed

internal/mithril-persistence/src/database/query/cardano_transaction/get_cardano_transaction.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ impl GetCardanoTransactionQuery {
6464

6565
Self { condition }
6666
}
67+
68+
pub fn with_highest_block_number() -> Self {
69+
Self {
70+
condition: WhereCondition::new(
71+
"block_number = (select max(block_number) from cardano_tx)",
72+
vec![],
73+
),
74+
}
75+
}
6776
}
6877

6978
impl Query for GetCardanoTransactionQuery {
@@ -80,3 +89,49 @@ impl Query for GetCardanoTransactionQuery {
8089
format!("select {projection} from cardano_tx where {condition} order by block_number, transaction_hash")
8190
}
8291
}
92+
93+
#[cfg(test)]
94+
mod tests {
95+
use crate::database::query::InsertCardanoTransactionQuery;
96+
use crate::database::test_helper::cardano_tx_db_connection;
97+
use crate::sqlite::{ConnectionExtensions, SqliteConnection};
98+
99+
use super::*;
100+
101+
fn insert_transactions(connection: &SqliteConnection, records: Vec<CardanoTransactionRecord>) {
102+
connection
103+
.fetch_first(InsertCardanoTransactionQuery::insert_many(records).unwrap())
104+
.unwrap();
105+
}
106+
107+
#[test]
108+
fn with_highest_block_number() {
109+
let connection = cardano_tx_db_connection().unwrap();
110+
111+
let cursor = connection
112+
.fetch(GetCardanoTransactionQuery::with_highest_block_number())
113+
.unwrap();
114+
assert_eq!(0, cursor.count());
115+
116+
insert_transactions(
117+
&connection,
118+
vec![
119+
CardanoTransactionRecord::new("tx-hash-0", 10, 50, "block-hash-10", 1),
120+
CardanoTransactionRecord::new("tx-hash-1", 10, 51, "block-hash-10", 1),
121+
CardanoTransactionRecord::new("tx-hash-2", 11, 54, "block-hash-11", 1),
122+
CardanoTransactionRecord::new("tx-hash-3", 11, 55, "block-hash-11", 1),
123+
],
124+
);
125+
126+
let records: Vec<CardanoTransactionRecord> = connection
127+
.fetch_collect(GetCardanoTransactionQuery::with_highest_block_number())
128+
.unwrap();
129+
assert_eq!(
130+
vec![
131+
CardanoTransactionRecord::new("tx-hash-2", 11, 54, "block-hash-11", 1),
132+
CardanoTransactionRecord::new("tx-hash-3", 11, 55, "block-hash-11", 1),
133+
],
134+
records
135+
);
136+
}
137+
}

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use async_trait::async_trait;
77
use mithril_common::cardano_block_scanner::ImmutableLowerBoundFinder;
88
use mithril_common::crypto_helper::MKTreeNode;
99
use mithril_common::entities::{
10-
BlockHash, BlockNumber, BlockRange, CardanoTransaction, ImmutableFileNumber, SlotNumber,
11-
TransactionHash,
10+
BlockHash, BlockNumber, BlockRange, CardanoTransaction, ChainPoint, ImmutableFileNumber,
11+
SlotNumber, TransactionHash,
1212
};
1313
use mithril_common::signable_builder::BlockRangeRootRetriever;
1414
use mithril_common::StdResult;
@@ -107,16 +107,14 @@ impl CardanoTransactionRepository {
107107
}
108108

109109
/// Get the highest [BlockNumber] of the cardano transactions stored in the database.
110-
pub async fn get_transaction_highest_block_number(&self) -> StdResult<Option<BlockNumber>> {
111-
let highest: Option<i64> = self
110+
pub async fn get_transaction_highest_chain_point(&self) -> StdResult<Option<ChainPoint>> {
111+
let first_transaction_with_highest_block_number = self
112112
.connection
113-
.query_single_cell("select max(block_number) as highest from cardano_tx;", &[])?;
114-
highest
115-
.map(u64::try_from)
116-
.transpose()
117-
.with_context(||
118-
format!("Integer field max(block_number) (value={highest:?}) is incompatible with u64 representation.")
119-
)
113+
.fetch_first(GetCardanoTransactionQuery::with_highest_block_number())?;
114+
115+
Ok(first_transaction_with_highest_block_number.map(|record| {
116+
ChainPoint::new(record.slot_number, record.block_number, record.block_hash)
117+
}))
120118
}
121119

122120
/// Get the highest start [BlockNumber] of the block range roots stored in the database.
@@ -484,36 +482,43 @@ mod tests {
484482
}
485483

486484
#[tokio::test]
487-
async fn repository_get_transaction_highest_block_number_without_transactions_in_db() {
485+
async fn repository_get_transaction_highest_chain_point_without_transactions_in_db() {
488486
let connection = Arc::new(cardano_tx_db_connection().unwrap());
489487
let repository = CardanoTransactionRepository::new(connection);
490488

491489
let highest_beacon = repository
492-
.get_transaction_highest_block_number()
490+
.get_transaction_highest_chain_point()
493491
.await
494492
.unwrap();
495493
assert_eq!(None, highest_beacon);
496494
}
497495

498496
#[tokio::test]
499-
async fn repository_get_transaction_highest_block_number_with_transactions_in_db() {
497+
async fn repository_get_transaction_highest_chain_point_with_transactions_in_db() {
500498
let connection = Arc::new(cardano_tx_db_connection().unwrap());
501499
let repository = CardanoTransactionRepository::new(connection);
502500

503501
let cardano_transactions = vec![
504-
CardanoTransaction::new("tx-hash-123".to_string(), 10, 50, "block-hash-123", 50),
505-
CardanoTransaction::new("tx-hash-456".to_string(), 25, 51, "block-hash-456", 100),
502+
CardanoTransaction::new("tx-hash-123", 10, 50, "block-hash-10", 50),
503+
CardanoTransaction::new("tx-hash-456", 25, 51, "block-hash-25", 100),
506504
];
507505
repository
508506
.create_transactions(cardano_transactions)
509507
.await
510508
.unwrap();
511509

512510
let highest_beacon = repository
513-
.get_transaction_highest_block_number()
511+
.get_transaction_highest_chain_point()
514512
.await
515513
.unwrap();
516-
assert_eq!(Some(25), highest_beacon);
514+
assert_eq!(
515+
Some(ChainPoint {
516+
slot_number: 51,
517+
block_number: 25,
518+
block_hash: "block-hash-25".to_string()
519+
}),
520+
highest_beacon
521+
);
517522
}
518523

519524
#[tokio::test]

mithril-aggregator/src/artifact_builder/cardano_transactions.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::{anyhow, Context};
44
use async_trait::async_trait;
55
use mithril_common::{
66
entities::{
7-
CardanoTransactionsSnapshot, Certificate, ChainPoint, ProtocolMessagePartKey,
7+
BlockNumber, CardanoTransactionsSnapshot, Certificate, ProtocolMessagePartKey,
88
SignedEntityType,
99
},
1010
StdResult,
@@ -27,12 +27,12 @@ impl CardanoTransactionsArtifactBuilder {
2727
}
2828

2929
#[async_trait]
30-
impl ArtifactBuilder<ChainPoint, CardanoTransactionsSnapshot>
30+
impl ArtifactBuilder<BlockNumber, CardanoTransactionsSnapshot>
3131
for CardanoTransactionsArtifactBuilder
3232
{
3333
async fn compute_artifact(
3434
&self,
35-
beacon: ChainPoint,
35+
beacon: BlockNumber,
3636
certificate: &Certificate,
3737
) -> StdResult<CardanoTransactionsSnapshot> {
3838
let merkle_root = certificate
@@ -44,10 +44,10 @@ impl ArtifactBuilder<ChainPoint, CardanoTransactionsSnapshot>
4444
.with_context(|| {
4545
format!(
4646
"Can not compute CardanoTransactionsCommitment artifact for signed_entity: {:?}",
47-
SignedEntityType::CardanoTransactions(certificate.epoch, beacon.clone())
47+
SignedEntityType::CardanoTransactions(certificate.epoch, beacon)
4848
)
4949
})?;
50-
self.prover_service.compute_cache(&beacon).await?;
50+
self.prover_service.compute_cache(beacon).await?;
5151

5252
Ok(CardanoTransactionsSnapshot::new(
5353
merkle_root.to_string(),
@@ -77,13 +77,13 @@ mod tests {
7777
certificate
7878
};
7979

80-
let beacon = ChainPoint::dummy();
80+
let beacon = 100;
8181
let mut mock_prover = MockProverService::new();
8282
mock_prover.expect_compute_cache().returning(|_| Ok(()));
8383
let cardano_transaction_artifact_builder =
8484
CardanoTransactionsArtifactBuilder::new(Arc::new(mock_prover));
8585
let artifact = cardano_transaction_artifact_builder
86-
.compute_artifact(beacon.clone(), &certificate)
86+
.compute_artifact(beacon, &certificate)
8787
.await
8888
.unwrap();
8989
let artifact_expected = CardanoTransactionsSnapshot::new("merkleroot".to_string(), beacon);
@@ -104,7 +104,7 @@ mod tests {
104104
let cardano_transaction_artifact_builder =
105105
CardanoTransactionsArtifactBuilder::new(Arc::new(mock_prover));
106106
cardano_transaction_artifact_builder
107-
.compute_artifact(ChainPoint::dummy(), &certificate)
107+
.compute_artifact(12390, &certificate)
108108
.await
109109
.expect_err("The artifact building must fail since there is no CardanoTransactionsMerkleRoot part in its message.");
110110
}

mithril-aggregator/src/configuration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ mod test {
645645
SignedEntityType::MithrilStakeDistribution(beacon.epoch),
646646
SignedEntityType::CardanoStakeDistribution(beacon.epoch),
647647
SignedEntityType::CardanoImmutableFilesFull(beacon.clone()),
648-
SignedEntityType::CardanoTransactions(beacon.epoch, chain_point),
648+
SignedEntityType::CardanoTransactions(beacon.epoch, chain_point.block_number),
649649
],
650650
signed_entity_types
651651
);

mithril-aggregator/src/database/record/signed_entity.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use chrono::{DateTime, Utc};
22
use serde::{Deserialize, Serialize};
33

44
use mithril_common::crypto_helper::ProtocolParameters;
5-
use mithril_common::entities::{ChainPoint, Epoch, SignedEntity, SignedEntityType, Snapshot};
5+
use mithril_common::entities::{BlockNumber, Epoch, SignedEntity, SignedEntityType, Snapshot};
66
use mithril_common::messages::{
77
CardanoTransactionSnapshotListItemMessage, CardanoTransactionSnapshotMessage,
88
MithrilStakeDistributionListItemMessage, MithrilStakeDistributionMessage,
@@ -172,14 +172,14 @@ impl TryFrom<SignedEntityRecord> for CardanoTransactionSnapshotMessage {
172172
#[derive(Deserialize)]
173173
struct TmpCardanoTransaction {
174174
merkle_root: String,
175-
chain_point: ChainPoint,
175+
block_number: BlockNumber,
176176
hash: String,
177177
}
178178
let artifact = serde_json::from_str::<TmpCardanoTransaction>(&value.artifact)?;
179179
let cardano_transaction_message = CardanoTransactionSnapshotMessage {
180180
merkle_root: artifact.merkle_root,
181181
epoch: value.signed_entity_type.get_epoch(),
182-
chain_point: artifact.chain_point,
182+
block_number: artifact.block_number,
183183
hash: artifact.hash,
184184
certificate_hash: value.certificate_id,
185185
created_at: value.created_at,
@@ -196,14 +196,14 @@ impl TryFrom<SignedEntityRecord> for CardanoTransactionSnapshotListItemMessage {
196196
#[derive(Deserialize)]
197197
struct TmpCardanoTransaction {
198198
merkle_root: String,
199-
chain_point: ChainPoint,
199+
block_number: BlockNumber,
200200
hash: String,
201201
}
202202
let artifact = serde_json::from_str::<TmpCardanoTransaction>(&value.artifact)?;
203203
let message = CardanoTransactionSnapshotListItemMessage {
204204
merkle_root: artifact.merkle_root,
205205
epoch: value.signed_entity_type.get_epoch(),
206-
chain_point: artifact.chain_point,
206+
block_number: artifact.block_number,
207207
hash: artifact.hash,
208208
certificate_hash: value.certificate_id,
209209
created_at: value.created_at,

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ use std::ops::Range;
33
use async_trait::async_trait;
44

55
use mithril_common::crypto_helper::MKTreeNode;
6-
use mithril_common::entities::{BlockNumber, BlockRange, CardanoTransaction, TransactionHash};
6+
use mithril_common::entities::{
7+
BlockNumber, BlockRange, CardanoTransaction, ChainPoint, TransactionHash,
8+
};
79
use mithril_common::StdResult;
810
use mithril_persistence::database::repository::CardanoTransactionRepository;
911

1012
use crate::services::{TransactionStore, TransactionsRetriever};
1113

1214
#[async_trait]
1315
impl TransactionStore for CardanoTransactionRepository {
14-
async fn get_highest_beacon(&self) -> StdResult<Option<BlockNumber>> {
15-
self.get_transaction_highest_block_number().await
16+
async fn get_highest_beacon(&self) -> StdResult<Option<ChainPoint>> {
17+
self.get_transaction_highest_chain_point().await
1618
}
1719

1820
async fn store_transactions(&self, transactions: Vec<CardanoTransaction>) -> StdResult<()> {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl OpenMessageRepository {
104104

105105
#[cfg(test)]
106106
mod tests {
107-
use mithril_common::entities::{CardanoDbBeacon, ChainPoint};
107+
use mithril_common::entities::CardanoDbBeacon;
108108

109109
use crate::database::record::SingleSignatureRecord;
110110
use crate::database::test_helper::{
@@ -184,7 +184,7 @@ mod tests {
184184
for signed_entity_type in [
185185
SignedEntityType::MithrilStakeDistribution(epoch),
186186
SignedEntityType::CardanoImmutableFilesFull(CardanoDbBeacon::new("devnet", *epoch, 1)),
187-
SignedEntityType::CardanoTransactions(epoch, ChainPoint::dummy()),
187+
SignedEntityType::CardanoTransactions(epoch, 100),
188188
] {
189189
repository
190190
.create_open_message(epoch, &signed_entity_type, &ProtocolMessage::new())

mithril-aggregator/src/dependency_injection/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ impl DependenciesBuilder {
11041104
.await?
11051105
{
11061106
prover_service
1107-
.compute_cache(&signed_entity.artifact.chain_point)
1107+
.compute_cache(signed_entity.artifact.block_number)
11081108
.await?;
11091109
}
11101110

mithril-aggregator/src/http_server/routes/artifact_routes/cardano_transaction.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,8 @@ pub mod tests {
9595
},
9696
services::MockMessageService,
9797
};
98-
use mithril_common::entities::{ChainPoint, Epoch};
9998
use mithril_common::{
100-
entities::SignedEntityType,
99+
entities::{Epoch, SignedEntityType},
101100
messages::ToMessageAdapter,
102101
test_utils::{apispec::APISpec, fake_data},
103102
};
@@ -126,7 +125,7 @@ pub mod tests {
126125
#[tokio::test]
127126
async fn test_cardano_transactions_get_ok() {
128127
let signed_entity_records = create_signed_entities(
129-
SignedEntityType::CardanoTransactions(Epoch(1), ChainPoint::dummy()),
128+
SignedEntityType::CardanoTransactions(Epoch(1), 120),
130129
fake_data::cardano_transactions_snapshot(5),
131130
);
132131
let message = ToCardanoTransactionListMessageAdapter::adapt(signed_entity_records);
@@ -193,7 +192,7 @@ pub mod tests {
193192
#[tokio::test]
194193
async fn test_cardano_transaction_get_ok() {
195194
let signed_entity = create_signed_entities(
196-
SignedEntityType::CardanoTransactions(Epoch(1), ChainPoint::dummy()),
195+
SignedEntityType::CardanoTransactions(Epoch(1), 100),
197196
fake_data::cardano_transactions_snapshot(1),
198197
)
199198
.first()

mithril-aggregator/src/http_server/routes/proof_routes.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ mod handlers {
9797
) -> StdResult<CardanoTransactionsProofsMessage> {
9898
let transactions_set_proofs = prover_service
9999
.compute_transactions_proofs(
100-
&signed_entity.artifact.chain_point,
100+
signed_entity.artifact.block_number,
101101
transaction_hashes.as_slice(),
102102
)
103103
.await?;
@@ -122,9 +122,7 @@ mod tests {
122122
};
123123

124124
use mithril_common::{
125-
entities::{
126-
CardanoTransactionsSetProof, CardanoTransactionsSnapshot, ChainPoint, SignedEntity,
127-
},
125+
entities::{CardanoTransactionsSetProof, CardanoTransactionsSnapshot, SignedEntity},
128126
test_utils::apispec::APISpec,
129127
};
130128

@@ -150,21 +148,14 @@ mod tests {
150148
}
151149

152150
#[tokio::test]
153-
async fn build_response_message_return_immutable_file_number_from_artifact_beacon() {
151+
async fn build_response_message_return_latest_block_number_from_artifact_beacon() {
154152
// Arrange
155153
let mut mock_prover_service = MockProverService::new();
156154
mock_prover_service
157155
.expect_compute_transactions_proofs()
158156
.returning(|_, _| Ok(vec![CardanoTransactionsSetProof::dummy()]));
159157

160-
let cardano_transactions_snapshot = {
161-
let merkle_root = String::new();
162-
let chain_point = ChainPoint {
163-
block_number: 2309,
164-
..ChainPoint::dummy()
165-
};
166-
CardanoTransactionsSnapshot::new(merkle_root, chain_point)
167-
};
158+
let cardano_transactions_snapshot = CardanoTransactionsSnapshot::new(String::new(), 2309);
168159

169160
let signed_entity = SignedEntity::<CardanoTransactionsSnapshot> {
170161
artifact: cardano_transactions_snapshot,

0 commit comments

Comments
 (0)