Skip to content

Commit f04a629

Browse files
authored
Merge pull request #1795 from input-output-hk/djo/1785/last_tx_not_proved
Bugfix: Can't generate proof for transactions on the last signed block number
2 parents f10e4eb + 10e2a20 commit f04a629

File tree

18 files changed

+515
-238
lines changed

18 files changed

+515
-238
lines changed

Cargo.lock

Lines changed: 4 additions & 4 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.2.14"
3+
version = "0.2.15"
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/query/block_range_root/delete_block_range_root.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,13 @@ mod tests {
4949
use mithril_common::crypto_helper::MKTreeNode;
5050
use mithril_common::entities::BlockRange;
5151

52-
use crate::database::query::{GetBlockRangeRootQuery, InsertBlockRangeRootQuery};
52+
use crate::database::query::block_range_root::test_helper::insert_block_range_roots;
53+
use crate::database::query::GetBlockRangeRootQuery;
5354
use crate::database::test_helper::cardano_tx_db_connection;
54-
use crate::sqlite::{ConnectionExtensions, SqliteConnection};
55+
use crate::sqlite::ConnectionExtensions;
5556

5657
use super::*;
5758

58-
fn insert_block_range_roots(connection: &SqliteConnection, records: Vec<BlockRangeRootRecord>) {
59-
connection
60-
.fetch_first(InsertBlockRangeRootQuery::insert_many(records).unwrap())
61-
.unwrap();
62-
}
63-
6459
fn block_range_root_dataset() -> Vec<BlockRangeRootRecord> {
6560
[
6661
(

internal/mithril-persistence/src/database/query/block_range_root/get_block_range_root.rs

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use mithril_common::entities::BlockNumber;
21
use sqlite::Value;
32

3+
use mithril_common::entities::BlockNumber;
4+
45
use crate::database::record::BlockRangeRootRecord;
56
use crate::sqlite::{Query, SourceAlias, SqLiteEntity, WhereCondition};
67

@@ -16,12 +17,9 @@ impl GetBlockRangeRootQuery {
1617
}
1718
}
1819

19-
pub fn up_to_block_number(up_to_or_equal_end_block_number: BlockNumber) -> Self {
20+
pub fn contains_or_below_block_number(block_number: BlockNumber) -> Self {
2021
Self {
21-
condition: WhereCondition::new(
22-
"end <= ?*",
23-
vec![Value::Integer(up_to_or_equal_end_block_number as i64)],
24-
),
22+
condition: WhereCondition::new("start < ?*", vec![Value::Integer(block_number as i64)]),
2523
}
2624
}
2725
}
@@ -40,3 +38,100 @@ impl Query for GetBlockRangeRootQuery {
4038
format!("select {projection} from block_range_root where {condition} order by start, end")
4139
}
4240
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use mithril_common::crypto_helper::MKTreeNode;
45+
use mithril_common::entities::BlockRange;
46+
47+
use crate::database::query::block_range_root::test_helper::insert_block_range_roots;
48+
use crate::database::query::GetBlockRangeRootQuery;
49+
use crate::database::test_helper::cardano_tx_db_connection;
50+
use crate::sqlite::ConnectionExtensions;
51+
52+
use super::*;
53+
54+
fn block_range_root_dataset() -> Vec<BlockRangeRootRecord> {
55+
[
56+
(
57+
BlockRange::from_block_number(15),
58+
MKTreeNode::from_hex("AAAA").unwrap(),
59+
),
60+
(
61+
BlockRange::from_block_number(30),
62+
MKTreeNode::from_hex("BBBB").unwrap(),
63+
),
64+
(
65+
BlockRange::from_block_number(45),
66+
MKTreeNode::from_hex("CCCC").unwrap(),
67+
),
68+
]
69+
.into_iter()
70+
.map(BlockRangeRootRecord::from)
71+
.collect()
72+
}
73+
74+
#[test]
75+
fn test_get_contains_or_below_block_number_with_empty_db() {
76+
let connection = cardano_tx_db_connection().unwrap();
77+
78+
let cursor: Vec<BlockRangeRootRecord> = connection
79+
.fetch_collect(GetBlockRangeRootQuery::contains_or_below_block_number(100))
80+
.unwrap();
81+
assert_eq!(Vec::<BlockRangeRootRecord>::new(), cursor);
82+
}
83+
84+
#[test]
85+
fn test_get_contains_or_below_block_number_higher_than_the_highest_stored_block_range() {
86+
let connection = cardano_tx_db_connection().unwrap();
87+
let dataset = block_range_root_dataset();
88+
insert_block_range_roots(&connection, dataset.clone());
89+
90+
let cursor: Vec<BlockRangeRootRecord> = connection
91+
.fetch_collect(GetBlockRangeRootQuery::contains_or_below_block_number(
92+
10_000,
93+
))
94+
.unwrap();
95+
96+
assert_eq!(dataset, cursor);
97+
}
98+
99+
#[test]
100+
fn test_get_contains_or_below_block_number_below_end_of_the_third_block_range() {
101+
let connection = cardano_tx_db_connection().unwrap();
102+
let dataset = block_range_root_dataset();
103+
insert_block_range_roots(&connection, dataset.clone());
104+
105+
let cursor: Vec<BlockRangeRootRecord> = connection
106+
.fetch_collect(GetBlockRangeRootQuery::contains_or_below_block_number(44))
107+
.unwrap();
108+
109+
assert_eq!(&dataset[0..2], &cursor);
110+
}
111+
112+
#[test]
113+
fn test_get_contains_or_below_block_number_equal_to_end_of_the_third_block_range() {
114+
let connection = cardano_tx_db_connection().unwrap();
115+
let dataset = block_range_root_dataset();
116+
insert_block_range_roots(&connection, dataset.clone());
117+
118+
let cursor: Vec<BlockRangeRootRecord> = connection
119+
.fetch_collect(GetBlockRangeRootQuery::contains_or_below_block_number(45))
120+
.unwrap();
121+
122+
assert_eq!(&dataset[0..2], &cursor);
123+
}
124+
125+
#[test]
126+
fn test_get_contains_or_below_block_number_after_end_of_the_third_block_range() {
127+
let connection = cardano_tx_db_connection().unwrap();
128+
let dataset = block_range_root_dataset();
129+
insert_block_range_roots(&connection, dataset.clone());
130+
131+
let cursor: Vec<BlockRangeRootRecord> = connection
132+
.fetch_collect(GetBlockRangeRootQuery::contains_or_below_block_number(46))
133+
.unwrap();
134+
135+
assert_eq!(dataset, cursor);
136+
}
137+
}

internal/mithril-persistence/src/database/query/block_range_root/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,20 @@ pub use delete_block_range_root::*;
77
pub use get_block_range_root::*;
88
pub use get_interval_without_block_range::*;
99
pub use insert_block_range::*;
10+
11+
#[cfg(test)]
12+
mod test_helper {
13+
use crate::database::record::BlockRangeRootRecord;
14+
use crate::sqlite::{ConnectionExtensions, SqliteConnection};
15+
16+
use super::*;
17+
18+
pub fn insert_block_range_roots(
19+
connection: &SqliteConnection,
20+
records: Vec<BlockRangeRootRecord>,
21+
) {
22+
connection
23+
.fetch_first(InsertBlockRangeRootQuery::insert_many(records).unwrap())
24+
.unwrap();
25+
}
26+
}

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

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,17 @@ impl CardanoTransactionRepository {
146146
)
147147
}
148148

149-
/// Retrieve all the Block Range Roots in database up to the given end block number included.
149+
/// Retrieve all the Block Range Roots in database up to the block range that contains the given
150+
/// block number.
150151
pub async fn retrieve_block_range_roots_up_to(
151152
&self,
152-
up_to_or_equal_end_block_number: BlockNumber,
153+
block_number: BlockNumber,
153154
) -> StdResult<Box<dyn Iterator<Item = (BlockRange, MKTreeNode)> + '_>> {
154155
let block_range_roots = self
155156
.connection_pool
156157
.connection()?
157-
.fetch(GetBlockRangeRootQuery::up_to_block_number(
158-
up_to_or_equal_end_block_number,
158+
.fetch(GetBlockRangeRootQuery::contains_or_below_block_number(
159+
block_number,
159160
))?
160161
.map(|record| -> (BlockRange, MKTreeNode) { record.into() })
161162
.collect::<Vec<_>>(); // TODO: remove this collect to return the iterator directly
@@ -325,13 +326,9 @@ impl CardanoTransactionRepository {
325326
impl BlockRangeRootRetriever for CardanoTransactionRepository {
326327
async fn retrieve_block_range_roots<'a>(
327328
&'a self,
328-
up_to_or_equal_beacon: BlockNumber,
329+
up_to_beacon: BlockNumber,
329330
) -> StdResult<Box<dyn Iterator<Item = (BlockRange, MKTreeNode)> + 'a>> {
330-
let iterator = self
331-
.retrieve_block_range_roots_up_to(up_to_or_equal_beacon)
332-
.await?;
333-
334-
Ok(Box::new(iterator))
331+
self.retrieve_block_range_roots_up_to(up_to_beacon).await
335332
}
336333
}
337334

@@ -973,50 +970,14 @@ mod tests {
973970
.await
974971
.unwrap();
975972

976-
// Retrieve with a block far higher than the highest block range - should return all
977-
{
978-
let retrieved_block_ranges = repository
979-
.retrieve_block_range_roots_up_to(1000)
980-
.await
981-
.unwrap();
982-
assert_eq!(
983-
block_range_roots,
984-
retrieved_block_ranges.collect::<Vec<_>>()
985-
);
986-
}
987-
// Retrieve with a block bellow than the smallest block range - should return none
988-
{
989-
let retrieved_block_ranges = repository
990-
.retrieve_block_range_roots_up_to(2)
991-
.await
992-
.unwrap();
993-
assert_eq!(
994-
Vec::<(BlockRange, MKTreeNode)>::new(),
995-
retrieved_block_ranges.collect::<Vec<_>>()
996-
);
997-
}
998-
// Right below the end of the second block range - should return first of the three
999-
{
1000-
let retrieved_block_ranges = repository
1001-
.retrieve_block_range_roots_up_to(44)
1002-
.await
1003-
.unwrap();
1004-
assert_eq!(
1005-
vec![block_range_roots[0].clone()],
1006-
retrieved_block_ranges.collect::<Vec<_>>()
1007-
);
1008-
}
1009-
// The given block is matched to the end (included) - should return the two of the three
1010-
{
1011-
let retrieved_block_ranges = repository
1012-
.retrieve_block_range_roots_up_to(45)
1013-
.await
1014-
.unwrap();
1015-
assert_eq!(
1016-
block_range_roots[0..=1].to_vec(),
1017-
retrieved_block_ranges.collect::<Vec<_>>()
1018-
);
1019-
}
973+
let retrieved_block_ranges = repository
974+
.retrieve_block_range_roots_up_to(45)
975+
.await
976+
.unwrap();
977+
assert_eq!(
978+
block_range_roots[0..2].to_vec(),
979+
retrieved_block_ranges.collect::<Vec<_>>()
980+
);
1020981
}
1021982

1022983
#[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.34"
3+
version = "0.5.35"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-aggregator/src/services/prover.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl ProverService for MithrilProverService {
141141

142142
// 4 - Enrich the Merkle map with the block ranges Merkle trees
143143
for (block_range, mk_tree) in mk_trees {
144-
mk_map.insert(block_range, mk_tree.into())?;
144+
mk_map.replace(block_range, mk_tree.into())?;
145145
}
146146

147147
// 5 - Compute the proof for all transactions
@@ -167,7 +167,8 @@ impl ProverService for MithrilProverService {
167167
let pool_size = self.mk_map_pool.size();
168168
info!(
169169
self.logger,
170-
"Prover starts computing the Merkle map pool resource of size {pool_size}"
170+
"Prover starts computing the Merkle map pool resource of size {pool_size}";
171+
"up_to_block_number" => up_to,
171172
);
172173
let mk_map_cache = self
173174
.block_range_root_retriever

mithril-aggregator/tests/create_certificate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ async fn create_certificate() {
142142

143143
comment!(
144144
"Increase cardano chain block number to 185,
145-
the state machine should be signing CardanoTransactions for block 180"
145+
the state machine should be signing CardanoTransactions for block 179"
146146
);
147147
tester.increase_block_number(85, 185).await.unwrap();
148148
cycle!(tester, "signing");
@@ -166,7 +166,7 @@ async fn create_certificate() {
166166
.map(|s| s.signer_with_stake.clone().into())
167167
.collect::<Vec<_>>(),
168168
fixture.compute_and_encode_avk(),
169-
SignedEntityType::CardanoTransactions(Epoch(1), 180),
169+
SignedEntityType::CardanoTransactions(Epoch(1), 179),
170170
ExpectedCertificate::genesis_identifier(&CardanoDbBeacon::new(
171171
"devnet".to_string(),
172172
1,
@@ -201,7 +201,7 @@ async fn create_certificate() {
201201
.map(|s| s.signer_with_stake.clone().into())
202202
.collect::<Vec<_>>(),
203203
fixture.compute_and_encode_avk(),
204-
SignedEntityType::CardanoTransactions(Epoch(1), 120),
204+
SignedEntityType::CardanoTransactions(Epoch(1), 119),
205205
ExpectedCertificate::genesis_identifier(&CardanoDbBeacon::new(
206206
"devnet".to_string(),
207207
1,

0 commit comments

Comments
 (0)