When a message is shared, share its transitive dependencies

Like other recursive operations on the dependency graph, this is
not done in a single transaction to prevent an attacker from creating
arbitrary large transactions.

So at startup, the `ValidationManager` finds and resumes any
unfinished operations, by looking for shared messages with unshared
dependencies.
This commit is contained in:
Torsten Grote
2016-08-31 13:15:59 -03:00
parent 7a0db798d1
commit d058172429
19 changed files with 480 additions and 76 deletions

View File

@@ -28,14 +28,14 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
this.metadataParser = metadataParser;
}
protected abstract void incomingMessage(Transaction txn, Message m,
protected abstract boolean incomingMessage(Transaction txn, Message m,
BdfList body, BdfDictionary meta) throws DbException,
FormatException;
@Override
public void incomingMessage(Transaction txn, Message m, Metadata meta)
public boolean incomingMessage(Transaction txn, Message m, Metadata meta)
throws DbException {
incomingMessage(txn, m, meta, MESSAGE_HEADER_LENGTH);
return incomingMessage(txn, m, meta, MESSAGE_HEADER_LENGTH);
}
@Override
@@ -44,14 +44,14 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
incomingMessage(txn, q, meta, QUEUE_MESSAGE_HEADER_LENGTH);
}
private void incomingMessage(Transaction txn, Message m, Metadata meta,
private boolean incomingMessage(Transaction txn, Message m, Metadata meta,
int headerLength) throws DbException {
try {
byte[] raw = m.getRaw();
BdfList body = clientHelper.toList(raw, headerLength,
raw.length - headerLength);
BdfDictionary metaDictionary = metadataParser.parse(meta);
incomingMessage(txn, m, body, metaDictionary);
return incomingMessage(txn, m, body, metaDictionary);
} catch (FormatException e) {
throw new DbException(e);
}

View File

@@ -245,12 +245,6 @@ class ClientHelperImpl implements ClientHelper {
db.mergeMessageMetadata(txn, m, metadataEncoder.encode(metadata));
}
@Override
public void setMessageShared(Transaction txn, MessageId m, boolean shared)
throws DbException {
db.setMessageShared(txn, m, shared);
}
@Override
public byte[] toByteArray(BdfDictionary dictionary) throws FormatException {
ByteArrayOutputStream out = new ByteArrayOutputStream();

View File

@@ -188,12 +188,12 @@ class MessageQueueManagerImpl implements MessageQueueManager {
private final IncomingQueueMessageHook delegate;
DelegatingIncomingMessageHook(IncomingQueueMessageHook delegate) {
private DelegatingIncomingMessageHook(IncomingQueueMessageHook delegate) {
this.delegate = delegate;
}
@Override
public void incomingMessage(Transaction txn, Message m, Metadata meta)
public boolean incomingMessage(Transaction txn, Message m, Metadata meta)
throws DbException {
long queuePosition = ByteUtils.readUint64(m.getRaw(),
MESSAGE_HEADER_LENGTH);
@@ -239,6 +239,9 @@ class MessageQueueManagerImpl implements MessageQueueManager {
delegate.incomingMessage(txn, q, meta);
}
}
// message queues are only useful for groups with two members
// so messages don't need to be shared
return false;
}
}
}