Skip to content
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

Liveness improvements #148

Merged
merged 10 commits into from
Mar 6, 2025
6 changes: 4 additions & 2 deletions simulator/src/main/java/byzzbench/simulator/BaseScenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import byzzbench.simulator.config.ByzzBenchConfig;
import byzzbench.simulator.faults.Fault;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.faults.factories.ByzzFuzzScenarioFaultFactory;
import byzzbench.simulator.faults.faults.GlobalStabilizationTimeFault;
import byzzbench.simulator.faults.faults.HealNodeNetworkFault;
import byzzbench.simulator.faults.faults.IsolateProcessNetworkFault;
import byzzbench.simulator.schedule.Schedule;
Expand Down Expand Up @@ -179,6 +180,7 @@ public final void setupScenario() {
//this.getClients().values().forEach(Client::initialize);
this.getNodes().values().forEach(Node::initialize);
this.scheduler.initializeScenario(this);
this.transport.addFault(new GlobalStabilizationTimeFault(), false);
}

public final void loadParameters(JsonNode parameters) {
Expand All @@ -196,7 +198,7 @@ public final void loadParameters(JsonNode parameters) {
if (parameters.has("faults")) {
System.out.println("Faults: " + parameters.get("faults").toPrettyString());
ByzzFuzzScenarioFaultFactory faultFactory = new ByzzFuzzScenarioFaultFactory();
List<Fault> faults = faultFactory.generateFaults(new FaultContext(this));
List<Fault> faults = faultFactory.generateFaults(new ScenarioContext(this));
faults.forEach(fault -> this.transport.addFault(fault, true));
}

Expand Down
4 changes: 2 additions & 2 deletions simulator/src/main/java/byzzbench/simulator/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public interface Node extends Serializable {
* @param message the message payload
* @throws Exception if an error occurs while handling the message
*/
void handleMessage(String sender, MessagePayload message) throws Exception;
void handleMessage(String sender, MessagePayload message);

/**
* Get the current time from the timekeeper.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ public String getName() {
}

@Override
public boolean test(FaultContext state) {
public boolean test(ScenarioContext state) {
return predicate.test(state);
}

@Override
public void accept(FaultContext state) {
public void accept(ScenarioContext state) {
behavior.accept(state);
}
}
8 changes: 4 additions & 4 deletions simulator/src/main/java/byzzbench/simulator/faults/Fault.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* which checks if the fault can be applied to a message, and a {@link Consumer}, which
* applies the faulty behavior.
*/
public interface Fault extends Predicate<FaultContext>, FaultBehavior, Serializable {
public interface Fault extends Predicate<ScenarioContext>, FaultBehavior, Serializable {
/**
* Gets the unique id of the fault.
*
Expand All @@ -35,23 +35,23 @@ public interface Fault extends Predicate<FaultContext>, FaultBehavior, Serializa
* @return True if the fault can be applied, false otherwise
*/
@Override
boolean test(FaultContext state);
boolean test(ScenarioContext state);

/**
* Applies a fault to the state of the system
*
* @param state the state of the system
*/
@Override
void accept(FaultContext state);
void accept(ScenarioContext state);

/**
* Checks if the fault can be applied to the given state and applies it if it can
*
* @param state the state of the system
* @return True if the fault was applied, false otherwise
*/
default boolean testAndAccept(FaultContext state) {
default boolean testAndAccept(ScenarioContext state) {
if (test(state)) {
accept(state);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import java.io.Serializable;
import java.util.function.Consumer;

public interface FaultBehavior extends Consumer<FaultContext>, Serializable {
@NonNull String getId();
@NonNull String getName();
public interface FaultBehavior extends Consumer<ScenarioContext>, Serializable {
@NonNull
String getId();

@NonNull
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ default String getId() {
return this.getClass().getSimpleName();
}

List<Fault> generateFaults(FaultContext input);
List<Fault> generateFaults(ScenarioContext input);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.io.Serializable;
import java.util.function.Predicate;

public interface FaultPredicate extends Predicate<FaultContext>, Serializable {
public interface FaultPredicate extends Predicate<ScenarioContext>, Serializable {
String getId();

String getName();
Expand All @@ -29,7 +29,7 @@ public String getName() {
}

@Override
public boolean test(FaultContext ctx) {
public boolean test(ScenarioContext ctx) {
return FaultPredicate.this.test(ctx) && other.test(ctx);
}
};
Expand All @@ -54,7 +54,7 @@ public String getName() {
}

@Override
public boolean test(FaultContext ctx) {
public boolean test(ScenarioContext ctx) {
return FaultPredicate.this.test(ctx) || other.test(ctx);
}
};
Expand All @@ -79,7 +79,7 @@ public String getName() {
}

@Override
public boolean test(FaultContext ctx) {
public boolean test(ScenarioContext ctx) {
return !FaultPredicate.this.test(ctx);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* This is useful for example for fault injection, where the fault context can be used to determine
* if a fault should be injected or not and to offer a mechanism to apply its behavior.
*/
public class FaultContext {
public class ScenarioContext {
/**
* The scenario that is being processed.
*/
Expand All @@ -31,7 +31,7 @@ public class FaultContext {
* @param scenario The scenario that is being processed.
* @param event The event that is being processed.
*/
public FaultContext(@NonNull Scenario scenario, Event event) {
public ScenarioContext(@NonNull Scenario scenario, Event event) {
this.scenario = scenario;
this.eventOptional = event;
}
Expand All @@ -41,7 +41,7 @@ public FaultContext(@NonNull Scenario scenario, Event event) {
*
* @param scenario The scenario that is being processed.
*/
public FaultContext(@NonNull Scenario scenario) {
public ScenarioContext(@NonNull Scenario scenario) {
this(scenario, null);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package byzzbench.simulator.faults.behaviors;

import byzzbench.simulator.faults.FaultBehavior;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.transport.Event;
import byzzbench.simulator.transport.MessageEvent;
import byzzbench.simulator.transport.Router;
Expand Down Expand Up @@ -78,7 +78,7 @@ public String getName() {
}

@Override
public void accept(FaultContext context) {
public void accept(ScenarioContext context) {
Optional<Event> event = context.getEvent();

if (event.isEmpty()) {
Expand All @@ -102,7 +102,7 @@ public void accept(FaultContext context) {
}

// otherwise, drop the message: the sender and recipient are in different partitions
if(e.getStatus() == Event.Status.QUEUED) {
if (e.getStatus() == Event.Status.QUEUED) {
context.getScenario().getTransport().dropEvent(e.getEventId());
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package byzzbench.simulator.faults.behaviors;

import byzzbench.simulator.faults.FaultBehavior;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.transport.Router;

import java.util.Arrays;
Expand Down Expand Up @@ -62,7 +62,7 @@ public String getName() {
}

@Override
public void accept(FaultContext context) {
public void accept(ScenarioContext context) {
Router router = context.getScenario().getTransport().getRouter();
for (String[] partition : partitions) {
router.isolateNodes(partition);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package byzzbench.simulator.faults.behaviors;

import byzzbench.simulator.faults.FaultBehavior;
import byzzbench.simulator.faults.ScenarioContext;

public class GlobalStabilizationTimeBehavior implements FaultBehavior {
@Override
public String getId() {
return "GST";
}

@Override
public String getName() {
return "Global Stabilization Time";
}

@Override
public void accept(ScenarioContext ctx) {
ctx.getScenario().getTransport().globalStabilizationTime();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package byzzbench.simulator.faults.behaviors;

import byzzbench.simulator.faults.FaultBehavior;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.transport.Router;
import lombok.RequiredArgsConstructor;

Expand All @@ -20,7 +20,7 @@ public String getName() {
}

@Override
public void accept(FaultContext context) {
public void accept(ScenarioContext context) {
Router router = context.getScenario().getTransport().getRouter();
router.isolateNode(nodeId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import byzzbench.simulator.ApplicationContextUtils;
import byzzbench.simulator.faults.FaultBehavior;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.faults.faults.MessageMutationFault;
import byzzbench.simulator.service.MessageMutatorService;
import byzzbench.simulator.transport.Event;
Expand Down Expand Up @@ -37,7 +37,7 @@ public String getName() {
}

@Override
public void accept(FaultContext context) {
public void accept(ScenarioContext context) {
Optional<Event> event = context.getEvent();

if (event.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import byzzbench.simulator.Scenario;
import byzzbench.simulator.faults.Fault;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.FaultFactory;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.faults.faults.ByzzFuzzNetworkFault;
import byzzbench.simulator.faults.faults.ByzzFuzzProcessFault;
import byzzbench.simulator.scheduler.ByzzFuzzScheduler;
Expand All @@ -25,7 +25,7 @@ public class ByzzFuzzScenarioFaultFactory implements FaultFactory {
private final Random rand = new Random();

@Override
public List<Fault> generateFaults(FaultContext input) {
public List<Fault> generateFaults(ScenarioContext input) {
List<Fault> faults = new ArrayList<>();
Scenario scenario = input.getScenario();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import byzzbench.simulator.Replica;
import byzzbench.simulator.faults.Fault;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.FaultFactory;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.faults.faults.HealNetworkFault;
import byzzbench.simulator.faults.faults.HealNodeNetworkFault;
import byzzbench.simulator.faults.faults.IsolateProcessNetworkFault;
Expand All @@ -19,7 +19,7 @@
@Component
public class IsolateProcessNetworkFaultFactory implements FaultFactory {
@Override
public List<Fault> generateFaults(FaultContext input) {
public List<Fault> generateFaults(ScenarioContext input) {
List<Fault> networkFaults = new ArrayList<>();

// create a IsolateProcessNetworkFault for each replica in the network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import byzzbench.simulator.faults.BaseFault;
import byzzbench.simulator.faults.behaviors.ByzzFuzzDropMessageBehavior;
import byzzbench.simulator.faults.predicates.ANDPredicate;
import byzzbench.simulator.faults.predicates.IsBeforeGST;
import byzzbench.simulator.faults.predicates.MessageRoundPredicate;

import java.util.Set;
Expand All @@ -22,7 +24,7 @@ public class ByzzFuzzNetworkFault extends BaseFault {
public ByzzFuzzNetworkFault(Set<String> partition, int round) {
super(
"byzzfuzznetworkfault-%d-%s".formatted(round, String.join("-", partition)),
new MessageRoundPredicate(round),
new ANDPredicate(new IsBeforeGST(), new MessageRoundPredicate(round)),
new ByzzFuzzDropMessageBehavior(partition)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package byzzbench.simulator.faults.faults;

import byzzbench.simulator.faults.BaseFault;
import byzzbench.simulator.faults.behaviors.GlobalStabilizationTimeBehavior;
import byzzbench.simulator.faults.predicates.IsBeforeGST;

/**
* Triggers the Global Stabilization Time (GST) if not already triggered.
*/
public class GlobalStabilizationTimeFault extends BaseFault {
public GlobalStabilizationTimeFault() {
super("GST", new IsBeforeGST(), new GlobalStabilizationTimeBehavior());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package byzzbench.simulator.faults.faults;

import byzzbench.simulator.faults.Fault;
import byzzbench.simulator.faults.FaultContext;
import byzzbench.simulator.faults.ScenarioContext;
import byzzbench.simulator.transport.Router;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -29,7 +29,7 @@ public String getName() {
* @return True if the network is not already healed, false otherwise
*/
@Override
public final boolean test(FaultContext ctx) {
public final boolean test(ScenarioContext ctx) {
Router router = ctx.getScenario().getTransport().getRouter();
return router.hasActivePartitions();
}
Expand All @@ -40,7 +40,7 @@ public final boolean test(FaultContext ctx) {
* @param state the input argument
*/
@Override
public void accept(FaultContext state) {
public void accept(ScenarioContext state) {
Router router = state.getScenario().getTransport().getRouter();
router.resetPartitions();
}
Expand Down
Loading