Acknowledgments are now returned, received, and the message (Plaintext object) updated

-> no logic to resend messages yet
This commit is contained in:
2016-05-06 19:39:39 +02:00
parent de8f04e22a
commit 05d9ea93d2
12 changed files with 79 additions and 39 deletions

View File

@ -31,8 +31,6 @@ import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -71,16 +69,10 @@ public class BitmessageContext {
private BitmessageContext(Builder builder) {
ctx = new InternalContext(builder);
labeler = builder.labeler;
ctx.getProofOfWorkService().doMissingProofOfWork();
networkListener = new DefaultMessageListener(ctx, labeler, builder.listener);
sendPubkeyOnIdentityCreation = builder.sendPubkeyOnIdentityCreation;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
ctx.getProofOfWorkService().doMissingProofOfWork();
}
}, 30_000); // After 30 seconds
}
public AddressRepository addresses() {

View File

@ -48,9 +48,12 @@ class DefaultMessageListener implements NetworkHandler.MessageListener {
}
@Override
@SuppressWarnings("ConstantConditions")
public void receive(ObjectMessage object) throws IOException {
ObjectPayload payload = object.getPayload();
if (payload.getType() == null) return;
if (payload.getType() == null && payload instanceof GenericPayload) {
receive((GenericPayload) payload);
}
switch (payload.getType()) {
case GET_PUBKEY: {
@ -125,7 +128,7 @@ class DefaultMessageListener implements NetworkHandler.MessageListener {
if (!object.isSignatureValid(plaintext.getFrom().getPubkey())) {
LOG.warn("Msg with IV " + object.getInventoryVector() + " was successfully decrypted, but signature check failed. Ignoring.");
} else {
receive(object.getInventoryVector(), msg.getPlaintext());
receive(object.getInventoryVector(), plaintext);
}
break;
} catch (DecryptionFailedException ignore) {
@ -133,6 +136,16 @@ class DefaultMessageListener implements NetworkHandler.MessageListener {
}
}
protected void receive(GenericPayload ack) {
if (ack.getData().length == Msg.ACK_LENGTH) {
Plaintext msg = ctx.getMessageRepository().getMessageForAck(ack.getData());
if (msg != null) {
ctx.getLabeler().markAsAcknowledged(msg);
ctx.getMessageRepository().save(msg);
}
}
}
protected void receive(ObjectMessage object, Broadcast broadcast) throws IOException {
byte[] tag = broadcast instanceof V5Broadcast ? ((V5Broadcast) broadcast).getTag() : null;
for (BitmessageAddress subscription : ctx.getAddressRepository().getSubscriptions(broadcast.getVersion())) {

View File

@ -12,6 +12,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import static ch.dissem.bitmessage.InternalContext.NETWORK_EXTRA_BYTES;
import static ch.dissem.bitmessage.InternalContext.NETWORK_NONCE_TRIALS_PER_BYTE;
@ -29,14 +31,21 @@ public class ProofOfWorkService implements ProofOfWorkEngine.Callback, InternalC
private MessageRepository messageRepo;
public void doMissingProofOfWork() {
List<byte[]> items = powRepo.getItems();
final List<byte[]> items = powRepo.getItems();
if (items.isEmpty()) return;
LOG.info("Doing POW for " + items.size() + " tasks.");
for (byte[] initialHash : items) {
Item item = powRepo.getItem(initialHash);
cryptography.doProofOfWork(item.object, item.nonceTrialsPerByte, item.extraBytes, this);
}
// Wait for 30 seconds, to let the application start up before putting heavy load on the CPU
new Timer().schedule(new TimerTask() {
@Override
public void run() {
LOG.info("Doing POW for " + items.size() + " tasks.");
for (byte[] initialHash : items) {
Item item = powRepo.getItem(initialHash);
cryptography.doProofOfWork(item.object, item.nonceTrialsPerByte, item.extraBytes,
ProofOfWorkService.this);
}
}
}, 30_000);
}
public void doProofOfWork(ObjectMessage object) {
@ -79,7 +88,6 @@ public class ProofOfWorkService implements ProofOfWorkEngine.Callback, InternalC
messageRepo.save(plaintext);
}
ctx.getInventory().storeObject(object);
powRepo.removeObject(initialHash);
ctx.getNetworkHandler().offer(object.getInventoryVector());
} else {
item.message.getAckMessage().setNonce(nonce);
@ -96,6 +104,7 @@ public class ProofOfWorkService implements ProofOfWorkEngine.Callback, InternalC
}
doProofOfWork(item.message.getTo(), object);
}
powRepo.removeObject(initialHash);
}
@Override

View File

@ -16,6 +16,7 @@
package ch.dissem.bitmessage.entity;
import ch.dissem.bitmessage.entity.payload.Msg;
import ch.dissem.bitmessage.entity.payload.Pubkey;
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
import ch.dissem.bitmessage.entity.valueobject.Label;
@ -511,7 +512,7 @@ public class Plaintext implements Streamable {
to = new BitmessageAddress(0, 0, destinationRipe);
}
if (type == Type.MSG && ackMessage == null && ackData == null) {
ackData = cryptography().randomBytes(32);
ackData = cryptography().randomBytes(Msg.ACK_LENGTH);
}
return new Plaintext(this);
}

View File

@ -53,6 +53,10 @@ public class GenericPayload extends ObjectPayload {
return stream;
}
public byte[] getData() {
return data;
}
@Override
public void write(OutputStream stream) throws IOException {
stream.write(data);

View File

@ -33,6 +33,7 @@ import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG;
*/
public class Msg extends ObjectPayload implements Encrypted, PlaintextHolder {
private static final long serialVersionUID = 4327495048296365733L;
public static final int ACK_LENGTH = 32;
private long stream;
private CryptoBox encrypted;

View File

@ -23,6 +23,8 @@ import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.payload.*;
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
import ch.dissem.bitmessage.exception.NodeException;
import ch.dissem.bitmessage.utils.TTL;
import ch.dissem.bitmessage.utils.UnixTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -210,6 +212,6 @@ public class Factory {
if (plaintext == null || plaintext.getAckData() == null)
return null;
GenericPayload ack = new GenericPayload(3, plaintext.getFrom().getStream(), plaintext.getAckData());
return new ObjectMessage.Builder().objectType(MSG).payload(ack).build();
return new ObjectMessage.Builder().objectType(MSG).payload(ack).expiresTime(UnixTime.now(+TTL.msg())).build();
}
}

View File

@ -34,6 +34,8 @@ public interface MessageRepository {
Plaintext getMessage(byte[] initialHash);
Plaintext getMessageForAck(byte[] ackData);
List<Plaintext> findMessages(Label label);
List<Plaintext> findMessages(Status status);