Skip to content

Commit 65dd0f1

Browse files
authored
Merge pull request #91 from datachainlab/S2
S2
2 parents 548cd4a + c39f734 commit 65dd0f1

File tree

2 files changed

+74
-18
lines changed

2 files changed

+74
-18
lines changed

light-client/src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ pub enum Error {
141141
UnexpectedMissingForkSpecInCurrentEpochCalculation(BlockNumber, alloc::boxed::Box<Error>),
142142
UnexpectedMissingForkSpecInPreviousEpochCalculation(BlockNumber, alloc::boxed::Box<Error>),
143143
UnexpectedPreviousEpochInCalculatingNextEpoch(BlockNumber, BlockNumber, BlockNumber),
144+
UnexpectedEpochLength(u64, u64),
144145
MustBeEpoch(BlockNumber, ForkSpec),
145146
MustNotBeEpoch(BlockNumber, ForkSpec),
146147

@@ -508,6 +509,9 @@ impl core::fmt::Display for Error {
508509
Error::UnexpectedEpochInfo(e1, e2) => {
509510
write!(f, "UnexpectedEpochInfo : {} {}", e1, e2)
510511
}
512+
Error::UnexpectedEpochLength(e1, e2) => {
513+
write!(f, "UnexpectedEpochLength : {} {}", e1, e2)
514+
}
511515
Error::MustBeEpoch(e1, e2) => {
512516
write!(f, "MustBeEpoch : {} {:?}", e1, e2)
513517
}

light-client/src/fork_spec.rs

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use crate::misc::BlockNumber;
33
use parlia_ibc_proto::ibc::lightclients::parlia::v1::fork_spec::HeightOrTimestamp as RawHeightOrTimestamp;
44
use parlia_ibc_proto::ibc::lightclients::parlia::v1::ForkSpec as RawForkSpec;
55

6+
const DEFAULT_EPOCH_LENGTH: u64 = 200;
7+
68
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
79
pub enum HeightOrTimestamp {
810
Height(u64),
@@ -67,34 +69,44 @@ impl ForkSpec {
6769
/// current_first = 2000
6870
pub fn boundary_epochs(&self, prev_fork_spec: &ForkSpec) -> Result<BoundaryEpochs, Error> {
6971
if let HeightOrTimestamp::Height(height) = self.height_or_timestamp {
70-
let prev_last = height - (height % prev_fork_spec.epoch_length);
71-
let current_first = (height..).find(|&h| h % self.epoch_length == 0).unwrap();
72+
if self.epoch_length == 0 || prev_fork_spec.epoch_length == 0 {
73+
return Err(Error::UnexpectedEpochLength(
74+
self.epoch_length,
75+
prev_fork_spec.epoch_length,
76+
));
77+
}
78+
let previous_last = height - (height % prev_fork_spec.epoch_length);
79+
80+
let current_first = if height % self.epoch_length == 0 {
81+
height
82+
} else {
83+
height + (self.epoch_length - height % self.epoch_length)
84+
};
7285
let mut intermediates = vec![];
7386

7487
// starts 0, 200, 400...epoch_length
75-
if prev_last == 0 {
76-
const DEFAULT_EPOCH_LENGTH: u64 = 200;
88+
if previous_last == 0 {
7789
let additive: u64 = if prev_fork_spec.epoch_length > DEFAULT_EPOCH_LENGTH {
7890
DEFAULT_EPOCH_LENGTH
7991
} else {
8092
prev_fork_spec.epoch_length
8193
};
82-
let mut mid = prev_last + additive;
94+
let mut mid = previous_last + additive;
8395
while mid < prev_fork_spec.epoch_length {
8496
intermediates.push(mid);
8597
mid += additive;
8698
}
8799
}
88-
let mut mid = prev_last + prev_fork_spec.epoch_length;
100+
let mut mid = previous_last + prev_fork_spec.epoch_length;
89101
while mid < current_first {
90102
intermediates.push(mid);
91103
mid += prev_fork_spec.epoch_length;
92104
}
93105
return Ok(BoundaryEpochs {
94106
previous_fork_spec: prev_fork_spec.clone(),
95107
current_fork_spec: self.clone(),
108+
previous_last,
96109
current_first,
97-
prev_last,
98110
intermediates,
99111
});
100112
}
@@ -106,7 +118,7 @@ impl ForkSpec {
106118
pub struct BoundaryEpochs {
107119
previous_fork_spec: ForkSpec,
108120
current_fork_spec: ForkSpec,
109-
prev_last: BlockNumber,
121+
previous_last: BlockNumber,
110122
current_first: BlockNumber,
111123
intermediates: alloc::vec::Vec<BlockNumber>,
112124
}
@@ -147,14 +159,14 @@ impl BoundaryEpochs {
147159
return 0;
148160
}
149161
// Before HF
150-
if current_epoch_block_number <= self.prev_last {
162+
if current_epoch_block_number <= self.previous_last {
151163
return current_epoch_block_number - self.previous_fork_spec.epoch_length;
152164
}
153165

154166
for (i, mid) in self.intermediates.iter().enumerate() {
155167
if current_epoch_block_number == *mid {
156168
if i == 0 {
157-
return self.prev_last;
169+
return self.previous_last;
158170
} else {
159171
return self.intermediates[i - 1];
160172
}
@@ -163,7 +175,7 @@ impl BoundaryEpochs {
163175

164176
if current_epoch_block_number == self.current_first {
165177
if self.intermediates.is_empty() {
166-
return self.prev_last;
178+
return self.previous_last;
167179
}
168180
return *self.intermediates.last().unwrap();
169181
}
@@ -600,36 +612,76 @@ mod test {
600612
}
601613
}
602614

615+
#[test]
616+
fn test_error_boundary_epochs_current_epoch_length_zero() {
617+
let current = ForkSpec {
618+
height_or_timestamp: HeightOrTimestamp::Height(0),
619+
additional_header_item_count: 1,
620+
epoch_length: 0,
621+
max_turn_length: 64,
622+
};
623+
match current
624+
.boundary_epochs(&fork_spec_after_pascal())
625+
.unwrap_err()
626+
{
627+
Error::UnexpectedEpochLength(e1, e2) => {
628+
assert_eq!(current.epoch_length, e1);
629+
assert_ne!(current.epoch_length, e2);
630+
}
631+
_ => unreachable!("unexpected error"),
632+
}
633+
}
634+
635+
#[test]
636+
fn test_error_boundary_epochs_previous_epoch_length_zero() {
637+
let previous = ForkSpec {
638+
height_or_timestamp: HeightOrTimestamp::Height(0),
639+
additional_header_item_count: 1,
640+
epoch_length: 0,
641+
max_turn_length: 64,
642+
};
643+
match fork_spec_after_pascal()
644+
.boundary_epochs(&previous)
645+
.unwrap_err()
646+
{
647+
Error::UnexpectedEpochLength(e1, e2) => {
648+
assert_ne!(previous.epoch_length, e1);
649+
assert_eq!(previous.epoch_length, e2);
650+
}
651+
_ => unreachable!("unexpected error"),
652+
}
653+
}
654+
603655
#[test]
604656
fn test_success_boundary_epochs() {
605657
let mut f1 = fork_spec_after_lorentz().clone();
606658
f1.height_or_timestamp = HeightOrTimestamp::Height(1501);
607659
let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap();
608-
assert_eq!(be.prev_last, 1400);
660+
assert_eq!(be.previous_last, 1400);
609661
assert_eq!(be.intermediates, vec![1600, 1800]);
610662
assert_eq!(be.current_first, 2000);
611663

612664
f1.height_or_timestamp = HeightOrTimestamp::Height(1600);
613665
let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap();
614-
assert_eq!(be.prev_last, 1600);
666+
assert_eq!(be.previous_last, 1600);
615667
assert_eq!(be.intermediates, vec![1800]);
616668
assert_eq!(be.current_first, 2000);
617669

618670
f1.height_or_timestamp = HeightOrTimestamp::Height(1601);
619671
let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap();
620-
assert_eq!(be.prev_last, 1600);
672+
assert_eq!(be.previous_last, 1600);
621673
assert_eq!(be.intermediates, vec![1800]);
622674
assert_eq!(be.current_first, 2000);
623675

624676
f1.height_or_timestamp = HeightOrTimestamp::Height(1800);
625677
let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap();
626-
assert_eq!(be.prev_last, 1800);
678+
assert_eq!(be.previous_last, 1800);
627679
assert_eq!(be.intermediates, vec![]);
628680
assert_eq!(be.current_first, 2000);
629681

630682
f1.height_or_timestamp = HeightOrTimestamp::Height(2000);
631683
let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap();
632-
assert_eq!(be.prev_last, 2000);
684+
assert_eq!(be.previous_last, 2000);
633685
assert_eq!(be.intermediates, vec![]);
634686
assert_eq!(be.current_first, 2000);
635687
}
@@ -639,7 +691,7 @@ mod test {
639691
let be = fork_spec_after_lorentz()
640692
.boundary_epochs(&fork_spec_after_pascal())
641693
.unwrap();
642-
assert_eq!(be.prev_last, 0);
694+
assert_eq!(be.previous_last, 0);
643695
assert_eq!(be.intermediates[0], 200);
644696
assert_eq!(be.intermediates[1], 400);
645697
assert_eq!(be.current_first, 500);
@@ -670,7 +722,7 @@ mod test {
670722
let be = fork_spec_after_maxwell()
671723
.boundary_epochs(&fork_spec_after_lorentz())
672724
.unwrap();
673-
assert_eq!(be.prev_last, 0);
725+
assert_eq!(be.previous_last, 0);
674726
assert_eq!(be.intermediates[0], 200);
675727
assert_eq!(be.intermediates[1], 400);
676728
assert_eq!(be.intermediates[2], 500);

0 commit comments

Comments
 (0)