23
23
@ Log
24
24
@ Getter
25
25
public class FastByzantineReplica extends LeaderBasedProtocolReplica {
26
+ // The number of replicas in the system with each role.
27
+ private final int p , a , l , f ;
28
+ // Timeout until the proposer replica starts suspecting the leader for the lack of progress.
29
+ private final long messageTimeoutDuration ;
30
+ @ JsonIgnore
31
+ private final Transport transport ;
32
+ // Current client ID that the system is communicating with.
33
+ private final String clientId ;
34
+ /**
35
+ * The log of received messages for the replica.
36
+ */
37
+ @ JsonIgnore
38
+ private final MessageLog messageLog ;
26
39
// In the "Fast Byzantine Consensus" protocol, a replica can have one or more roles.
27
40
// The possible roles are : PROPOSER, ACCEPTOR, LEARNER.
28
41
// The required number of replicas with each role is:
29
42
// p ( proposers ) = 3 * f + 1, a ( acceptors ) = 5 * f + 1, l ( learners ) = 3 * f + 1.
30
43
private List <Role > roles = new ArrayList <>();
31
-
32
- // The number of replicas in the system with each role.
33
- private final int p , a , l , f ;
34
44
// The message round number.
35
45
private long viewNumber ;
36
46
private long proposalNumber ;
37
47
// The value that the leader replica is proposing - changes each round, depending on the client request.
38
48
private byte [] proposedValue ;
39
49
// The progress certificate for the current view.
40
50
private ProgressCertificate pc ;
41
- // Timeout until the proposer replica starts suspecting the leader for the lack of progress.
42
- private final long messageTimeoutDuration ;
43
51
// Current leader.
44
52
@ Setter
45
53
private String leaderId ;
46
54
@ Setter
47
55
private boolean isCurrentlyLeader ;
48
-
49
56
// The set of node IDs in the system for each role.
50
57
private SortedSet <String > acceptorNodeIds = new TreeSet <>();
51
58
private SortedSet <String > learnerNodeIds = new TreeSet <>();
52
- private SortedSet <String > proposerNodeIds = new TreeSet <>();;
53
- private SortedSet <String > nodeIds = new TreeSet <>();;
54
-
55
- @ JsonIgnore
56
- private final Transport transport ;
57
-
58
- // Current client ID that the system is communicating with.
59
- private String clientId ;
60
-
59
+ private SortedSet <String > proposerNodeIds = new TreeSet <>();
60
+ private SortedSet <String > nodeIds = new TreeSet <>();
61
61
private boolean isSatisfied ;
62
62
// Keep track of the timeouts set by the replica.
63
63
private long learnerTimeoutId = -1 ;
@@ -67,11 +67,6 @@ public class FastByzantineReplica extends LeaderBasedProtocolReplica {
67
67
@ Setter
68
68
private boolean isRecovered ;
69
69
private int forwards ;
70
- /**
71
- * The log of received messages for the replica.
72
- */
73
- @ JsonIgnore
74
- private MessageLog messageLog ;
75
70
private boolean committed ;
76
71
private byte [] operation ;
77
72
private long viewChangeRequests = 0 ;
@@ -188,15 +183,16 @@ private void leaderOnStart(ProposeMessage proposeMessage) {
188
183
private void proposerOnStart () {
189
184
int learnedThreshold = (int ) Math .ceil ((l + f + 1 ) / 2.0 );
190
185
191
- this .proposerTimeoutId = this .setTimeout (
192
- "proposer-timeout" ,
193
- () -> {
194
- if (!messageLog .proposerHasLearned (learnedThreshold )) {
195
- log .warning ("Leader suspected by proposer " + getId ());
196
- broadcastMessageIncludingSelf (new SuspectMessage (getId (), this .leaderId , this .viewNumber ));
197
- }
198
- }, Duration .ofMillis (messageTimeoutDuration ));
186
+ this .proposerTimeoutId = this .setTimeout (
187
+ "proposer-timeout" ,
188
+ () -> {
189
+ if (!messageLog .proposerHasLearned (learnedThreshold )) {
190
+ log .warning ("Leader suspected by proposer " + getId ());
191
+ broadcastMessageIncludingSelf (new SuspectMessage (getId (), this .leaderId , this .viewNumber ));
192
+ }
193
+ }, Duration .ofMillis (messageTimeoutDuration ));
199
194
}
195
+
200
196
/**
201
197
* Learner replica starts by awaiting to learn a value.
202
198
* If it has not learned any value after waiting, send a PULL message to all other LEARNER replicas.
@@ -218,10 +214,10 @@ private void learnerOnStart() {
218
214
219
215
/**
220
216
* Handle a client request received by the replica.
217
+ *
221
218
* @param clientId the ID of the client
222
219
* @param request the request payload
223
220
*/
224
- @ Override
225
221
public void handleClientRequest (String clientId , Serializable request ) throws UnsupportedOperationException {
226
222
// If the client request is not send to the leader, forward it to the leader.
227
223
if (!isLeader ()) {
@@ -302,7 +298,8 @@ private void handleForwardClientRequest(String sender, ForwardClientRequest forw
302
298
303
299
/**
304
300
* Handle a PROPOSE message send by a replica with Proposer role, who is the leader, received by all Acceptor replicas.
305
- * @param sender : the nodeId of the sender (the current leader)
301
+ *
302
+ * @param sender : the nodeId of the sender (the current leader)
306
303
* @param proposeMessage : the PROPOSE message with the proposed value and round number
307
304
*/
308
305
private void handleProposeMessage (String sender , ProposeMessage proposeMessage ) {
@@ -320,7 +317,8 @@ private void handleProposeMessage(String sender, ProposeMessage proposeMessage)
320
317
321
318
/**
322
319
* Handle an ACCEPT message sent by an Acceptor replica, received by a Learner replica.
323
- * @param sender : the nodeId of the sender (an Acceptor replica)
320
+ *
321
+ * @param sender : the nodeId of the sender (an Acceptor replica)
324
322
* @param acceptMessage : the ACCEPT message with the value and proposal number
325
323
*/
326
324
private void handleAcceptMessage (String sender , AcceptMessage acceptMessage ) {
@@ -354,7 +352,8 @@ private void handleAcceptMessage(String sender, AcceptMessage acceptMessage) {
354
352
355
353
/**
356
354
* Handle a LEARN message sent by a Proposer replica, received by a Proposer replica.
357
- * @param sender : the nodeId of the sender (a Learner replica)
355
+ *
356
+ * @param sender : the nodeId of the sender (a Learner replica)
358
357
* @param learnMessage : the LEARN message with the value and proposal number
359
358
*/
360
359
private void handleLearnMessageProposer (String sender , LearnMessage learnMessage ) {
@@ -390,7 +389,8 @@ private void handleLearnMessageProposer(String sender, LearnMessage learnMessage
390
389
391
390
/**
392
391
* Handle a LEARN message sent by a Learner replica, received by a Learner replica.
393
- * @param sender : the nodeId of the sender (a Learner replica)
392
+ *
393
+ * @param sender : the nodeId of the sender (a Learner replica)
394
394
* @param learnMessage : the LEARN message with the value and proposal number
395
395
*/
396
396
private void handleLearnMessageLearner (String sender , LearnMessage learnMessage ) {
@@ -428,7 +428,8 @@ private void handleLearnMessageLearner(String sender, LearnMessage learnMessage)
428
428
429
429
/**
430
430
* Handle a SATISFIED message received by a Proposer replica.
431
- * @param sender : the nodeId of the sender (a Proposer replica)
431
+ *
432
+ * @param sender : the nodeId of the sender (a Proposer replica)
432
433
* @param satisfiedMessage : the SATISFIED message with the value and proposal number
433
434
*/
434
435
private void handleSatisfiedMessage (String sender , SatisfiedMessage satisfiedMessage ) {
@@ -466,7 +467,8 @@ private void handleSatisfiedMessage(String sender, SatisfiedMessage satisfiedMes
466
467
/**
467
468
* Handle a QUERY message received by an Acceptor replica.
468
469
* This message is sent after a new leader has been elected.
469
- * @param sender : the nodeId of the sender (the new leader)
470
+ *
471
+ * @param sender : the nodeId of the sender (the new leader)
470
472
* @param queryMessage : the QUERY message with the view number and progress certificate
471
473
*/
472
474
private void handleQueryMessage (String sender , QueryMessage queryMessage ) {
@@ -494,7 +496,8 @@ private void handleQueryMessage(String sender, QueryMessage queryMessage) {
494
496
495
497
/**
496
498
* Handle a PULL message received by a Learner replica. Should send the learned value, if any.
497
- * @param sender : the nodeId of the sender (a Learner replica)
499
+ *
500
+ * @param sender : the nodeId of the sender (a Learner replica)
498
501
* @param pullMessage : the PULL message
499
502
*/
500
503
private void handlePullMessage (String sender , PullMessage pullMessage ) {
@@ -515,7 +518,8 @@ private void handlePullMessage(String sender, PullMessage pullMessage) {
515
518
516
519
/**
517
520
* Handle a SUSPECT message received by a replica.
518
- * @param sender : the nodeId of the sender (a replica that suspects the leader)
521
+ *
522
+ * @param sender : the nodeId of the sender (a replica that suspects the leader)
519
523
* @param suspectMessage : the SUSPECT message with the nodeId of the suspected leader
520
524
*/
521
525
private void handleSuspectMessage (String sender , SuspectMessage suspectMessage ) {
@@ -535,7 +539,8 @@ private void handleSuspectMessage(String sender, SuspectMessage suspectMessage)
535
539
536
540
/**
537
541
* Handle a REPLY message received by the leader replica.
538
- * @param sender : the nodeId of the sender (an Acceptor replica which was queried)
542
+ *
543
+ * @param sender : the nodeId of the sender (an Acceptor replica which was queried)
539
544
* @param replyMessage : the REPLY message with the value and round number of the previous round
540
545
*/
541
546
public void handleReplyMessage (String sender , ReplyMessage replyMessage ) {
@@ -579,7 +584,8 @@ public void handleReplyMessage(String sender, ReplyMessage replyMessage) {
579
584
* Handle a VIEW_CHANGE message received by a replica.
580
585
* This is used to update the view number and leader ID sent to all the other replicas
581
586
* after a replica elected a new leader.
582
- * @param sender : the nodeId of the sender (the replica that elected a new leader)
587
+ *
588
+ * @param sender : the nodeId of the sender (the replica that elected a new leader)
583
589
* @param viewChangeMessage : the VIEW_CHANGE message with the new view number and leader ID
584
590
*/
585
591
private void handleViewChangeMessage (String sender , ViewChangeMessage viewChangeMessage ) {
@@ -695,9 +701,10 @@ private String getNewLeader() {
695
701
696
702
/**
697
703
* Move replica to the next view number and reset the replica.
704
+ *
698
705
* @param newViewNumber : the new view number
699
- * @param sender : the nodeId of the sender that triggered the reset
700
- * @param message : the message that caused the reset
706
+ * @param sender : the nodeId of the sender that triggered the reset
707
+ * @param message : the message that caused the reset
701
708
*/
702
709
public void reset (long newViewNumber , String sender , MessagePayload message ) {
703
710
// Since we are resetting the replica, previous timeouts should be cleared
@@ -715,7 +722,9 @@ public void reset(long newViewNumber, String sender, MessagePayload message) {
715
722
onStart ();
716
723
}
717
724
718
- /** Methods for checking the roles of the replica. **/
725
+ /**
726
+ * Methods for checking the roles of the replica.
727
+ **/
719
728
private boolean isAcceptor () {
720
729
return this .roles .contains (Role .ACCEPTOR );
721
730
}
0 commit comments