Skip to content

feat(code/test): Middleware for testing #948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions code/crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,6 @@ pub struct TestConfig {
pub max_retain_blocks: usize,
#[serde(default)]
pub vote_extensions: VoteExtensionsConfig,
#[serde(default)]
pub is_byzantine_proposer: bool,
}

impl Default for TestConfig {
Expand All @@ -663,7 +661,6 @@ impl Default for TestConfig {
exec_time_per_tx: Duration::from_millis(1),
max_retain_blocks: 1000,
vote_extensions: VoteExtensionsConfig::default(),
is_byzantine_proposer: false,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions code/crates/core-consensus/src/handle/proposed_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ where
// b) In any mode if the proposed value was provided by Sync, where we do net get a Proposal message but only the full value and the certificate
if state.params.value_payload.parts_only() || origin == ValueOrigin::Sync {
let proposal = Ctx::new_proposal(
&state.ctx,
proposed_value.height,
proposed_value.round,
proposed_value.value.clone(),
Expand Down
2 changes: 1 addition & 1 deletion code/crates/core-driver/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ where
let info = Info::new(input_round, &self.address, proposer.address());

// Apply the input to the round state machine
let transition = round_state.apply(&info, input);
let transition = round_state.apply(&self.ctx, &info, input);

// Update state
self.round_state = transition.next_state;
Expand Down
9 changes: 6 additions & 3 deletions code/crates/core-state-machine/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,36 @@ where
impl<Ctx: Context> Output<Ctx> {
/// Build a `Proposal` output.
pub fn proposal(
ctx: &Ctx,
height: Ctx::Height,
round: Round,
value: Ctx::Value,
pol_round: Round,
address: Ctx::Address,
) -> Self {
Output::Proposal(Ctx::new_proposal(height, round, value, pol_round, address))
Output::Proposal(ctx.new_proposal(height, round, value, pol_round, address))
}

/// Build a `Vote` output for a prevote.
pub fn prevote(
ctx: &Ctx,
height: Ctx::Height,
round: Round,
value_id: NilOrVal<ValueId<Ctx>>,
address: Ctx::Address,
) -> Self {
Output::Vote(Ctx::new_prevote(height, round, value_id, address))
Output::Vote(ctx.new_prevote(height, round, value_id, address))
}

/// Build a `Vote` output for a precommit.
pub fn precommit(
ctx: &Ctx,
height: Ctx::Height,
round: Round,
value_id: NilOrVal<ValueId<Ctx>>,
address: Ctx::Address,
) -> Self {
Output::Vote(Ctx::new_precommit(height, round, value_id, address))
Output::Vote(ctx.new_precommit(height, round, value_id, address))
}

/// Build a `ScheduleTimeout` output.
Expand Down
4 changes: 2 additions & 2 deletions code/crates/core-state-machine/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ where
}

/// Apply the given input to the current state, triggering a transition.
pub fn apply(self, data: &Info<Ctx>, input: Input<Ctx>) -> Transition<Ctx> {
crate::state_machine::apply(self, data, input)
pub fn apply(self, ctx: &Ctx, data: &Info<Ctx>, input: Input<Ctx>) -> Transition<Ctx> {
crate::state_machine::apply(ctx, self, data, input)
}

/// Return the traces logged during execution.
Expand Down
54 changes: 36 additions & 18 deletions code/crates/core-state-machine/src/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ where
/// Valid transitions result in at least a change to the state and/or an output.
///
/// Commented numbers refer to line numbers in the spec paper.
pub fn apply<Ctx>(mut state: State<Ctx>, info: &Info<Ctx>, input: Input<Ctx>) -> Transition<Ctx>
pub fn apply<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
info: &Info<Ctx>,
input: Input<Ctx>,
) -> Transition<Ctx>
where
Ctx: Context,
{
Expand All @@ -87,7 +92,7 @@ where
debug_trace!(state, Line::L11Proposer);

// We are the proposer
propose_valid_or_get_value(state, info.address)
propose_valid_or_get_value(ctx, state, info.address)
}

// L11/L20
Expand All @@ -109,7 +114,7 @@ where
(Step::Propose, Input::ProposeValue(value)) if this_round => {
debug_assert!(info.is_proposer());

propose(state, value, info.address)
propose(ctx, state, value, info.address)
}

// L22 with valid proposal
Expand All @@ -118,18 +123,20 @@ where
{
debug_trace!(state, Line::L22);

prevote(state, info.address, &proposal)
prevote(ctx, state, info.address, &proposal)
}

// L22 with invalid proposal
(Step::Propose, Input::InvalidProposal) if this_round => prevote_nil(state, info.address),
(Step::Propose, Input::InvalidProposal) if this_round => {
prevote_nil(ctx, state, info.address)
}

// L28 with valid proposal
(Step::Propose, Input::ProposalAndPolkaPrevious(proposal))
if this_round && is_valid_pol_round(&state, proposal.pol_round()) =>
{
debug_trace!(state, Line::L28ValidProposal);
prevote_previous(state, info.address, &proposal)
prevote_previous(ctx, state, info.address, &proposal)
}

// L28 with invalid proposal
Expand All @@ -139,23 +146,23 @@ where
debug_trace!(state, Line::L28InvalidProposal);
debug_trace!(state, Line::L32InvalidValue);

prevote_nil(state, info.address)
prevote_nil(ctx, state, info.address)
}

// L57
// We are the proposer.
(Step::Propose, Input::TimeoutPropose) if this_round && info.is_proposer() => {
debug_trace!(state, Line::L59Proposer);

prevote_nil(state, info.address)
prevote_nil(ctx, state, info.address)
}

// L57
// We are not the proposer.
(Step::Propose, Input::TimeoutPropose) if this_round => {
debug_trace!(state, Line::L59NonProposer);

prevote_nil(state, info.address)
prevote_nil(ctx, state, info.address)
}

//
Expand All @@ -174,22 +181,22 @@ where
(Step::Prevote, Input::PolkaNil) if this_round => {
debug_trace!(state, Line::L45);

precommit_nil(state, info.address)
precommit_nil(ctx, state, info.address)
}

// L36/L37
// NOTE: Only executed the first time, as the votekeeper will only emit this threshold once.
(Step::Prevote, Input::ProposalAndPolkaCurrent(proposal)) if this_round => {
debug_trace!(state, Line::L36ValidProposal);

precommit(state, info.address, proposal)
precommit(ctx, state, info.address, proposal)
}

// L61
(Step::Prevote, Input::TimeoutPrevote) if this_round => {
debug_trace!(state, Line::L61);

precommit_nil(state, info.address)
precommit_nil(ctx, state, info.address)
}

//
Expand Down Expand Up @@ -251,6 +258,7 @@ where
///
/// Ref: L13-L16, L19
pub fn propose_valid_or_get_value<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
address: &Ctx::Address,
) -> Transition<Ctx>
Expand All @@ -264,6 +272,7 @@ where
// L16
let pol_round = round_value.round;
let proposal = Output::proposal(
ctx,
state.height,
state.round,
round_value.value.clone(),
Expand Down Expand Up @@ -294,6 +303,7 @@ where
///
/// Ref: L13, L17-18
pub fn propose<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
value: Ctx::Value,
address: &Ctx::Address,
Expand All @@ -302,6 +312,7 @@ where
Ctx: Context,
{
let proposal = Output::proposal(
ctx,
state.height,
state.round,
value,
Expand All @@ -322,6 +333,7 @@ where
///
/// Ref: L22 with valid proposal
pub fn prevote<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
address: &Ctx::Address,
proposal: &Ctx::Proposal,
Expand Down Expand Up @@ -350,7 +362,7 @@ where
}
};

let output = Output::prevote(state.height, state.round, value, address.clone());
let output = Output::prevote(ctx, state.height, state.round, value, address.clone());
Transition::to(state.with_step(Step::Prevote)).with_output(output)
}

Expand All @@ -359,6 +371,7 @@ where
///
/// Ref: L28
pub fn prevote_previous<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
address: &Ctx::Address,
proposal: &Ctx::Proposal,
Expand Down Expand Up @@ -394,18 +407,19 @@ where
}
};

let output = Output::prevote(state.height, state.round, value, address.clone());
let output = Output::Vote(ctx.new_prevote(state.height, state.round, value, address.clone()));
Transition::to(state.with_step(Step::Prevote)).with_output(output)
}

/// Received a complete proposal for an empty or invalid value, or timed out; prevote nil.
///
/// Ref: L22/L25, L28/L31, L57
pub fn prevote_nil<Ctx>(state: State<Ctx>, address: &Ctx::Address) -> Transition<Ctx>
pub fn prevote_nil<Ctx>(ctx: &Ctx, state: State<Ctx>, address: &Ctx::Address) -> Transition<Ctx>
where
Ctx: Context,
{
let output = Output::prevote(state.height, state.round, NilOrVal::Nil, address.clone());
let output =
Output::Vote(ctx.new_prevote(state.height, state.round, NilOrVal::Nil, address.clone()));

Transition::to(state.with_step(Step::Prevote)).with_output(output)
}
Expand All @@ -421,6 +435,7 @@ where
/// NOTE: Only one of this and set_valid_value should be called once in a round
/// How do we enforce this?
pub fn precommit<Ctx>(
ctx: &Ctx,
state: State<Ctx>,
address: &Ctx::Address,
proposal: Ctx::Proposal,
Expand All @@ -434,6 +449,7 @@ where

let value = proposal.value();
let output = Output::precommit(
ctx,
state.height,
state.round,
NilOrVal::Val(value.id()),
Expand All @@ -451,11 +467,13 @@ where
/// Received a polka for nil or timed out of prevote; precommit nil.
///
/// Ref: L44, L61
pub fn precommit_nil<Ctx>(state: State<Ctx>, address: &Ctx::Address) -> Transition<Ctx>
pub fn precommit_nil<Ctx>(ctx: &Ctx, state: State<Ctx>, address: &Ctx::Address) -> Transition<Ctx>
where
Ctx: Context,
{
let output = Output::precommit(state.height, state.round, NilOrVal::Nil, address.clone());
let output =
Output::Vote(ctx.new_precommit(state.height, state.round, NilOrVal::Nil, address.clone()));

Transition::to(state.with_step(Step::Precommit)).with_output(output)
}

Expand Down
3 changes: 3 additions & 0 deletions code/crates/core-types/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ where

/// Build a new proposal for the given value at the given height, round and POL round.
fn new_proposal(
&self,
height: Self::Height,
round: Round,
value: Self::Value,
Expand All @@ -60,6 +61,7 @@ where
/// Build a new prevote vote by the validator with the given address,
/// for the value identified by the given value id, at the given round.
fn new_prevote(
&self,
height: Self::Height,
round: Round,
value_id: NilOrVal<ValueId<Self>>,
Expand All @@ -69,6 +71,7 @@ where
/// Build a new precommit vote by the validator with the given address,
/// for the value identified by the given value id, at the given round.
fn new_precommit(
&self,
height: Self::Height,
round: Round,
value_id: NilOrVal<ValueId<Self>>,
Expand Down
3 changes: 3 additions & 0 deletions code/crates/starknet/p2p-types/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl Context for MockContext {
}

fn new_proposal(
&self,
height: Height,
round: Round,
value_id: Hash,
Expand All @@ -61,6 +62,7 @@ impl Context for MockContext {
}

fn new_prevote(
&self,
height: Height,
round: Round,
value_id: NilOrVal<Hash>,
Expand All @@ -70,6 +72,7 @@ impl Context for MockContext {
}

fn new_precommit(
&self,
height: Height,
round: Round,
value_id: NilOrVal<Hash>,
Expand Down
5 changes: 1 addition & 4 deletions code/crates/test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ malachitebft-core-types = { workspace = true }
malachitebft-config = { workspace = true }
malachitebft-core-consensus = { workspace = true }
malachitebft-proto = { workspace = true }
malachitebft-signing-ed25519 = { workspace = true, features = [
"rand",
"serde",
] }
malachitebft-signing-ed25519 = { workspace = true, features = ["rand", "serde"] }
malachitebft-sync = { workspace = true }

async-trait = { workspace = true }
Expand Down
Loading