/** * Copyright (c) 2007-2009 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags * * This file is part of SMaRt. * * SMaRt is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SMaRt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with SMaRt. If not, see . */ package navigators.smart.tom.util; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Random; import navigators.smart.reconfiguration.ReconfigurationManager; import navigators.smart.tom.core.messages.TOMMessage; /** * Batch format: TIMESTAMP(long) + N_NONCES(int) + SEED(long) + * N_MESSAGES(int) + N_MESSAGES*[MSGSIZE(int),MSG(byte),SIG(byte)] + * * * The methods does not try to enforce any constraint, so be correct when using it. * */ public final class BatchBuilder { private Random rnd = new Random(); /** build buffer */ private byte[] createBatch(long timestamp, int numberOfNonces, int numberOfMessages, int totalMessagesSize, boolean useSignatures, byte[][] messages, byte[][] signatures, ReconfigurationManager manager) { int size = 20 + //timestamp 8, nonces 4, nummessages 4 (numberOfNonces > 0 ? 8 : 0) + //seed if needed (numberOfMessages*(4+(useSignatures?TOMUtil.getSignatureSize(manager):0)))+ // msglength + signature for each msg totalMessagesSize; //size of all msges ByteBuffer proposalBuffer = ByteBuffer.allocate(size); proposalBuffer.putLong(timestamp); proposalBuffer.putInt(numberOfNonces); if(numberOfNonces>0){ proposalBuffer.putLong(rnd.nextLong()); } proposalBuffer.putInt(numberOfMessages); for (int i = 0; i < numberOfMessages; i++) { putMessage(proposalBuffer,messages[i], false, signatures[i]); } return proposalBuffer.array(); } private void putMessage(ByteBuffer proposalBuffer, byte[] message, boolean isHash, byte[] signature) { proposalBuffer.putInt(isHash?0:message.length); proposalBuffer.put(message); if(signature != null) { proposalBuffer.put(signature); } } public byte[] makeBatch(Collection msgs, int numNounces, long timestamp, ReconfigurationManager reconfManager) { int numMsgs = msgs.size(); int totalMessageSize = 0; //total size of the messages being batched byte[][] messages = new byte[numMsgs][]; //bytes of the message (or its hash) byte[][] signatures = new byte[numMsgs][]; //bytes of the message (or its hash) // Fill the array of bytes for the messages/signatures being batched int i = 0; for (TOMMessage msg : msgs) { //TOMMessage msg = msgs.next(); //Logger.println("(TOMLayer.run) adding req " + msg + " to PROPOSE"); messages[i] = msg.serializedMessage; signatures[i] = msg.serializedMessageSignature; totalMessageSize += messages[i].length; i++; } // return the batch return createBatch(timestamp, numNounces, numMsgs, totalMessageSize, reconfManager.getStaticConf().getUseSignatures() == 1, messages, signatures,reconfManager); } }