Skip to content

Commit 7cdf97b

Browse files
committed
PR Review: make BlockRangeRootRecor::hydrate fail if range is invalid
* start & end must be multiples of BlockRange::Length * start & end interval must be equal to BlockRange::Length
1 parent a7a7720 commit 7cdf97b

File tree

2 files changed

+123
-5
lines changed

2 files changed

+123
-5
lines changed

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

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,25 @@ impl SqLiteEntity for BlockRangeRootRecord {
3636
Self: Sized,
3737
{
3838
let start = try_to_u64("block_range.start", row.read::<i64, _>(0))?;
39-
let _end = try_to_u64("block_range.end", row.read::<i64, _>(1))?;
39+
let end = try_to_u64("block_range.end", row.read::<i64, _>(1))?;
40+
let range = BlockRange::from_block_number(start);
4041
let merkle_root = row.read::<&str, _>(2);
4142

43+
if range.start != start || range.end != end {
44+
return Err(HydrationError::InvalidData(format!(
45+
"Invalid block range: start={start}, end={end}, expected_start={}, expected_end={}",
46+
range.start, range.end
47+
)));
48+
}
49+
4250
Ok(Self {
43-
range: BlockRange::from_block_number(start),
51+
range,
4452
merkle_root: MKTreeNode::from_hex(merkle_root)
4553
.map_err(|e| HydrationError::InvalidData(
4654
format!(
4755
"Field block_range.merkle_root (value={merkle_root}) is incompatible with hex representation. Error = {e}")
4856
)
49-
)?,
57+
)?,
5058
})
5159
}
5260

@@ -58,3 +66,54 @@ impl SqLiteEntity for BlockRangeRootRecord {
5866
])
5967
}
6068
}
69+
70+
#[cfg(test)]
71+
mod tests {
72+
use super::*;
73+
use mithril_common::entities::BlockNumber;
74+
use sqlite::Connection;
75+
76+
fn select_block_range_from_db(start: BlockNumber, end: BlockNumber, merkle_root: &str) -> Row {
77+
let conn = Connection::open(":memory:").unwrap();
78+
let query = format!("SELECT {start}, {end}, '{merkle_root}'");
79+
let mut statement = conn.prepare(query).unwrap();
80+
statement.iter().next().unwrap().unwrap()
81+
}
82+
83+
#[test]
84+
fn hydrate_succeed_if_valid_block_range_in_row() {
85+
// A valid block range has both bounds as multiples of block range length and the interval
86+
// size is equal to block range length.
87+
let row = select_block_range_from_db(0, BlockRange::LENGTH, "AAAA");
88+
let res = BlockRangeRootRecord::hydrate(row).expect("Expected hydrate to succeed");
89+
90+
assert_eq!(
91+
res,
92+
BlockRangeRootRecord {
93+
range: BlockRange::from_block_number(0),
94+
merkle_root: MKTreeNode::from_hex("AAAA").unwrap(),
95+
}
96+
);
97+
}
98+
99+
#[test]
100+
fn hydrate_fail_if_invalid_block_range_in_row() {
101+
for invalid_row in [
102+
// Start is not a multiple of block range length
103+
select_block_range_from_db(1, BlockRange::LENGTH, "AAAA"),
104+
// End is not a multiple of block range length
105+
select_block_range_from_db(0, BlockRange::LENGTH - 1, "AAAA"),
106+
// Interval is not equal to block range length
107+
select_block_range_from_db(0, BlockRange::LENGTH * 4, "AAAA"),
108+
] {
109+
let res =
110+
BlockRangeRootRecord::hydrate(invalid_row).expect_err("Expected hydrate to fail");
111+
112+
assert!(
113+
format!("{res:?}").contains("Invalid block range"),
114+
"Expected 'Invalid block range' error, got {:?}",
115+
res
116+
);
117+
}
118+
}
119+
}

mithril-signer/src/database/record/block_range_root.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,19 @@ impl SqLiteEntity for BlockRangeRootRecord {
3636
Self: Sized,
3737
{
3838
let start = try_to_u64("block_range.start", row.read::<i64, _>(0))?;
39-
let _end = try_to_u64("block_range.end", row.read::<i64, _>(1))?;
39+
let end = try_to_u64("block_range.end", row.read::<i64, _>(1))?;
40+
let range = BlockRange::from_block_number(start);
4041
let merkle_root = row.read::<&str, _>(2);
4142

43+
if range.start != start || range.end != end {
44+
return Err(HydrationError::InvalidData(format!(
45+
"Invalid block range: start={start}, end={end}, expected_start={}, expected_end={}",
46+
range.start, range.end
47+
)));
48+
}
49+
4250
Ok(Self {
43-
range: BlockRange::from_block_number(start),
51+
range,
4452
merkle_root: MKTreeNode::from_hex(merkle_root)
4553
.map_err(|e| HydrationError::InvalidData(
4654
format!(
@@ -58,3 +66,54 @@ impl SqLiteEntity for BlockRangeRootRecord {
5866
])
5967
}
6068
}
69+
70+
#[cfg(test)]
71+
mod tests {
72+
use super::*;
73+
use mithril_common::entities::BlockNumber;
74+
use sqlite::Connection;
75+
76+
fn select_block_range_from_db(start: BlockNumber, end: BlockNumber, merkle_root: &str) -> Row {
77+
let conn = Connection::open(":memory:").unwrap();
78+
let query = format!("SELECT {start}, {end}, '{merkle_root}'");
79+
let mut statement = conn.prepare(query).unwrap();
80+
statement.iter().next().unwrap().unwrap()
81+
}
82+
83+
#[test]
84+
fn hydrate_succeed_if_valid_block_range_in_row() {
85+
// A valid block range has both bounds as multiples of block range length and the interval
86+
// size is equal to block range length.
87+
let row = select_block_range_from_db(0, BlockRange::LENGTH, "AAAA");
88+
let res = BlockRangeRootRecord::hydrate(row).expect("Expected hydrate to succeed");
89+
90+
assert_eq!(
91+
res,
92+
BlockRangeRootRecord {
93+
range: BlockRange::from_block_number(0),
94+
merkle_root: MKTreeNode::from_hex("AAAA").unwrap(),
95+
}
96+
);
97+
}
98+
99+
#[test]
100+
fn hydrate_fail_if_invalid_block_range_in_row() {
101+
for invalid_row in [
102+
// Start is not a multiple of block range length
103+
select_block_range_from_db(1, BlockRange::LENGTH, "AAAA"),
104+
// End is not a multiple of block range length
105+
select_block_range_from_db(0, BlockRange::LENGTH - 1, "AAAA"),
106+
// Interval is not equal to block range length
107+
select_block_range_from_db(0, BlockRange::LENGTH * 4, "AAAA"),
108+
] {
109+
let res =
110+
BlockRangeRootRecord::hydrate(invalid_row).expect_err("Expected hydrate to fail");
111+
112+
assert!(
113+
format!("{res:?}").contains("Invalid block range"),
114+
"Expected 'Invalid block range' error, got {:?}",
115+
res
116+
);
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)