From 11bec9da06b38b4cb358eb7b55fe5efb613eaf82 Mon Sep 17 00:00:00 2001 From: ss-es <155648797+ss-es@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:40:29 -0400 Subject: [PATCH 1/7] add byzantine test for sending multiple bad proposals --- crates/hotshot/src/tasks/mod.rs | 43 ++++++++++++++++++++ crates/testing/tests/tests_1/test_success.rs | 29 ++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/crates/hotshot/src/tasks/mod.rs b/crates/hotshot/src/tasks/mod.rs index a370034a97..011d554371 100644 --- a/crates/hotshot/src/tasks/mod.rs +++ b/crates/hotshot/src/tasks/mod.rs @@ -314,6 +314,8 @@ where let mut results = state.send_handler(&msg).await; + results.reverse(); + while let Some(event) = results.pop() { let _ = sender_to_network.broadcast(event.into()).await; } @@ -330,6 +332,8 @@ where let mut results = state.recv_handler(&msg).await; + results.reverse(); + while let Some(event) = results.pop() { let _ = original_sender.broadcast(event.into()).await; } @@ -342,6 +346,45 @@ where } } +#[derive(Debug)] +/// An `EventTransformerState` that multiplies `QuorumProposalSend` events, incrementing the view number of the proposal +pub struct BadProposalViewDos { + /// The number of times to duplicate a `QuorumProposalSend` event + pub multiplier: u64, + /// The view number increment each time it's duplicated + pub increment: u64, +} + +#[async_trait] +impl> EventTransformerState + for BadProposalViewDos +{ + async fn recv_handler(&mut self, event: &HotShotEvent) -> Vec> { + vec![event.clone()] + } + + async fn send_handler(&mut self, event: &HotShotEvent) -> Vec> { + match event { + HotShotEvent::QuorumProposalSend(proposal, signature) => { + let mut result = Vec::new(); + + for n in 0..self.multiplier { + let mut modified_proposal = proposal.clone(); + + modified_proposal.data.view_number += (n * self.increment).into(); + + result.push(HotShotEvent::QuorumProposalSend(modified_proposal, signature.clone())) + } + + result + } + _ => vec![event.clone()], + } + } +} + + + #[derive(Debug)] /// An `EventHandlerState` that doubles the `QuorumVoteSend` and `QuorumProposalSend` events pub struct DoubleProposeVote; diff --git a/crates/testing/tests/tests_1/test_success.rs b/crates/testing/tests/tests_1/test_success.rs index fb2ef50d5b..82b09f6771 100644 --- a/crates/testing/tests/tests_1/test_success.rs +++ b/crates/testing/tests/tests_1/test_success.rs @@ -11,7 +11,7 @@ use hotshot_testing::{ test_builder::TestDescription, }; #[cfg(async_executor_impl = "async-std")] -use {hotshot::tasks::DoubleProposeVote, hotshot_testing::test_builder::Behaviour, std::rc::Rc}; +use {hotshot::tasks::{DoubleProposeVote, BadProposalViewDos}, hotshot_testing::test_builder::Behaviour, std::rc::Rc}; cross_tests!( TestName: test_success, @@ -33,7 +33,7 @@ cross_tests!( #[cfg(async_executor_impl = "async-std")] cross_tests!( - TestName: twins_test_success, + TestName: double_propose_vote, Impls: [MemoryImpl], Types: [TestTypes], Ignore: false, @@ -55,3 +55,28 @@ cross_tests!( } }, ); + +#[cfg(async_executor_impl = "async-std")] +cross_tests!( + TestName: multiple_bad_proposals, + Impls: [MemoryImpl], + Types: [TestTypes], + Ignore: false, + Metadata: { + let behaviour = Rc::new(|node_id| { match node_id { + 4 => Behaviour::Byzantine(Box::new(BadProposalViewDos { multiplier: 100, increment: 1 })), + _ => Behaviour::Standard, + } }); + + TestDescription { + // allow more time to pass in CI + completion_task_description: CompletionTaskDescription::TimeBasedCompletionTaskBuilder( + TimeBasedCompletionTaskDescription { + duration: Duration::from_secs(60), + }, + ), + behaviour, + ..TestDescription::default() + } + }, +); From faf10dc3f2d7c36fbb34233d393ab3bb0373353c Mon Sep 17 00:00:00 2001 From: ss-es <155648797+ss-es@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:42:36 -0400 Subject: [PATCH 2/7] set num_failed_views = 1 --- crates/testing/tests/tests_1/test_success.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/testing/tests/tests_1/test_success.rs b/crates/testing/tests/tests_1/test_success.rs index 82b09f6771..645020d4b6 100644 --- a/crates/testing/tests/tests_1/test_success.rs +++ b/crates/testing/tests/tests_1/test_success.rs @@ -68,7 +68,7 @@ cross_tests!( _ => Behaviour::Standard, } }); - TestDescription { + let mut metadata = TestDescription { // allow more time to pass in CI completion_task_description: CompletionTaskDescription::TimeBasedCompletionTaskBuilder( TimeBasedCompletionTaskDescription { @@ -77,6 +77,10 @@ cross_tests!( ), behaviour, ..TestDescription::default() - } + }; + + metadata.overall_safety_properties.num_failed_views = 1; + + metadata }, ); From ee8c2b68be3b0227da510413deef4aedb824444e Mon Sep 17 00:00:00 2001 From: ss-es <155648797+ss-es@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:36:01 -0400 Subject: [PATCH 3/7] fmt --- crates/hotshot/src/tasks/mod.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/crates/hotshot/src/tasks/mod.rs b/crates/hotshot/src/tasks/mod.rs index 5d9615b75f..42a5eaebab 100644 --- a/crates/hotshot/src/tasks/mod.rs +++ b/crates/hotshot/src/tasks/mod.rs @@ -349,15 +349,15 @@ where #[derive(Debug)] /// An `EventTransformerState` that multiplies `QuorumProposalSend` events, incrementing the view number of the proposal pub struct BadProposalViewDos { - /// The number of times to duplicate a `QuorumProposalSend` event - pub multiplier: u64, - /// The view number increment each time it's duplicated - pub increment: u64, + /// The number of times to duplicate a `QuorumProposalSend` event + pub multiplier: u64, + /// The view number increment each time it's duplicated + pub increment: u64, } #[async_trait] impl> EventTransformerState - for BadProposalViewDos + for BadProposalViewDos { async fn recv_handler(&mut self, event: &HotShotEvent) -> Vec> { vec![event.clone()] @@ -366,25 +366,26 @@ impl> EventTransformerState) -> Vec> { match event { HotShotEvent::QuorumProposalSend(proposal, signature) => { - let mut result = Vec::new(); + let mut result = Vec::new(); - for n in 0..self.multiplier { - let mut modified_proposal = proposal.clone(); + for n in 0..self.multiplier { + let mut modified_proposal = proposal.clone(); - modified_proposal.data.view_number += (n * self.increment).into(); + modified_proposal.data.view_number += (n * self.increment).into(); - result.push(HotShotEvent::QuorumProposalSend(modified_proposal, signature.clone())) - } + result.push(HotShotEvent::QuorumProposalSend( + modified_proposal, + signature.clone(), + )) + } - result + result } _ => vec![event.clone()], } } } - - #[derive(Debug)] /// An `EventHandlerState` that doubles the `QuorumVoteSend` and `QuorumProposalSend` events pub struct DoubleProposeVote; From 391bc652e69fae9cdba031dcfdf88d7cd0424906 Mon Sep 17 00:00:00 2001 From: ss-es <155648797+ss-es@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:36:57 -0400 Subject: [PATCH 4/7] set num failed views to 0 --- crates/testing/tests/tests_1/test_success.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/testing/tests/tests_1/test_success.rs b/crates/testing/tests/tests_1/test_success.rs index 645020d4b6..618e8a71df 100644 --- a/crates/testing/tests/tests_1/test_success.rs +++ b/crates/testing/tests/tests_1/test_success.rs @@ -79,7 +79,7 @@ cross_tests!( ..TestDescription::default() }; - metadata.overall_safety_properties.num_failed_views = 1; + metadata.overall_safety_properties.num_failed_views = 0; metadata }, From b00f21c3775e4b1c734aa7ec2f006a799e436de5 Mon Sep 17 00:00:00 2001 From: ss-es <155648797+ss-es@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:53:36 -0400 Subject: [PATCH 5/7] clippy --- crates/hotshot/src/tasks/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/hotshot/src/tasks/mod.rs b/crates/hotshot/src/tasks/mod.rs index 42a5eaebab..5ed9503891 100644 --- a/crates/hotshot/src/tasks/mod.rs +++ b/crates/hotshot/src/tasks/mod.rs @@ -371,12 +371,12 @@ impl> EventTransformerState Date: Wed, 31 Jul 2024 10:57:22 -0400 Subject: [PATCH 6/7] comment --- crates/testing/tests/tests_1/test_success.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/testing/tests/tests_1/test_success.rs b/crates/testing/tests/tests_1/test_success.rs index 618e8a71df..267daa6b5a 100644 --- a/crates/testing/tests/tests_1/test_success.rs +++ b/crates/testing/tests/tests_1/test_success.rs @@ -57,6 +57,7 @@ cross_tests!( ); #[cfg(async_executor_impl = "async-std")] +/// Test where node 4 sends out the correct quorum proposal and additionally spams the network with an extra 99 malformed proposals cross_tests!( TestName: multiple_bad_proposals, Impls: [MemoryImpl], From e86da6a2698b906989cb2f34c9156920faac370b Mon Sep 17 00:00:00 2001 From: ss-es <155648797+ss-es@users.noreply.github.com> Date: Wed, 31 Jul 2024 11:01:17 -0400 Subject: [PATCH 7/7] clippy --- crates/testing/tests/tests_1/test_success.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/testing/tests/tests_1/test_success.rs b/crates/testing/tests/tests_1/test_success.rs index 267daa6b5a..90acc43eb2 100644 --- a/crates/testing/tests/tests_1/test_success.rs +++ b/crates/testing/tests/tests_1/test_success.rs @@ -11,7 +11,11 @@ use hotshot_testing::{ test_builder::TestDescription, }; #[cfg(async_executor_impl = "async-std")] -use {hotshot::tasks::{DoubleProposeVote, BadProposalViewDos}, hotshot_testing::test_builder::Behaviour, std::rc::Rc}; +use { + hotshot::tasks::{BadProposalViewDos, DoubleProposeVote}, + hotshot_testing::test_builder::Behaviour, + std::rc::Rc, +}; cross_tests!( TestName: test_success, @@ -56,8 +60,8 @@ cross_tests!( }, ); +// Test where node 4 sends out the correct quorum proposal and additionally spams the network with an extra 99 malformed proposals #[cfg(async_executor_impl = "async-std")] -/// Test where node 4 sends out the correct quorum proposal and additionally spams the network with an extra 99 malformed proposals cross_tests!( TestName: multiple_bad_proposals, Impls: [MemoryImpl],