Started removing dependency on CompleteBatch.
Tags of batches are now stored as a blob until the batch is complete.Cached-Client
							parent
							
								
									229cbfd48f
								
							
						
					
					
						commit
						337a135151
					
				| 
						 | 
				
			
			@ -31,7 +31,7 @@ public class LocalBulletinBoardClient implements DeletableSubscriptionBulletinBo
 | 
			
		|||
 | 
			
		||||
    private final DeletableBulletinBoardServer server;
 | 
			
		||||
    private final ListeningScheduledExecutorService executorService;
 | 
			
		||||
    private final BatchDigest digest;
 | 
			
		||||
    private final BulletinBoardDigest digest;
 | 
			
		||||
    private final long subsrciptionDelay;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ public class LocalBulletinBoardClient implements DeletableSubscriptionBulletinBo
 | 
			
		|||
    public LocalBulletinBoardClient(DeletableBulletinBoardServer server, int threadNum, int subscriptionDelay) {
 | 
			
		||||
        this.server = server;
 | 
			
		||||
        this.executorService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadNum));
 | 
			
		||||
        this.digest = new GenericBatchDigest(new SHA256Digest());
 | 
			
		||||
        this.digest = new GenericBulletinBoardDigest(new SHA256Digest());
 | 
			
		||||
        this.subsrciptionDelay = subscriptionDelay;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,9 +74,9 @@ public class LocalBulletinBoardClient implements DeletableSubscriptionBulletinBo
 | 
			
		|||
 | 
			
		||||
    private class CompleteBatchPoster implements Callable<Boolean> {
 | 
			
		||||
 | 
			
		||||
        private final CompleteBatch completeBatch;
 | 
			
		||||
        private final BulletinBoardMessage completeBatch;
 | 
			
		||||
 | 
			
		||||
        public CompleteBatchPoster(CompleteBatch completeBatch) {
 | 
			
		||||
        public CompleteBatchPoster(BulletinBoardMessage completeBatch) {
 | 
			
		||||
            this.completeBatch = completeBatch;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,8 @@ public class LocalBulletinBoardClient implements DeletableSubscriptionBulletinBo
 | 
			
		|||
        @Override
 | 
			
		||||
        public Boolean call() throws CommunicationException {
 | 
			
		||||
 | 
			
		||||
            server.beginBatch(completeBatch.getBeginBatchMessage());
 | 
			
		||||
            server.beginBatch(BeginBatchMessage.newBuilder().setSignerId(completeBatch.getSig(0))
 | 
			
		||||
                    completeBatch.getBeginBatchMessage());
 | 
			
		||||
 | 
			
		||||
            BatchMessage.Builder builder = BatchMessage.newBuilder()
 | 
			
		||||
                    .setSignerId(completeBatch.getSignature().getSignerId())
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +106,7 @@ public class LocalBulletinBoardClient implements DeletableSubscriptionBulletinBo
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MessageID postBatch(CompleteBatch completeBatch, FutureCallback<Boolean> callback) {
 | 
			
		||||
    public MessageID postBatch(ByteString signerId, int batchId, BulletinBoardMessage completeBatch, FutureCallback<Boolean> callback) {
 | 
			
		||||
 | 
			
		||||
        Futures.addCallback(executorService.submit(new CompleteBatchPoster(completeBatch)), callback);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{
 | 
			
		|||
 | 
			
		||||
    protected Client client;
 | 
			
		||||
 | 
			
		||||
    protected BatchDigest digest;
 | 
			
		||||
    protected BulletinBoardDigest digest;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Stores database locations and initializes the web Client
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{
 | 
			
		|||
        client.register(ProtobufMessageBodyWriter.class);
 | 
			
		||||
 | 
			
		||||
        // Wrap the Digest into a BatchDigest
 | 
			
		||||
        digest = new GenericBatchDigest(new SHA256Digest());
 | 
			
		||||
        digest = new GenericBulletinBoardDigest(new SHA256Digest());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,8 +4,6 @@ import com.google.common.util.concurrent.FutureCallback;
 | 
			
		|||
import com.google.protobuf.ByteString;
 | 
			
		||||
 | 
			
		||||
import meerkat.bulletinboard.workers.multiserver.*;
 | 
			
		||||
import meerkat.comm.CommunicationException;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.*;
 | 
			
		||||
import meerkat.protobuf.Voting.*;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +29,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple
 | 
			
		|||
    // Per-server clients
 | 
			
		||||
    private List<SingleServerBulletinBoardClient> clients;
 | 
			
		||||
 | 
			
		||||
    private BatchDigest batchDigest;
 | 
			
		||||
    private BulletinBoardDigest batchDigest;
 | 
			
		||||
 | 
			
		||||
    private final static int POST_MESSAGE_RETRY_NUM = 3;
 | 
			
		||||
    private final static int READ_MESSAGES_RETRY_NUM = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +52,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple
 | 
			
		|||
 | 
			
		||||
        super.init(clientParams);
 | 
			
		||||
 | 
			
		||||
        batchDigest = new GenericBatchDigest(digest);
 | 
			
		||||
        batchDigest = new GenericBulletinBoardDigest(digest);
 | 
			
		||||
 | 
			
		||||
        minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * (float) clientParams.getBulletinBoardAddressCount());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +98,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MessageID postBatch(CompleteBatch completeBatch, FutureCallback<Boolean> callback) {
 | 
			
		||||
    public MessageID postBatch(BulletinBoardMessage completeBatch, FutureCallback<Boolean> callback) {
 | 
			
		||||
 | 
			
		||||
        // Create job
 | 
			
		||||
        MultiServerPostBatchWorker worker =
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +211,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback<CompleteBatch> callback) {
 | 
			
		||||
    public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback<BulletinBoardMessage> callback) {
 | 
			
		||||
 | 
			
		||||
        // Create job
 | 
			
		||||
        MultiServerReadBatchWorker worker =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,16 +3,17 @@ package meerkat.bulletinboard.workers.multiserver;
 | 
			
		|||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import meerkat.bulletinboard.CompleteBatch;
 | 
			
		||||
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 27-Dec-15.
 | 
			
		||||
 */
 | 
			
		||||
public class MultiServerPostBatchWorker extends MultiServerGenericPostWorker<CompleteBatch> {
 | 
			
		||||
public class MultiServerPostBatchWorker extends MultiServerGenericPostWorker<BulletinBoardMessage> {
 | 
			
		||||
 | 
			
		||||
    public MultiServerPostBatchWorker(List<SingleServerBulletinBoardClient> clients,
 | 
			
		||||
                                      int minServers, CompleteBatch payload, int maxRetry,
 | 
			
		||||
                                      int minServers, BulletinBoardMessage payload, int maxRetry,
 | 
			
		||||
                                      FutureCallback<Boolean> futureCallback) {
 | 
			
		||||
 | 
			
		||||
        super(clients, minServers, payload, maxRetry, futureCallback);
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +21,7 @@ public class MultiServerPostBatchWorker extends MultiServerGenericPostWorker<Com
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void doPost(SingleServerBulletinBoardClient client, CompleteBatch payload) {
 | 
			
		||||
    protected void doPost(SingleServerBulletinBoardClient client, BulletinBoardMessage payload) {
 | 
			
		||||
        client.postBatch(payload, this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
package meerkat.bulletinboard.workers.multiserver;
 | 
			
		||||
 | 
			
		||||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import meerkat.bulletinboard.CompleteBatch;
 | 
			
		||||
import meerkat.bulletinboard.SingleServerBulletinBoardClient;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.BatchSpecificationMessage;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
| 
						 | 
				
			
			@ -11,11 +11,11 @@ import java.util.List;
 | 
			
		|||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 27-Dec-15.
 | 
			
		||||
 */
 | 
			
		||||
public class MultiServerReadBatchWorker extends MultiServerGenericReadWorker<BatchSpecificationMessage, CompleteBatch> {
 | 
			
		||||
public class MultiServerReadBatchWorker extends MultiServerGenericReadWorker<BatchSpecificationMessage, BulletinBoardMessage> {
 | 
			
		||||
 | 
			
		||||
    public MultiServerReadBatchWorker(List<SingleServerBulletinBoardClient> clients,
 | 
			
		||||
                                      int minServers, BatchSpecificationMessage payload, int maxRetry,
 | 
			
		||||
                                      FutureCallback<CompleteBatch> futureCallback) {
 | 
			
		||||
                                      FutureCallback<BulletinBoardMessage> futureCallback) {
 | 
			
		||||
 | 
			
		||||
        super(clients, minServers, payload, maxRetry, futureCallback);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ import static meerkat.bulletinboard.BulletinBoardConstants.*;
 | 
			
		|||
import meerkat.comm.CommunicationException;
 | 
			
		||||
 | 
			
		||||
import meerkat.comm.MessageOutputStream;
 | 
			
		||||
import meerkat.crypto.DigitalSignature;
 | 
			
		||||
import meerkat.crypto.concrete.ECDSASignature;
 | 
			
		||||
import meerkat.crypto.concrete.SHA256Digest;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,9 +137,9 @@ public class BulletinBoardSQLServer implements DeletableBulletinBoardServer{
 | 
			
		|||
					new int[] {Types.BLOB, Types.INTEGER, Types.INTEGER, Types.BLOB}
 | 
			
		||||
			),
 | 
			
		||||
 | 
			
		||||
			CONNECT_BATCH_TAG(
 | 
			
		||||
					new String[] {"SignerId", "BatchId", "Tag"},
 | 
			
		||||
					new int[] {Types.BLOB, Types.INTEGER, Types.VARCHAR}
 | 
			
		||||
			STORE_BATCH_TAGS(
 | 
			
		||||
					new String[] {"SignerId", "BatchId", "Tags"},
 | 
			
		||||
					new int[] {Types.BLOB, Types.INTEGER, Types.BLOB}
 | 
			
		||||
			),
 | 
			
		||||
 | 
			
		||||
			GET_BATCH_TAGS(
 | 
			
		||||
| 
						 | 
				
			
			@ -326,8 +327,8 @@ public class BulletinBoardSQLServer implements DeletableBulletinBoardServer{
 | 
			
		|||
 | 
			
		||||
	protected NamedParameterJdbcTemplate jdbcTemplate;
 | 
			
		||||
	
 | 
			
		||||
	protected BatchDigest digest;
 | 
			
		||||
	protected BatchDigitalSignature signer;
 | 
			
		||||
	protected BulletinBoardDigest digest;
 | 
			
		||||
	protected DigitalSignature signer;
 | 
			
		||||
	
 | 
			
		||||
	protected List<SignatureVerificationKey> trusteeSignatureVerificationArray;
 | 
			
		||||
	protected int minTrusteeSignatures;
 | 
			
		||||
| 
						 | 
				
			
			@ -363,7 +364,7 @@ public class BulletinBoardSQLServer implements DeletableBulletinBoardServer{
 | 
			
		|||
	public void init(String meerkatDB) throws CommunicationException {
 | 
			
		||||
		// TODO write signature reading part.
 | 
			
		||||
		
 | 
			
		||||
		digest = new GenericBatchDigest(new SHA256Digest());
 | 
			
		||||
		digest = new GenericBulletinBoardDigest(new SHA256Digest());
 | 
			
		||||
		signer = new GenericBatchDigitalSignature(new ECDSASignature());
 | 
			
		||||
 | 
			
		||||
		jdbcTemplate = new NamedParameterJdbcTemplate(sqlQueryProvider.getDataSource());
 | 
			
		||||
| 
						 | 
				
			
			@ -749,28 +750,15 @@ public class BulletinBoardSQLServer implements DeletableBulletinBoardServer{
 | 
			
		|||
			return BoolMsg.newBuilder().setValue(false).build();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Add new tags to table
 | 
			
		||||
		ProtocolStringList tagList = message.getTagList();
 | 
			
		||||
		String[] tags = new String[tagList.size()];
 | 
			
		||||
		tags = tagList.toArray(tags);
 | 
			
		||||
		try {
 | 
			
		||||
			insertNewTags(tags);
 | 
			
		||||
		} catch (SQLException e) {
 | 
			
		||||
			throw new CommunicationException(e.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		// Store tags
 | 
			
		||||
		String sql = sqlQueryProvider.getSQLString(QueryType.STORE_BATCH_TAGS);
 | 
			
		||||
		MapSqlParameterSource namedParameters = new MapSqlParameterSource();
 | 
			
		||||
 | 
			
		||||
		// Connect tags
 | 
			
		||||
		String sql = sqlQueryProvider.getSQLString(QueryType.CONNECT_BATCH_TAG);
 | 
			
		||||
		MapSqlParameterSource namedParameters[] = new MapSqlParameterSource[tags.length];
 | 
			
		||||
		namedParameters.addValue(QueryType.STORE_BATCH_TAGS.getParamName(0),message.getSignerId().toByteArray());
 | 
			
		||||
		namedParameters.addValue(QueryType.STORE_BATCH_TAGS.getParamName(1),message.getBatchId());
 | 
			
		||||
		namedParameters.addValue(QueryType.STORE_BATCH_TAGS.getParamName(2),message.toByteArray());
 | 
			
		||||
 | 
			
		||||
		for (int i=0 ; i < tags.length ; i++) {
 | 
			
		||||
			namedParameters[i] = new MapSqlParameterSource();
 | 
			
		||||
			namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(0),message.getSignerId().toByteArray());
 | 
			
		||||
			namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(1),message.getBatchId());
 | 
			
		||||
			namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(2),tags[i]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		jdbcTemplate.batchUpdate(sql,namedParameters);
 | 
			
		||||
		jdbcTemplate.update(sql,namedParameters);
 | 
			
		||||
 | 
			
		||||
		return BoolMsg.newBuilder().setValue(true).build();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -832,18 +820,18 @@ public class BulletinBoardSQLServer implements DeletableBulletinBoardServer{
 | 
			
		|||
		namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(0),signerId.toByteArray());
 | 
			
		||||
		namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(1),batchId);
 | 
			
		||||
 | 
			
		||||
		List<String> tags = jdbcTemplate.query(sql, namedParameters, new StringMapper());
 | 
			
		||||
		List<BeginBatchMessage> beginBatchMessages = jdbcTemplate.query(sql, namedParameters, new BeginBatchMessageMapper());
 | 
			
		||||
 | 
			
		||||
		CompleteBatch completeBatch = new CompleteBatch(
 | 
			
		||||
				BeginBatchMessage.newBuilder()
 | 
			
		||||
						.setSignerId(signerId)
 | 
			
		||||
						.setBatchId(batchId)
 | 
			
		||||
						.addAllTag(tags)
 | 
			
		||||
						.build()
 | 
			
		||||
		);
 | 
			
		||||
		if (beginBatchMessages == null || beginBatchMessages.size() <= 0 || beginBatchMessages.get(0) == null) {
 | 
			
		||||
			return BoolMsg.newBuilder().setValue(false).build();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Add timestamp to CompleteBatch
 | 
			
		||||
		completeBatch.setTimestamp(message.getTimestamp());
 | 
			
		||||
		UnsignedBulletinBoardMessage unsignedMessage = UnsignedBulletinBoardMessage.newBuilder()
 | 
			
		||||
				.addAllTag(beginBatchMessages.get(0).getTagList())
 | 
			
		||||
				.addTag(BATCH_TAG)
 | 
			
		||||
				.addTag(batchIdToTag(batchId))
 | 
			
		||||
				.setTimestamp(message.getTimestamp())
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
		// Add actual batch data to CompleteBatch
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -854,36 +842,14 @@ public class BulletinBoardSQLServer implements DeletableBulletinBoardServer{
 | 
			
		|||
		namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),batchId);
 | 
			
		||||
		namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),0); // Read from the beginning
 | 
			
		||||
 | 
			
		||||
		completeBatch.appendBatchData(jdbcTemplate.query(sql, namedParameters, new BatchDataMapper()));
 | 
			
		||||
 | 
			
		||||
		// Verify signature
 | 
			
		||||
 | 
			
		||||
		completeBatch.setSignature(message.getSig());
 | 
			
		||||
 | 
			
		||||
//		try {
 | 
			
		||||
//			TODO: Actual verification
 | 
			
		||||
//			//signer.verify(completeBatch);
 | 
			
		||||
//		} catch (CertificateException | InvalidKeyException | SignatureException e) {
 | 
			
		||||
//			return BoolMsg.newBuilder().setValue(false).build();
 | 
			
		||||
//		}
 | 
			
		||||
 | 
			
		||||
		// Batch verified: finalize it
 | 
			
		||||
 | 
			
		||||
		// Calculate message ID
 | 
			
		||||
		digest.reset();
 | 
			
		||||
		digest.update(completeBatch);
 | 
			
		||||
		MessageID msgID = MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build();
 | 
			
		||||
		//TODO: Verification
 | 
			
		||||
		// Will need to use the following to carry out the signature calculation:
 | 
			
		||||
//		jdbcTemplate.query(sql, namedParameters, new BatchDataMapper());
 | 
			
		||||
 | 
			
		||||
		// Create Bulletin Board message
 | 
			
		||||
		BulletinBoardMessage bulletinBoardMessage = BulletinBoardMessage.newBuilder()
 | 
			
		||||
				.setMsg(unsignedMessage)
 | 
			
		||||
				.addSig(message.getSig())
 | 
			
		||||
				.setMsg(UnsignedBulletinBoardMessage.newBuilder()
 | 
			
		||||
					.addAllTag(tags)
 | 
			
		||||
					.addTag(BATCH_TAG)
 | 
			
		||||
					.addTag(batchIdToTag(batchId))
 | 
			
		||||
					.setData(message.getSig().getSignerId())
 | 
			
		||||
					.setTimestamp(message.getTimestamp())
 | 
			
		||||
					.build())
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
		// Post message without checking signature validity
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,18 +134,16 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider
 | 
			
		|||
                        QueryType.CHECK_BATCH_LENGTH.getParamName(0),
 | 
			
		||||
                        QueryType.CHECK_BATCH_LENGTH.getParamName(1));
 | 
			
		||||
 | 
			
		||||
            case CONNECT_BATCH_TAG:
 | 
			
		||||
            case STORE_BATCH_TAGS:
 | 
			
		||||
                return MessageFormat.format(
 | 
			
		||||
                        "INSERT INTO BatchTagTable (SignerId, BatchId, TagId) SELECT :{0}, :{1}, TagId FROM TagTable"
 | 
			
		||||
                                + " WHERE Tag = :{2}",
 | 
			
		||||
                        QueryType.CONNECT_BATCH_TAG.getParamName(0),
 | 
			
		||||
                        QueryType.CONNECT_BATCH_TAG.getParamName(1),
 | 
			
		||||
                        QueryType.CONNECT_BATCH_TAG.getParamName(2));
 | 
			
		||||
                        "INSERT INTO BatchTagTable (SignerId, BatchId, TagId) VALUES (:{0}, :{1}, :{2})",
 | 
			
		||||
                        QueryType.STORE_BATCH_TAGS.getParamName(0),
 | 
			
		||||
                        QueryType.STORE_BATCH_TAGS.getParamName(1),
 | 
			
		||||
                        QueryType.STORE_BATCH_TAGS.getParamName(2));
 | 
			
		||||
 | 
			
		||||
            case GET_BATCH_TAGS:
 | 
			
		||||
                return MessageFormat.format(
 | 
			
		||||
                        "SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.TagId"
 | 
			
		||||
                                + " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC",
 | 
			
		||||
                        "SELECT Tags FROM BatchTagTable WHERE SignerId = :{0} AND BatchId = :{1}",
 | 
			
		||||
                        QueryType.GET_BATCH_TAGS.getParamName(0),
 | 
			
		||||
                        QueryType.GET_BATCH_TAGS.getParamName(1));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -255,15 +253,14 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider
 | 
			
		|||
                + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum) ON DELETE CASCADE)");
 | 
			
		||||
 | 
			
		||||
        list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)");
 | 
			
		||||
        list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)");
 | 
			
		||||
        list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignatureIndex ON SignatureTable(SignerId, EntryNum)");
 | 
			
		||||
 | 
			
		||||
        list.add("CREATE TABLE IF NOT EXISTS BatchTable (SignerId TINYBLOB, BatchId INT, SerialNum INT, Data BLOB,"
 | 
			
		||||
                + " UNIQUE(SignerId, BatchId, SerialNum))");
 | 
			
		||||
 | 
			
		||||
        list.add("CREATE TABLE IF NOT EXISTS BatchTagTable (SignerId TINYBLOB, BatchId INT, TagId INT,"
 | 
			
		||||
                + " FOREIGN KEY (TagId) REFERENCES TagTable(TagId) ON DELETE CASCADE)");
 | 
			
		||||
        list.add("CREATE TABLE IF NOT EXISTS BatchTagTable (SignerId TINYBLOB, BatchId INT, Tags BLOB)");
 | 
			
		||||
 | 
			
		||||
        list.add("CREATE INDEX IF NOT EXISTS BatchIndex ON BatchTagTable(SignerId, BatchId)");
 | 
			
		||||
        list.add("CREATE UNIQUE INDEX IF NOT EXISTS BatchIndex ON BatchTagTable(SignerId, BatchId)");
 | 
			
		||||
 | 
			
		||||
        // This is used to create a simple table with one entry.
 | 
			
		||||
        // It is used for implementing a workaround for the missing INSERT IGNORE syntax
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
package meerkat.bulletinboard.sqlserver.mappers;
 | 
			
		||||
 | 
			
		||||
import com.google.protobuf.InvalidProtocolBufferException;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage;
 | 
			
		||||
import org.springframework.jdbc.core.RowMapper;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 20-Dec-15.
 | 
			
		||||
 */
 | 
			
		||||
public class BeginBatchMessageMapper implements RowMapper<BeginBatchMessage> {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public BeginBatchMessage mapRow(ResultSet rs, int rowNum) throws SQLException {
 | 
			
		||||
        try {
 | 
			
		||||
            return BeginBatchMessage.newBuilder().mergeFrom(rs.getBytes(1)).build();
 | 
			
		||||
        } catch (InvalidProtocolBufferException e) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
syntax = "proto3";
 | 
			
		||||
 | 
			
		||||
package meerkat;
 | 
			
		||||
 | 
			
		||||
option java_package = "meerkat.protobuf";
 | 
			
		||||
 | 
			
		||||
message Boolean {
 | 
			
		||||
    bool value = 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -21,11 +21,23 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient {
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * Perform an end-to-end post of a signed batch message
 | 
			
		||||
     * @param signerId is the canonical form for the ID of the sender of this batch
 | 
			
		||||
     * @param batchId is a unique (per signer) ID for this batch
 | 
			
		||||
     * @param completeBatch contains all the data of the batch including the meta-data and the signature
 | 
			
		||||
     * @param callback is a class containing methods to handle the result of the operation
 | 
			
		||||
     * @return a unique identifier for the batch message
 | 
			
		||||
     */
 | 
			
		||||
    public MessageID postBatch(CompleteBatch completeBatch, FutureCallback<Boolean> callback);
 | 
			
		||||
    public MessageID postBatch(byte[] signerId, int batchId, BulletinBoardMessage completeBatch, FutureCallback<Boolean> callback);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Perform an end-to-end post of a signed batch message
 | 
			
		||||
     * @param signerId is the canonical form for the ID of the sender of this batch
 | 
			
		||||
     * @param batchId is a unique (per signer) ID for this batch
 | 
			
		||||
     * @param completeBatch contains all the data of the batch including the meta-data and the signature
 | 
			
		||||
     * @param callback is a class containing methods to handle the result of the operation
 | 
			
		||||
     * @return a unique identifier for the batch message
 | 
			
		||||
     */
 | 
			
		||||
    public MessageID postBatch(ByteString signerId, int batchId, BulletinBoardMessage completeBatch, FutureCallback<Boolean> callback);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This message informs the server about the existence of a new batch message and supplies it with the tags associated with it
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +106,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient {
 | 
			
		|||
     * @param batchSpecificationMessage contains the data required to specify a single batch instance
 | 
			
		||||
     * @param callback is a callback class for handling the result of the operation
 | 
			
		||||
     */
 | 
			
		||||
    public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback<CompleteBatch> callback);
 | 
			
		||||
    public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback<BulletinBoardMessage> callback);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
package meerkat.bulletinboard;
 | 
			
		||||
 | 
			
		||||
import meerkat.crypto.Digest;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.*;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 18-Dec-15.
 | 
			
		||||
 * Extends the Digest interface with a method for digesting Batch messages
 | 
			
		||||
 */
 | 
			
		||||
public interface BatchDigest extends Digest {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the digest with the batch message data (ignore the signature)
 | 
			
		||||
     * @param completeBatch is the batch message that needs to be digested
 | 
			
		||||
     */
 | 
			
		||||
    public void update(CompleteBatch completeBatch);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
package meerkat.bulletinboard;
 | 
			
		||||
 | 
			
		||||
import meerkat.crypto.Digest;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.*;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 18-Dec-15.
 | 
			
		||||
 * Extends the Digest interface with a method for digesting Batch messages
 | 
			
		||||
 */
 | 
			
		||||
public interface BulletinBoardDigest extends Digest {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the digest with the batch message data (ignore the signature)
 | 
			
		||||
     * The digest only uses the part the signatures are computed on for this operation
 | 
			
		||||
     * @param completeBatch is the batch message that needs to be digested
 | 
			
		||||
     */
 | 
			
		||||
    public void updateCompleteBatch(BulletinBoardMessage completeBatch);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the digest with a BulletinBoardMessage that contains only the metadata of a batch message
 | 
			
		||||
     * The digest only uses the part the signatures are computed on for this operation
 | 
			
		||||
     * This operation is necessary before beginning to digest the actual data
 | 
			
		||||
     * @param batchStub contains the metadata
 | 
			
		||||
     */
 | 
			
		||||
    public void updateBatchStub(BulletinBoardMessage batchStub);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the digest with the batch message data (ignore the signature)
 | 
			
		||||
     * @param completeBatch is the batch message that needs to be digested
 | 
			
		||||
     */
 | 
			
		||||
    public void updateCompleteBatch(UnsignedBulletinBoardMessage completeBatch);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the digest with a BulletinBoardMessage that contains only the metadata of a batch message
 | 
			
		||||
     * This operation is necessary before beginning to digest the actual data
 | 
			
		||||
     * @param batchStub contains the metadata
 | 
			
		||||
     */
 | 
			
		||||
    public void updateBatchStub(UnsignedBulletinBoardMessage batchStub);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,61 +0,0 @@
 | 
			
		|||
package meerkat.bulletinboard;
 | 
			
		||||
 | 
			
		||||
import com.google.protobuf.Message;
 | 
			
		||||
import meerkat.crypto.Digest;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.MessageID;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.BatchData;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 19-Dec-15.
 | 
			
		||||
 * Wrapper class for digesting Batches in a standardized way
 | 
			
		||||
 */
 | 
			
		||||
public class GenericBatchDigest implements BatchDigest{
 | 
			
		||||
 | 
			
		||||
    private Digest digest;
 | 
			
		||||
 | 
			
		||||
    public GenericBatchDigest(Digest digest) {
 | 
			
		||||
        this.digest = digest;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update(CompleteBatch completeBatch) {
 | 
			
		||||
 | 
			
		||||
        update(completeBatch.getBeginBatchMessage());
 | 
			
		||||
 | 
			
		||||
        for (BatchData batchData : completeBatch.getBatchDataList()) {
 | 
			
		||||
            update(batchData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        update(completeBatch.getTimestamp());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public byte[] digest() {
 | 
			
		||||
        return digest.digest();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MessageID digestAsMessageID() {
 | 
			
		||||
        return digest.digestAsMessageID();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update(Message msg) {
 | 
			
		||||
        digest.update(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void reset() {
 | 
			
		||||
        digest.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public GenericBatchDigest clone() throws CloneNotSupportedException{
 | 
			
		||||
        return new GenericBatchDigest(digest.clone());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
package meerkat.bulletinboard;
 | 
			
		||||
 | 
			
		||||
import com.google.protobuf.BytesValue;
 | 
			
		||||
import com.google.protobuf.Message;
 | 
			
		||||
import meerkat.crypto.Digest;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.*;
 | 
			
		||||
import meerkat.protobuf.BulletinBoardAPI.MessageID;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Arbel Deutsch Peled on 19-Dec-15.
 | 
			
		||||
 * Wrapper class for digesting Batches in a standardized way
 | 
			
		||||
 */
 | 
			
		||||
public class GenericBulletinBoardDigest implements BulletinBoardDigest {
 | 
			
		||||
 | 
			
		||||
    private Digest digest;
 | 
			
		||||
 | 
			
		||||
    public GenericBulletinBoardDigest(Digest digest) {
 | 
			
		||||
        this.digest = digest;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public byte[] digest() {
 | 
			
		||||
        return digest.digest();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MessageID digestAsMessageID() {
 | 
			
		||||
        return digest.digestAsMessageID();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update(Message msg) {
 | 
			
		||||
        digest.update(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update(byte[] data) {
 | 
			
		||||
        digest.update(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void reset() {
 | 
			
		||||
        digest.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public GenericBulletinBoardDigest clone() throws CloneNotSupportedException{
 | 
			
		||||
        return new GenericBulletinBoardDigest(digest.clone());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updateCompleteBatch(BulletinBoardMessage completeBatch) {
 | 
			
		||||
        updateCompleteBatch(completeBatch.getMsg());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updateBatchStub(BulletinBoardMessage batchStub) {
 | 
			
		||||
        updateBatchStub(batchStub.getMsg());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updateCompleteBatch(UnsignedBulletinBoardMessage completeBatch) {
 | 
			
		||||
 | 
			
		||||
        // Digest just the signed part
 | 
			
		||||
        UnsignedBulletinBoardMessage batchStub = completeBatch.toBuilder().clearData().build();
 | 
			
		||||
        updateBatchStub(batchStub);
 | 
			
		||||
 | 
			
		||||
        // Digest the data
 | 
			
		||||
        update(completeBatch.getData().toByteArray());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updateBatchStub(UnsignedBulletinBoardMessage batchStub) {
 | 
			
		||||
        update(batchStub);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,12 @@ public interface Digest {
 | 
			
		|||
     */
 | 
			
		||||
    public MessageID digestAsMessageID();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the digest using the given raw data
 | 
			
		||||
     * @param data contains the raw data
 | 
			
		||||
     */
 | 
			
		||||
    public void update (byte[] data);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the digest using the specified message (in serialized wire form)
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,7 @@ public class SHA256Digest implements Digest {
 | 
			
		|||
        hash.update(msg.asReadOnlyByteBuffer());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    final public void update(byte[] msg) {
 | 
			
		||||
        hash.update(msg);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue