Skip to content

Commit dbcd782

Browse files
committed
Merge branch 'main' into fix-byzzfuzz-network-partitions
2 parents 2fac96f + 9b5b2e0 commit dbcd782

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

simulator/src/main/java/byzzbench/simulator/scheduler/BaseScheduler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public List<ClientRequestEvent> getQueuedClientRequestEvents(Scenario scenario)
118118
* @param messageEvents The list of queued message events
119119
* @return The next message event
120120
*/
121-
public Event getNextMessageEvent(List<Event> messageEvents) {
121+
public <T extends Event> T getNextMessageEvent(List<T> messageEvents) {
122122
switch (config.getScheduler().getExecutionMode()) {
123123
case SYNC -> {
124124
return messageEvents.stream().min(Comparator.comparing(Event::getEventId)).orElseThrow();

simulator/src/main/java/byzzbench/simulator/scheduler/RandomScheduler.java

+16-10
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import java.util.List;
1616
import java.util.Optional;
1717
import java.util.Random;
18-
import java.util.stream.Collectors;
18+
import java.util.SortedSet;
1919

2020
/**
2121
* A scheduler that randomly selects events to deliver, drop, mutate or timeout.
@@ -25,11 +25,14 @@
2525
public class RandomScheduler extends BaseScheduler {
2626
private final Random random = new Random();
2727

28-
2928
public RandomScheduler(ByzzBenchConfig config, MessageMutatorService messageMutatorService) {
3029
super(config, messageMutatorService);
3130
}
3231

32+
public <T> T getRandomElement(List<T> list) {
33+
return list.get(random.nextInt(list.size()));
34+
}
35+
3336
@Override
3437
public String getId() {
3538
return "Random";
@@ -52,21 +55,24 @@ public synchronized Optional<EventDecision> scheduleNext(Scenario scenario) thro
5255
}
5356

5457
List<TimeoutEvent> timeoutEvents = this.getQueuedTimeoutEvents(scenario);
55-
List<Event> clientRequestEvents = availableEvents.stream().filter(ClientRequestEvent.class::isInstance).collect(Collectors.toList());
56-
List<Event> messageEvents = availableEvents.stream().filter(MessageEvent.class::isInstance).collect(Collectors.toList());
58+
List<Event> clientRequestEvents = availableEvents.stream().filter(ClientRequestEvent.class::isInstance).toList();
59+
List<MessageEvent> messageEvents = availableEvents.stream().filter(MessageEvent.class::isInstance).map(MessageEvent.class::cast).toList();
60+
61+
SortedSet<String> faultyReplicaIds = scenario.getFaultyReplicaIds();
62+
List<MessageEvent> mutateableMessageEvents = messageEvents.stream().filter(msg -> faultyReplicaIds.contains(msg.getSenderId())).toList();
5763

5864
int timeoutWeight = timeoutEvents.size() * this.deliverTimeoutWeight();
5965
int deliverMessageWeight = messageEvents.size() * this.deliverMessageWeight();
6066
int deliverClientRequestWeight = clientRequestEvents.size() * this.deliverClientRequestWeight();
6167
int dropMessageWeight = (messageEvents.size() * this.dropMessageWeight(scenario));
62-
int mutateMessageWeight = (messageEvents.size() * this.mutateMessageWeight(scenario));
68+
int mutateMessageWeight = (mutateableMessageEvents.size() * this.mutateMessageWeight(scenario));
6369
int dieRoll = random.nextInt(timeoutWeight + deliverMessageWeight
6470
+ deliverClientRequestWeight + dropMessageWeight + mutateMessageWeight);
6571

6672
// check if we should trigger a timeout
6773
dieRoll -= timeoutWeight;
6874
if (dieRoll < 0) {
69-
Event timeout = timeoutEvents.get(random.nextInt(timeoutEvents.size()));
75+
Event timeout = getRandomElement(timeoutEvents);
7076
scenario.getTransport().deliverEvent(timeout.getEventId());
7177
EventDecision decision = new EventDecision(EventDecision.DecisionType.DELIVERED, timeout.getEventId());
7278
return Optional.of(decision);
@@ -84,7 +90,7 @@ public synchronized Optional<EventDecision> scheduleNext(Scenario scenario) thro
8490
// check if we should target delivering a request from a client to a replica
8591
dieRoll -= deliverClientRequestWeight;
8692
if (dieRoll < 0) {
87-
Event request = clientRequestEvents.get(random.nextInt(clientRequestEvents.size()));
93+
Event request = getRandomElement(clientRequestEvents);
8894
scenario.getTransport().deliverEvent(request.getEventId());
8995
EventDecision decision = new EventDecision(EventDecision.DecisionType.DELIVERED, request.getEventId());
9096
return Optional.of(decision);
@@ -93,7 +99,7 @@ public synchronized Optional<EventDecision> scheduleNext(Scenario scenario) thro
9399
// check if we should drop a message sent between nodes
94100
dieRoll -= dropMessageWeight;
95101
if (dieRoll < 0) {
96-
Event message = messageEvents.get(random.nextInt(messageEvents.size()));
102+
Event message = getRandomElement(messageEvents);
97103
scenario.getTransport().dropEvent(message.getEventId());
98104
EventDecision decision = new EventDecision(EventDecision.DecisionType.DROPPED, message.getEventId());
99105
return Optional.of(decision);
@@ -102,7 +108,7 @@ public synchronized Optional<EventDecision> scheduleNext(Scenario scenario) thro
102108
// check if we should mutate-and-deliver a message sent between nodes
103109
dieRoll -= mutateMessageWeight;
104110
if (dieRoll < 0) {
105-
Event message = messageEvents.get(random.nextInt(messageEvents.size()));
111+
Event message = getRandomElement(mutateableMessageEvents);
106112
List<MessageMutationFault> mutators = this.getMessageMutatorService().getMutatorsForEvent(message);
107113

108114
if (mutators.isEmpty()) {
@@ -112,7 +118,7 @@ public synchronized Optional<EventDecision> scheduleNext(Scenario scenario) thro
112118
}
113119
scenario.getTransport().applyMutation(
114120
message.getEventId(),
115-
mutators.get(random.nextInt(mutators.size())));
121+
getRandomElement(mutators));
116122
scenario.getTransport().deliverEvent(message.getEventId());
117123

118124
EventDecision decision = new EventDecision(EventDecision.DecisionType.MUTATED_AND_DELIVERED, message.getEventId());

0 commit comments

Comments
 (0)