diff --git a/src/refit/client/REFITLibByz.java b/src/refit/client/REFITLibByz.java index 78db8b9a7551893f162a16f3b22f528830a7b6ea..198b3f48fc8a8e288d614aedb9b1a105391155a9 100644 --- a/src/refit/client/REFITLibByz.java +++ b/src/refit/client/REFITLibByz.java @@ -399,54 +399,9 @@ public class REFITLibByz extends REFITClientLibrary { if (request.mode.isReadOnly() && (REFITConfig.USE_PBFT_READ_OPTIMIZATION || !request.mode.isTotalOrder())) { boolean[] executionReplicas = REFITReplicaGroups.getExecutionReplicas(0); - if (!REFITConfig.SIGNED_REQUESTS) { - // Append MAC, special case for executors - request.setRecipientCount(REFITConfig.EXEC_GROUP_SIZE); - request.serializeMessage(); - messageAuthentication.appendMulticastMAC(request, executionReplicas); - // Send directly to the execution replicas - sendToReplicas(request, executionReplicas); - } else { - // using MACs is sufficient as every executor processes the command on its own - // add MAC to wrapper to unify code paths - request.serializeMessage(); - messageAuthentication.appendNullMAC(request); - for (short i = 0; i < executionReplicas.length; i++) { - if (!executionReplicas[i]) continue; - // wrap - REFITRequestWrapper wrapper = new REFITRequestWrapper(uid, getNodeID(), request); - wrapper.serializeMessage(); - messageAuthentication.appendUnicastMAC(wrapper, i); - - sendToReplica(wrapper, i); - } - } + multicastRequest(request, executionReplicas, REFITConfig.EXEC_GROUP_SIZE); } else { - if (!REFITConfig.SIGNED_REQUESTS) { - // Append MAC - request.setRecipientCount(REFITConfig.ORDER_GROUP_SIZE); - request.serializeMessage(); - messageAuthentication.appendMulticastMAC(request, REFITOrderGroups.getGroupByID(groupID)); - if (!REFITConfig.USE_SPINNING_LEADER) { - // Send request to primary - sendToReplica(request, primaryID); - } else { - short[] group = REFITConfig.ORDER_GROUPS[request.groupID]; - short replicaID = group[getNodeID() % group.length]; - sendToReplica(request, replicaID); - } - } else { - request.serializeMessage(); - // use signatures to prevent executors from damaging the request's authenticator - messageAuthentication.appendSignature(request); - - // wrap - REFITRequestWrapper wrapper = new REFITRequestWrapper(uid, getNodeID(), request); - wrapper.serializeMessage(); - messageAuthentication.appendUnicastMAC(wrapper, primaryID); - - sendToReplica(wrapper, primaryID); - } + unicastRequestToPrimary(request); } } else if (request != null) { if (request.mode.equals(RequestMode.PROBE)) { @@ -465,35 +420,74 @@ public class REFITLibByz extends REFITClientLibrary { request = new REFITRequest(uid, getNodeID(), groupID, request.executeAfter, request.getPayload(), (short) -1, RequestMode.WRITE); readWriteConflict = true; + + // send first retry after mode change only to the primary + unicastRequestToPrimary(request); } else { request = new REFITRequest(request.uid, getNodeID(), groupID, request.executeAfter, request.getPayload(), (short) -1, request.mode); request.markPanic(); - } - if (!REFITConfig.SIGNED_REQUESTS) { - // Append MAC - request.setRecipientCount(retryGroupSize); - request.serializeMessage(); - messageAuthentication.appendMulticastMAC(request, retryGroup); - sendToReplicas(request, retryGroup); - } else { - // use signatures to prevent executors from damaging the request's authenticator - request.serializeMessage(); - messageAuthentication.appendSignature(request); - - boolean[] replicas = REFITReplicaGroups.getExecutionReplicas(0); - for (short i = 0; i < replicas.length; i++) { - if (!replicas[i]) continue; - // wrap - REFITRequestWrapper wrapper = new REFITRequestWrapper(request.uid, getNodeID(), request); - wrapper.serializeMessage(); - messageAuthentication.appendUnicastMAC(wrapper, i); - - sendToReplica(wrapper, i); + if (!REFITConfig.SIGNED_REQUESTS) { + multicastRequest(request, retryGroup, retryGroupSize); + } else { + multicastRequest(request, REFITReplicaGroups.getExecutionReplicas(0), REFITConfig.EXEC_GROUP_SIZE); } } } progress(); } + private void unicastRequestToPrimary(REFITRequest request) { + if (!REFITConfig.SIGNED_REQUESTS) { + // Append MAC + request.setRecipientCount(REFITConfig.ORDER_GROUP_SIZE); + request.serializeMessage(); + messageAuthentication.appendMulticastMAC(request, REFITOrderGroups.getGroupByID(request.groupID)); + if (!REFITConfig.USE_SPINNING_LEADER) { + // Send request to primary + sendToReplica(request, primaryID); + } else { + short[] group = REFITConfig.ORDER_GROUPS[request.groupID]; + short replicaID = group[getNodeID() % group.length]; + sendToReplica(request, replicaID); + } + } else { + request.serializeMessage(); + // use signatures to prevent executors from damaging the request's authenticator + messageAuthentication.appendSignature(request); + + // wrap + REFITRequestWrapper wrapper = new REFITRequestWrapper(request.uid, getNodeID(), request); + wrapper.serializeMessage(); + messageAuthentication.appendUnicastMAC(wrapper, primaryID); + + sendToReplica(wrapper, primaryID); + } + } + + private void multicastRequest(REFITRequest request, boolean[] executionReplicas, short recipientCount) { + if (!REFITConfig.SIGNED_REQUESTS) { + // Append MAC, special case for executors + request.setRecipientCount(recipientCount); + request.serializeMessage(); + messageAuthentication.appendMulticastMAC(request, executionReplicas); + // Send directly to the execution replicas + sendToReplicas(request, executionReplicas); + } else { + // using MACs is sufficient as every executor processes the command on its own + // add MAC to wrapper to unify code paths + request.serializeMessage(); + messageAuthentication.appendNullMAC(request); + for (short i = 0; i < executionReplicas.length; i++) { + if (!executionReplicas[i]) continue; + // wrap + REFITRequestWrapper wrapper = new REFITRequestWrapper(request.uid, getNodeID(), request); + wrapper.serializeMessage(); + messageAuthentication.appendUnicastMAC(wrapper, i); + + sendToReplica(wrapper, i); + } + } + } + }