Skip to content

Commit eee33e2

Browse files
committed
extract warn side-effect from ProposalMonitor
1 parent a85368c commit eee33e2

3 files changed

Lines changed: 50 additions & 21 deletions

File tree

crates/malachite-app/src/handlers/get_value.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use malachitebft_app_channel::app::types::LocallyProposedValue;
2626
use malachitebft_app_channel::{NetworkMsg, Reply};
2727
use malachitebft_core_types::Validity;
2828

29-
use arc_consensus_types::{Address, ArcContext, Height};
29+
use arc_consensus_types::{Address, ArcContext, Height, ValueId};
3030
use arc_eth_engine::engine::Engine;
3131
use arc_eth_engine::json_structures::ExecutionBlock;
3232
use arc_signer::ArcSigningProvider;
@@ -90,12 +90,7 @@ pub async fn handle(
9090

9191
if let Some(proposed_value) = proposed_value {
9292
if round.as_i64() == 0 {
93-
if let Some(monitor) = &mut state.proposal_monitor {
94-
debug_assert_eq!(monitor.height, height, "proposal monitor height mismatch");
95-
monitor.record_proposal(proposed_value.value.id());
96-
} else {
97-
warn!(%height, %round, "No proposal monitor present");
98-
}
93+
record_self_proposal_in_monitor(state, height, proposed_value.value.id());
9994
}
10095

10196
if let Err(e) = reply.send(proposed_value) {
@@ -308,3 +303,20 @@ async fn get_previously_built_block(
308303
let block = blocks.into_iter().find(|p| p.proposer == proposer);
309304
Ok(block)
310305
}
306+
307+
/// Records the proposed value in the proposal monitor for the given height, if the monitor exists.
308+
fn record_self_proposal_in_monitor(state: &mut State, height: Height, value_id: ValueId) {
309+
let Some(monitor) = &mut state.proposal_monitor else {
310+
warn!(%height, round = 0, "No proposal monitor present");
311+
return;
312+
};
313+
debug_assert_eq!(monitor.height, height, "proposal monitor height mismatch");
314+
if !monitor.record_proposal(value_id) {
315+
warn!(
316+
height = %monitor.height,
317+
first_value = %monitor.value_id.unwrap(),
318+
new_value = %value_id,
319+
"Equivocating proposal at round 0"
320+
);
321+
}
322+
}

crates/malachite-app/src/handlers/received_proposal_part.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,14 @@ fn record_proposal_in_monitor(state: &mut State, proposed_value: &ProposedValue<
128128
return;
129129
}
130130

131-
monitor.record_proposal(proposed_value.value.id());
131+
if !monitor.record_proposal(proposed_value.value.id()) {
132+
warn!(
133+
height = %monitor.height,
134+
first_value = %monitor.value_id.unwrap(),
135+
new_value = %proposed_value.value.id(),
136+
"Equivocating proposal at round 0"
137+
);
138+
}
132139
}
133140

134141
struct HandlerContext<'a, 'b> {

crates/types/src/proposal_monitor.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
//! By design, monitoring data is only stored for round-0 proposals.
2828
2929
use std::time::SystemTime;
30-
use tracing::warn;
30+
// use tracing::warn;
3131

3232
use crate::{Address, Height, ValueId};
3333

@@ -117,22 +117,16 @@ impl ProposalMonitor {
117117

118118
/// Record that proposal was received.
119119
/// Takes precedence over synced value.
120-
pub fn record_proposal(&mut self, value_id: ValueId) {
121-
// FIXME: this log message should not be produced here.
122-
if let Some(first_value) = self.value_id
123-
&& !self.synced
124-
{
125-
warn!(
126-
height = %self.height,
127-
%first_value,
128-
new_value = %value_id,
129-
"Equivocating proposal at round 0"
130-
);
131-
return;
120+
/// Returns `true` if this is the first proposal recorded,
121+
/// `false` if a previous proposal exist (equivocation).
122+
pub fn record_proposal(&mut self, value_id: ValueId) -> bool {
123+
if self.value_id.is_some() && !self.synced {
124+
return false;
132125
}
133126
self.proposal_receive_time = Some(SystemTime::now());
134127
self.value_id = Some(value_id);
135128
self.synced = false;
129+
true
136130
}
137131

138132
/// Check if the decided value matches the recorded proposal.
@@ -236,6 +230,22 @@ mod tests {
236230
assert_eq!(monitor.value_id, Some(value_id1));
237231
}
238232

233+
#[test]
234+
fn test_record_proposal_duplicate_returns_false() {
235+
let mut monitor = ProposalMonitor::new(Height::new(1), test_address(), SystemTime::now());
236+
237+
let value_id1 = test_value_id(0x11);
238+
assert!(monitor.record_proposal(value_id1));
239+
let time1 = monitor.proposal_receive_time.unwrap();
240+
241+
// Second proposal returns false (equivocation), first value preserved
242+
let value_id2 = test_value_id(0x22);
243+
assert!(!monitor.record_proposal(value_id2));
244+
245+
assert_eq!(monitor.proposal_receive_time, Some(time1));
246+
assert_eq!(monitor.value_id, Some(value_id1));
247+
}
248+
239249
#[test]
240250
fn test_mark_decided_successful() {
241251
let mut monitor = ProposalMonitor::new(Height::new(1), test_address(), SystemTime::now());

0 commit comments

Comments
 (0)