Started removing dependency on CompleteBatch.

Tags of batches are now stored as a blob until the batch is complete.
Cached-Client
Arbel Deutsch Peled 2016-06-15 10:34:46 +03:00
parent 229cbfd48f
commit 337a135151
16 changed files with 223 additions and 186 deletions

View File

@ -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);

View File

@ -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());
}

View File

@ -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 =

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -1,9 +0,0 @@
syntax = "proto3";
package meerkat;
option java_package = "meerkat.protobuf";
message Boolean {
bool value = 1;
}

View File

@ -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);
/**

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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)
*

View File

@ -80,6 +80,7 @@ public class SHA256Digest implements Digest {
hash.update(msg.asReadOnlyByteBuffer());
}
@Override
final public void update(byte[] msg) {
hash.update(msg);
}