Skip to content

Commit 307e516

Browse files
author
Daniel Kuehr
committed
Fix arithmetic and other lints
1 parent 3b99cd2 commit 307e516

37 files changed

+333
-147
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ members = [
3636
resolver = "2"
3737

3838
[workspace.lints.clippy]
39-
unwrap_used = "warn"
39+
#unwrap_used = "warn"
4040
arithmetic_side_effects = "warn"
4141
indexing_slicing = "warn"
4242

@@ -53,7 +53,7 @@ poly-commitment = {git = "https://github.com/openmina/proof-systems", rev = "2fd
5353
libp2p = { git = "https://github.com/openmina/rust-libp2p", rev = "5c44c7d9", default-features = false }
5454
vrf = { path = "vrf" }
5555
openmina-node-account = { path = "node/account" }
56-
redux = { git = "https://github.com/openmina/redux-rs.git", rev = "741a01d", features = ["serde"] }
56+
redux = { git = "https://github.com/openmina/redux-rs.git", rev = "ab14890c", features = ["serde"] }
5757
serde = "1.0.190"
5858
serde_json = "1.0.107"
5959
serde_with = { version = "3.7.0", features = ["hex"] }

node/build.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ fn main() -> Result<(), Box<dyn Error>> {
126126

127127
visit_dirs(&node_dir, &mut |file| {
128128
let mut path = file.path();
129-
let path_str = path.to_str().unwrap();
129+
let path_str = path.to_str().expect("path");
130130
if !path_str.ends_with("_actions.rs") && !path_str.ends_with("action.rs") {
131131
return;
132132
}
@@ -156,7 +156,8 @@ fn main() -> Result<(), Box<dyn Error>> {
156156
if let Some(action_name) = matches.get(2) {
157157
let action_name = action_name.as_str().to_owned();
158158
// Without 'Action' suffix
159-
let action_name_base = action_name[..(action_name.len() - 6)].to_string();
159+
let action_name_base =
160+
action_name[..(action_name.len().saturating_sub(6))].to_string();
160161
let mut variant_lines = vec![];
161162
loop {
162163
let Some(line) = lines.next() else { break };
@@ -252,8 +253,7 @@ fn main() -> Result<(), Box<dyn Error>> {
252253
.map(|(k, v)| {
253254
let mut s = "use crate::".to_owned();
254255
if !k.is_empty() {
255-
s += &k.join("::");
256-
s += "::";
256+
s.push_str(&format!("{}::", k.join("::")));
257257
}
258258
s += &format!("{{{}}};", v.join(", "));
259259
s
@@ -268,8 +268,7 @@ fn main() -> Result<(), Box<dyn Error>> {
268268
if meta.is_inlined() {
269269
meta.action_kinds()
270270
} else {
271-
// Remove suffix `Action` from action name.
272-
vec![name[..(name.len() - 6)].to_string()]
271+
vec![name[..name.len().saturating_sub(6)].to_string()]
273272
}
274273
});
275274
let action_kinds = std::iter::once("None".to_owned())
@@ -304,7 +303,7 @@ fn main() -> Result<(), Box<dyn Error>> {
304303
while let Some(action_name) = queue.pop_front() {
305304
let fn_body = match actions.get(dbg!(&action_name)).unwrap() {
306305
ActionMeta::Struct => {
307-
let action_kind = &action_name[..(action_name.len() - 6)];
306+
let action_kind = &action_name[..(action_name.len().saturating_sub(6))];
308307
format!("ActionKind::{action_kind}")
309308
}
310309
ActionMeta::Enum(variants) => {

node/common/src/service/p2p.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl webrtc::P2pServiceWebrtc for NodeService {
4444
&mut self,
4545
other_pk: &PublicKey,
4646
message: &T,
47-
) -> Result<T::Encrypted, ()> {
47+
) -> Result<T::Encrypted, Box<dyn std::error::Error>> {
4848
let rng = &mut self.rng;
4949
self.p2p.sec_key.encrypt(other_pk, rng, message)
5050
}
@@ -53,7 +53,7 @@ impl webrtc::P2pServiceWebrtc for NodeService {
5353
&mut self,
5454
other_pk: &PublicKey,
5555
encrypted: &T::Encrypted,
56-
) -> Result<T, ()> {
56+
) -> Result<T, Box<dyn std::error::Error>> {
5757
self.p2p.sec_key.decrypt(other_pk, encrypted)
5858
}
5959

node/src/block_producer/block_producer_reducer.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,10 @@ impl BlockProducerEnabled {
145145
if let Some(won_slot) = state.current.won_slot() {
146146
if let Some(chain) = best_chain.last().map(|best_tip| {
147147
if best_tip.global_slot() == won_slot.global_slot() {
148-
// We are producing block which replaces current best tip
149-
// instead of extending it.
150-
best_chain[..(best_chain.len() - 1)].to_vec()
148+
best_chain
149+
.get(..best_chain.len().saturating_sub(1))
150+
.unwrap_or(&[])
151+
.to_vec()
151152
} else {
152153
best_chain.to_vec()
153154
}
@@ -430,14 +431,24 @@ impl BlockProducerEnabled {
430431
epoch_length: v2::UnsignedExtendedUInt32StableV1(1.into()),
431432
};
432433
let epoch_count = v2::UnsignedExtendedUInt32StableV1(
433-
(pred_consensus_state.epoch_count.as_u32() + 1).into(),
434+
(pred_consensus_state
435+
.epoch_count
436+
.as_u32()
437+
.checked_add(1)
438+
.expect("overflow"))
439+
.into(),
434440
);
435441
(staking_data, next_data, epoch_count)
436442
} else {
437443
assert_eq!(pred_epoch, next_epoch);
438444
let mut next_data = pred_consensus_state.next_epoch_data.clone();
439445
next_data.epoch_length = v2::UnsignedExtendedUInt32StableV1(
440-
(next_data.epoch_length.as_u32() + 1).into(),
446+
(next_data
447+
.epoch_length
448+
.as_u32()
449+
.checked_add(1)
450+
.expect("overflow"))
451+
.into(),
441452
);
442453
(
443454
pred_consensus_state.staking_epoch_data.clone(),
@@ -475,7 +486,8 @@ impl BlockProducerEnabled {
475486

476487
let is_same_global_sub_window = pred_global_sub_window == next_global_sub_window;
477488
let are_windows_overlapping = pred_global_sub_window
478-
+ constraint_constants().sub_windows_per_window as u32
489+
.checked_add(constraint_constants().sub_windows_per_window as u32)
490+
.expect("overflow")
479491
>= next_global_sub_window;
480492

481493
let current_sub_window_densities = pred_sub_window_densities
@@ -525,7 +537,7 @@ impl BlockProducerEnabled {
525537
0
526538
};
527539
if incr_window {
528-
density + 1
540+
density.saturating_add(1)
529541
} else {
530542
density
531543
}
@@ -545,7 +557,9 @@ impl BlockProducerEnabled {
545557
&global_slot_since_genesis,
546558
);
547559
let consensus_state = v2::ConsensusProofOfStakeDataConsensusStateValueStableV2 {
548-
blockchain_length: v2::UnsignedExtendedUInt32StableV1((pred_block.height() + 1).into()),
560+
blockchain_length: v2::UnsignedExtendedUInt32StableV1(
561+
(pred_block.height().saturating_add(1)).into(),
562+
),
549563
epoch_count,
550564
min_window_density,
551565
sub_window_densities,
@@ -592,7 +606,11 @@ impl BlockProducerEnabled {
592606
0 => (pred_block.hash().clone(), List::new()),
593607
chain_proof_len => {
594608
// TODO(binier): test
595-
let mut iter = chain.iter().rev().take(chain_proof_len + 1).rev();
609+
let mut iter = chain
610+
.iter()
611+
.rev()
612+
.take(chain_proof_len.saturating_add(1))
613+
.rev();
596614
if let Some(first_block) = iter.next() {
597615
let first_hash = first_block.hash().clone();
598616
let body_hashes = iter

node/src/block_producer/block_producer_state.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,13 @@ impl BlockProducerCurrentState {
302302
match self {
303303
Self::WonSlot { won_slot, .. } | Self::WonSlotWait { won_slot, .. } => {
304304
// Make sure to only producer blocks when in the slot interval
305-
let slot_upper_bound = won_slot.slot_time + slot_interval;
306-
let estimated_produced_time = now + BLOCK_PRODUCTION_ESTIMATE;
305+
let slot_upper_bound = won_slot
306+
.slot_time
307+
.checked_add(slot_interval)
308+
.expect("overflow");
309+
let estimated_produced_time = now
310+
.checked_add(BLOCK_PRODUCTION_ESTIMATE)
311+
.expect("overflow");
307312
estimated_produced_time >= won_slot.slot_time && now < slot_upper_bound
308313
}
309314
_ => false,

node/src/block_producer/mod.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,30 @@ impl BlockProducerWonSlot {
7878
fn calculate_slot_time(genesis_timestamp: redux::Timestamp, slot: u32) -> redux::Timestamp {
7979
// FIXME: this calculation must use values from the protocol constants,
8080
// now it assumes 3 minutes blocks.
81-
genesis_timestamp + (slot as u64) * 3 * 60 * 1_000_000_000_u64
81+
genesis_timestamp
82+
.checked_add(
83+
(slot as u64)
84+
.checked_mul(3u64.saturating_mul(60).saturating_mul(1_000_000_000_u64))
85+
.expect("overflow"),
86+
)
87+
.expect("overflow")
8288
}
8389

8490
pub fn global_slot(&self) -> u32 {
8591
self.global_slot.slot_number.as_u32()
8692
}
8793

8894
pub fn epoch(&self) -> u32 {
89-
self.global_slot() / self.global_slot.slots_per_epoch.as_u32()
95+
self.global_slot()
96+
.checked_div(self.global_slot.slots_per_epoch.as_u32())
97+
.expect("division by 0")
9098
}
9199

92100
pub fn global_slot_since_genesis(
93101
&self,
94102
slot_diff: u32,
95103
) -> v2::MinaNumbersGlobalSlotSinceGenesisMStableV1 {
96-
let slot = self.global_slot() + slot_diff;
104+
let slot = self.global_slot().checked_add(slot_diff).expect("overflow");
97105
v2::MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(slot.into())
98106
}
99107

@@ -105,7 +113,9 @@ impl BlockProducerWonSlot {
105113
}
106114

107115
pub fn next_slot_time(&self) -> redux::Timestamp {
108-
self.slot_time + 3 * 60 * 1_000_000_000_u64
116+
self.slot_time
117+
.checked_add(3u64.saturating_mul(60).saturating_mul(1_000_000_000_u64))
118+
.expect("overflow")
109119
}
110120
}
111121

@@ -145,14 +155,24 @@ impl PartialOrd<ArcBlockWithHash> for BlockProducerWonSlot {
145155
}
146156

147157
pub fn to_epoch_and_slot(global_slot: &v2::ConsensusGlobalSlotStableV1) -> (u32, u32) {
148-
let epoch = global_slot.slot_number.as_u32() / global_slot.slots_per_epoch.as_u32();
149-
let slot = global_slot.slot_number.as_u32() % global_slot.slots_per_epoch.as_u32();
158+
let epoch = global_slot
159+
.slot_number
160+
.as_u32()
161+
.checked_div(global_slot.slots_per_epoch.as_u32())
162+
.expect("division by 0");
163+
let slot = global_slot
164+
.slot_number
165+
.as_u32()
166+
.checked_rem(global_slot.slots_per_epoch.as_u32())
167+
.expect("division by 0");
150168
(epoch, slot)
151169
}
152170

153171
pub fn next_epoch_first_slot(global_slot: &v2::ConsensusGlobalSlotStableV1) -> u32 {
154172
let (epoch, _) = to_epoch_and_slot(global_slot);
155-
(epoch + 1) * global_slot.slots_per_epoch.as_u32()
173+
(epoch.saturating_add(1))
174+
.checked_mul(global_slot.slots_per_epoch.as_u32())
175+
.expect("overflow")
156176
}
157177

158178
// Returns the epoch number and whether it is the last slot of the epoch

node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_actions.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ impl redux::EnablingCondition<crate::State> for BlockProducerVrfEvaluatorAction
133133
} => state.block_producer.with(false, |this| {
134134
if this.vrf_evaluator.is_slot_requested() {
135135
if let Some(current_evaluation) = this.vrf_evaluator.current_evaluation() {
136-
current_evaluation.latest_evaluated_slot + 1 == vrf_output.global_slot()
136+
current_evaluation
137+
.latest_evaluated_slot
138+
.checked_add(1)
139+
.expect("overflow")
140+
== vrf_output.global_slot()
137141
&& current_evaluation.epoch_data.ledger == *staking_ledger_hash
138142
} else {
139143
false

node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_reducer.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ impl BlockProducerVrfEvaluatorState {
191191
best_tip_epoch,
192192
root_block_epoch: *root_block_epoch,
193193
is_current_epoch_evaluated: state.is_epoch_evaluated(best_tip_epoch),
194-
is_next_epoch_evaluated: state.is_epoch_evaluated(best_tip_epoch + 1),
194+
is_next_epoch_evaluated: state
195+
.is_epoch_evaluated(best_tip_epoch.checked_add(1).expect("overflow")),
195196
last_evaluated_epoch: state.last_evaluated_epoch(),
196197
staking_epoch_data: staking_epoch_data.clone(),
197198
next_epoch_data: next_epoch_data.clone(),
@@ -235,7 +236,8 @@ impl BlockProducerVrfEvaluatorState {
235236
time: meta.time(),
236237
best_tip_epoch: *best_tip_epoch,
237238
is_current_epoch_evaluated: state.is_epoch_evaluated(*best_tip_epoch),
238-
is_next_epoch_evaluated: state.is_epoch_evaluated(best_tip_epoch + 1),
239+
is_next_epoch_evaluated: state
240+
.is_epoch_evaluated(best_tip_epoch.checked_add(1).expect("overflow")),
239241
best_tip_slot: *best_tip_slot,
240242
best_tip_global_slot: *best_tip_global_slot,
241243
next_epoch_first_slot: *next_epoch_first_slot,
@@ -425,7 +427,10 @@ impl BlockProducerVrfEvaluatorState {
425427
} => {
426428
let (epoch_number, initial_slot) = match state.epoch_context() {
427429
super::EpochContext::Current(_) => (*best_tip_epoch, *current_global_slot),
428-
super::EpochContext::Next(_) => (best_tip_epoch + 1, next_epoch_first_slot - 1),
430+
super::EpochContext::Next(_) => (
431+
best_tip_epoch.checked_add(1).expect("overflow"),
432+
next_epoch_first_slot.checked_sub(1).expect("underflow"),
433+
),
429434
super::EpochContext::Waiting => todo!(),
430435
};
431436
state.status = BlockProducerVrfEvaluatorStatus::InitialSlotSelection {

node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_state.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl BlockProducerVrfEvaluatorState {
4646
pub fn evaluate_epoch_bounds(global_slot: &u32) -> SlotPositionInEpoch {
4747
if global_slot % SLOTS_PER_EPOCH == 0 {
4848
SlotPositionInEpoch::Beginning
49-
} else if (global_slot + 1) % SLOTS_PER_EPOCH == 0 {
49+
} else if (global_slot.checked_add(1).expect("overflow")) % SLOTS_PER_EPOCH == 0 {
5050
SlotPositionInEpoch::End
5151
} else {
5252
SlotPositionInEpoch::Within
@@ -111,7 +111,7 @@ impl BlockProducerVrfEvaluatorState {
111111

112112
if !self.is_epoch_evaluated(best_tip_epoch) {
113113
self.epoch_context = EpochContext::Current((*staking_epoch_data).into())
114-
} else if !self.is_epoch_evaluated(best_tip_epoch + 1) {
114+
} else if !self.is_epoch_evaluated(best_tip_epoch.checked_add(1).expect("overflow")) {
115115
if root_block_epoch == best_tip_epoch && is_next_epoch_seed_finalized {
116116
self.epoch_context = EpochContext::Next((*next_epoch_data).into())
117117
} else {
@@ -284,7 +284,9 @@ impl BlockProducerVrfEvaluatorState {
284284
{
285285
match self.epoch_context {
286286
EpochContext::Current(_) => self.last_evaluated_epoch = Some(*epoch_number),
287-
EpochContext::Next(_) => self.last_evaluated_epoch = Some(epoch_number + 1),
287+
EpochContext::Next(_) => {
288+
self.last_evaluated_epoch = Some(epoch_number.checked_add(1).expect("overflow"))
289+
}
288290
EpochContext::Waiting => {}
289291
}
290292
}
@@ -333,7 +335,10 @@ impl BlockProducerVrfEvaluatorState {
333335
Some(VrfEvaluatorInput::new(
334336
pending_evaluation.epoch_data.seed,
335337
pending_evaluation.epoch_data.delegator_table,
336-
pending_evaluation.latest_evaluated_slot + 1,
338+
pending_evaluation
339+
.latest_evaluated_slot
340+
.checked_add(1)
341+
.expect("overflow"),
337342
pending_evaluation.epoch_data.total_currency,
338343
pending_evaluation.epoch_data.ledger,
339344
))
@@ -345,7 +350,7 @@ impl BlockProducerVrfEvaluatorState {
345350
pub fn retention_slot(&self, current_epoch_number: &u32) -> u32 {
346351
const PAST_EPOCHS_TO_KEEP: u32 = 2;
347352
let cutoff_epoch = current_epoch_number.saturating_sub(PAST_EPOCHS_TO_KEEP);
348-
(cutoff_epoch * SLOTS_PER_EPOCH).saturating_sub(1)
353+
(cutoff_epoch.saturating_mul(SLOTS_PER_EPOCH)).saturating_sub(1)
349354
}
350355

351356
pub fn cleanup_old_won_slots(&mut self, current_epoch_number: &u32) {

0 commit comments

Comments
 (0)