Some changes needed for POW server and some general improvements
This commit is contained in:
parent
61788802c5
commit
fad3e07871
@ -66,6 +66,8 @@ public class BitmessageContext {
|
|||||||
private final Listener listener;
|
private final Listener listener;
|
||||||
private final NetworkHandler.MessageListener networkListener;
|
private final NetworkHandler.MessageListener networkListener;
|
||||||
|
|
||||||
|
private final boolean sendPubkeyOnIdentityCreation;
|
||||||
|
|
||||||
private BitmessageContext(Builder builder) {
|
private BitmessageContext(Builder builder) {
|
||||||
ctx = new InternalContext(builder);
|
ctx = new InternalContext(builder);
|
||||||
listener = builder.listener;
|
listener = builder.listener;
|
||||||
@ -75,6 +77,8 @@ public class BitmessageContext {
|
|||||||
// one should be executed at any time.
|
// one should be executed at any time.
|
||||||
pool = Executors.newFixedThreadPool(1);
|
pool = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
|
sendPubkeyOnIdentityCreation = builder.sendPubkeyOnIdentityCreation;
|
||||||
|
|
||||||
new Timer().schedule(new TimerTask() {
|
new Timer().schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -100,12 +104,14 @@ public class BitmessageContext {
|
|||||||
features
|
features
|
||||||
));
|
));
|
||||||
ctx.getAddressRepository().save(identity);
|
ctx.getAddressRepository().save(identity);
|
||||||
pool.submit(new Runnable() {
|
if (sendPubkeyOnIdentityCreation) {
|
||||||
@Override
|
pool.submit(new Runnable() {
|
||||||
public void run() {
|
@Override
|
||||||
ctx.sendPubkey(identity, identity.getStream());
|
public void run() {
|
||||||
}
|
ctx.sendPubkey(identity, identity.getStream());
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +331,8 @@ public class BitmessageContext {
|
|||||||
Listener listener;
|
Listener listener;
|
||||||
int connectionLimit = 150;
|
int connectionLimit = 150;
|
||||||
long connectionTTL = 12 * HOUR;
|
long connectionTTL = 12 * HOUR;
|
||||||
|
boolean sendPubkeyOnIdentityCreation = true;
|
||||||
|
long pubkeyTTL = 28;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
}
|
}
|
||||||
@ -399,6 +407,30 @@ public class BitmessageContext {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default a client will send the public key when an identity is being created. On weaker devices
|
||||||
|
* this behaviour might not be desirable.
|
||||||
|
*/
|
||||||
|
public Builder doNotSendPubkeyOnIdentityCreation() {
|
||||||
|
this.sendPubkeyOnIdentityCreation = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time to live in seconds for public keys the client sends. Defaults to the maximum of 28 days,
|
||||||
|
* but on weak devices smaller values might be desirable.
|
||||||
|
* <p>
|
||||||
|
* Please be aware that this might cause some problems where you can't receive a message (the
|
||||||
|
* sender can't receive your public key) in some special situations. Also note that it's probably
|
||||||
|
* not a good idea to set it too low.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public Builder pubkeyTTL(long days) {
|
||||||
|
if (days < 0 || days > 28 * DAY) throw new IllegalArgumentException("TTL must be between 1 and 28 days");
|
||||||
|
this.pubkeyTTL = days;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public BitmessageContext build() {
|
public BitmessageContext build() {
|
||||||
nonNull("inventory", inventory);
|
nonNull("inventory", inventory);
|
||||||
nonNull("nodeRegistry", nodeRegistry);
|
nonNull("nodeRegistry", nodeRegistry);
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package ch.dissem.bitmessage;
|
package ch.dissem.bitmessage;
|
||||||
|
|
||||||
import ch.dissem.bitmessage.entity.*;
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
|
import ch.dissem.bitmessage.entity.Encrypted;
|
||||||
|
import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||||
import ch.dissem.bitmessage.entity.payload.Broadcast;
|
import ch.dissem.bitmessage.entity.payload.Broadcast;
|
||||||
import ch.dissem.bitmessage.entity.payload.GetPubkey;
|
import ch.dissem.bitmessage.entity.payload.GetPubkey;
|
||||||
import ch.dissem.bitmessage.entity.payload.ObjectPayload;
|
import ch.dissem.bitmessage.entity.payload.ObjectPayload;
|
||||||
@ -29,8 +31,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import static ch.dissem.bitmessage.utils.UnixTime.DAY;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The internal context should normally only be used for port implementations. If you need it in your client
|
* The internal context should normally only be used for port implementations. If you need it in your client
|
||||||
* implementation, you're either doing something wrong, something very weird, or the BitmessageContext should
|
* implementation, you're either doing something wrong, something very weird, or the BitmessageContext should
|
||||||
@ -59,6 +59,7 @@ public class InternalContext {
|
|||||||
private final long clientNonce;
|
private final long clientNonce;
|
||||||
private final long networkNonceTrialsPerByte = 1000;
|
private final long networkNonceTrialsPerByte = 1000;
|
||||||
private final long networkExtraBytes = 1000;
|
private final long networkExtraBytes = 1000;
|
||||||
|
private final long pubkeyTTL;
|
||||||
private long connectionTTL;
|
private long connectionTTL;
|
||||||
private int connectionLimit;
|
private int connectionLimit;
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ public class InternalContext {
|
|||||||
this.port = builder.port;
|
this.port = builder.port;
|
||||||
this.connectionLimit = builder.connectionLimit;
|
this.connectionLimit = builder.connectionLimit;
|
||||||
this.connectionTTL = builder.connectionTTL;
|
this.connectionTTL = builder.connectionTTL;
|
||||||
|
this.pubkeyTTL = builder.pubkeyTTL;
|
||||||
|
|
||||||
Singleton.initialize(security);
|
Singleton.initialize(security);
|
||||||
|
|
||||||
@ -193,7 +195,7 @@ public class InternalContext {
|
|||||||
|
|
||||||
public void sendPubkey(final BitmessageAddress identity, final long targetStream) {
|
public void sendPubkey(final BitmessageAddress identity, final long targetStream) {
|
||||||
try {
|
try {
|
||||||
long expires = UnixTime.now(+28 * DAY);
|
long expires = UnixTime.now(pubkeyTTL);
|
||||||
LOG.info("Expires at " + expires);
|
LOG.info("Expires at " + expires);
|
||||||
final ObjectMessage response = new ObjectMessage.Builder()
|
final ObjectMessage response = new ObjectMessage.Builder()
|
||||||
.stream(targetStream)
|
.stream(targetStream)
|
||||||
@ -211,7 +213,7 @@ public class InternalContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void requestPubkey(final BitmessageAddress contact) {
|
public void requestPubkey(final BitmessageAddress contact) {
|
||||||
long expires = UnixTime.now(+2 * DAY);
|
long expires = UnixTime.now(+pubkeyTTL);
|
||||||
LOG.info("Expires at " + expires);
|
LOG.info("Expires at " + expires);
|
||||||
final ObjectMessage response = new ObjectMessage.Builder()
|
final ObjectMessage response = new ObjectMessage.Builder()
|
||||||
.stream(contact.getStream())
|
.stream(contact.getStream())
|
||||||
|
@ -8,6 +8,10 @@ import ch.dissem.bitmessage.ports.MessageRepository;
|
|||||||
import ch.dissem.bitmessage.ports.ProofOfWorkEngine;
|
import ch.dissem.bitmessage.ports.ProofOfWorkEngine;
|
||||||
import ch.dissem.bitmessage.ports.ProofOfWorkRepository;
|
import ch.dissem.bitmessage.ports.ProofOfWorkRepository;
|
||||||
import ch.dissem.bitmessage.ports.Security;
|
import ch.dissem.bitmessage.ports.Security;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static ch.dissem.bitmessage.utils.Singleton.security;
|
import static ch.dissem.bitmessage.utils.Singleton.security;
|
||||||
|
|
||||||
@ -15,13 +19,19 @@ import static ch.dissem.bitmessage.utils.Singleton.security;
|
|||||||
* @author Christian Basler
|
* @author Christian Basler
|
||||||
*/
|
*/
|
||||||
public class ProofOfWorkService implements ProofOfWorkEngine.Callback, InternalContext.ContextHolder {
|
public class ProofOfWorkService implements ProofOfWorkEngine.Callback, InternalContext.ContextHolder {
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ProofOfWorkService.class);
|
||||||
|
|
||||||
private Security security;
|
private Security security;
|
||||||
private InternalContext ctx;
|
private InternalContext ctx;
|
||||||
private ProofOfWorkRepository powRepo;
|
private ProofOfWorkRepository powRepo;
|
||||||
private MessageRepository messageRepo;
|
private MessageRepository messageRepo;
|
||||||
|
|
||||||
public void doMissingProofOfWork() {
|
public void doMissingProofOfWork() {
|
||||||
for (byte[] initialHash : powRepo.getItems()) {
|
List<byte[]> items = powRepo.getItems();
|
||||||
|
if (items.isEmpty()) return;
|
||||||
|
|
||||||
|
LOG.info("Doing POW for " + items.size() + " tasks.");
|
||||||
|
for (byte[] initialHash : items) {
|
||||||
ProofOfWorkRepository.Item item = powRepo.getItem(initialHash);
|
ProofOfWorkRepository.Item item = powRepo.getItem(initialHash);
|
||||||
security.doProofOfWork(item.object, item.nonceTrialsPerByte, item.extraBytes, this);
|
security.doProofOfWork(item.object, item.nonceTrialsPerByte, item.extraBytes, this);
|
||||||
}
|
}
|
||||||
@ -32,8 +42,10 @@ public class ProofOfWorkService implements ProofOfWorkEngine.Callback, InternalC
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void doProofOfWork(BitmessageAddress recipient, ObjectMessage object) {
|
public void doProofOfWork(BitmessageAddress recipient, ObjectMessage object) {
|
||||||
long nonceTrialsPerByte = recipient == null ? 0 : recipient.getPubkey().getNonceTrialsPerByte();
|
long nonceTrialsPerByte = recipient == null ?
|
||||||
long extraBytes = recipient == null ? 0 : recipient.getPubkey().getExtraBytes();
|
ctx.getNetworkNonceTrialsPerByte() : recipient.getPubkey().getNonceTrialsPerByte();
|
||||||
|
long extraBytes = recipient == null ?
|
||||||
|
ctx.getNetworkExtraBytes() : recipient.getPubkey().getExtraBytes();
|
||||||
|
|
||||||
powRepo.putObject(object, nonceTrialsPerByte, extraBytes);
|
powRepo.putObject(object, nonceTrialsPerByte, extraBytes);
|
||||||
if (object.getPayload() instanceof PlaintextHolder) {
|
if (object.getPayload() instanceof PlaintextHolder) {
|
||||||
|
@ -43,7 +43,7 @@ public class CustomMessage implements MessagePayload {
|
|||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessagePayload read(InputStream in, int length) throws IOException {
|
public static CustomMessage read(InputStream in, int length) throws IOException {
|
||||||
AccessCounter counter = new AccessCounter();
|
AccessCounter counter = new AccessCounter();
|
||||||
return new CustomMessage(varString(in, counter), bytes(in, length - counter.length()));
|
return new CustomMessage(varString(in, counter), bytes(in, length - counter.length()));
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ public abstract class AbstractSecurity implements Security, InternalContext.Cont
|
|||||||
public static final Logger LOG = LoggerFactory.getLogger(Security.class);
|
public static final Logger LOG = LoggerFactory.getLogger(Security.class);
|
||||||
private static final SecureRandom RANDOM = new SecureRandom();
|
private static final SecureRandom RANDOM = new SecureRandom();
|
||||||
private static final BigInteger TWO = BigInteger.valueOf(2);
|
private static final BigInteger TWO = BigInteger.valueOf(2);
|
||||||
|
private static final BigInteger TWO_POW_64 = TWO.pow(64);
|
||||||
|
private static final BigInteger TWO_POW_16 = TWO.pow(16);
|
||||||
|
|
||||||
private final String provider;
|
private final String provider;
|
||||||
private InternalContext context;
|
private InternalContext context;
|
||||||
@ -96,18 +98,14 @@ public abstract class AbstractSecurity implements Security, InternalContext.Cont
|
|||||||
|
|
||||||
public void doProofOfWork(ObjectMessage object, long nonceTrialsPerByte,
|
public void doProofOfWork(ObjectMessage object, long nonceTrialsPerByte,
|
||||||
long extraBytes, ProofOfWorkEngine.Callback callback) {
|
long extraBytes, ProofOfWorkEngine.Callback callback) {
|
||||||
try {
|
nonceTrialsPerByte = max(nonceTrialsPerByte, context.getNetworkNonceTrialsPerByte());
|
||||||
nonceTrialsPerByte = max(nonceTrialsPerByte, context.getNetworkNonceTrialsPerByte());
|
extraBytes = max(extraBytes, context.getNetworkExtraBytes());
|
||||||
extraBytes = max(extraBytes, context.getNetworkExtraBytes());
|
|
||||||
|
|
||||||
byte[] initialHash = getInitialHash(object);
|
byte[] initialHash = getInitialHash(object);
|
||||||
|
|
||||||
byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
|
byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
|
||||||
|
|
||||||
context.getProofOfWorkEngine().calculateNonce(initialHash, target, callback);
|
context.getProofOfWorkEngine().calculateNonce(initialHash, target, callback);
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes)
|
public void checkProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes)
|
||||||
@ -124,11 +122,20 @@ public abstract class AbstractSecurity implements Security, InternalContext.Cont
|
|||||||
return sha512(object.getPayloadBytesWithoutNonce());
|
return sha512(object.getPayloadBytesWithoutNonce());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getProofOfWorkTarget(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException {
|
@Override
|
||||||
|
public byte[] getProofOfWorkTarget(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) {
|
||||||
|
if (nonceTrialsPerByte == 0) nonceTrialsPerByte = context.getNetworkNonceTrialsPerByte();
|
||||||
|
if (extraBytes == 0) extraBytes = context.getNetworkExtraBytes();
|
||||||
|
|
||||||
BigInteger TTL = BigInteger.valueOf(object.getExpiresTime() - UnixTime.now());
|
BigInteger TTL = BigInteger.valueOf(object.getExpiresTime() - UnixTime.now());
|
||||||
BigInteger numerator = TWO.pow(64);
|
BigInteger numerator = TWO_POW_64;
|
||||||
BigInteger powLength = BigInteger.valueOf(object.getPayloadBytesWithoutNonce().length + extraBytes);
|
BigInteger powLength = BigInteger.valueOf(object.getPayloadBytesWithoutNonce().length + extraBytes);
|
||||||
BigInteger denominator = BigInteger.valueOf(nonceTrialsPerByte).multiply(powLength.add(powLength.multiply(TTL).divide(BigInteger.valueOf(2).pow(16))));
|
BigInteger denominator = BigInteger.valueOf(nonceTrialsPerByte)
|
||||||
|
.multiply(
|
||||||
|
powLength.add(
|
||||||
|
powLength.multiply(TTL).divide(TWO_POW_16)
|
||||||
|
)
|
||||||
|
);
|
||||||
return Bytes.expand(numerator.divide(denominator).toByteArray(), 8);
|
return Bytes.expand(numerator.divide(denominator).toByteArray(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +136,8 @@ public interface Security {
|
|||||||
|
|
||||||
byte[] getInitialHash(ObjectMessage object);
|
byte[] getInitialHash(ObjectMessage object);
|
||||||
|
|
||||||
|
byte[] getProofOfWorkTarget(ObjectMessage object, long nonceTrialsPerByte, long extraBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the MAC for a message (data)
|
* Calculates the MAC for a message (data)
|
||||||
*
|
*
|
||||||
|
@ -54,8 +54,8 @@ public class CryptoCustomMessage<T extends Streamable> extends CustomMessage {
|
|||||||
this.dataReader = dataReader;
|
this.dataReader = dataReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Streamable> CryptoCustomMessage<T> read(byte[] data, Reader<T> dataReader) throws IOException {
|
public static <T extends Streamable> CryptoCustomMessage<T> read(CustomMessage data, Reader<T> dataReader) throws IOException {
|
||||||
CryptoBox cryptoBox = CryptoBox.read(new ByteArrayInputStream(data), data.length);
|
CryptoBox cryptoBox = CryptoBox.read(new ByteArrayInputStream(data.getData()), data.getData().length);
|
||||||
return new CryptoCustomMessage<>(cryptoBox, dataReader);
|
return new CryptoCustomMessage<>(cryptoBox, dataReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +111,7 @@ public class CryptoCustomMessage<T extends Streamable> extends CustomMessage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(OutputStream out) throws IOException {
|
public void write(OutputStream out) throws IOException {
|
||||||
|
Encode.varString(COMMAND, out);
|
||||||
container.write(out);
|
container.write(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import ch.dissem.bitmessage.utils.Encode;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static ch.dissem.bitmessage.utils.Decode.*;
|
import static ch.dissem.bitmessage.utils.Decode.*;
|
||||||
|
|
||||||
@ -80,6 +81,28 @@ public class ProofOfWorkRequest implements Streamable {
|
|||||||
Encode.varBytes(data, out);
|
Encode.varBytes(data, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ProofOfWorkRequest other = (ProofOfWorkRequest) o;
|
||||||
|
|
||||||
|
if (!sender.equals(other.sender)) return false;
|
||||||
|
if (!Arrays.equals(initialHash, other.initialHash)) return false;
|
||||||
|
if (request != other.request) return false;
|
||||||
|
return Arrays.equals(data, other.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = sender.hashCode();
|
||||||
|
result = 31 * result + Arrays.hashCode(initialHash);
|
||||||
|
result = 31 * result + request.hashCode();
|
||||||
|
result = 31 * result + Arrays.hashCode(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Reader implements CryptoCustomMessage.Reader<ProofOfWorkRequest> {
|
public static class Reader implements CryptoCustomMessage.Reader<ProofOfWorkRequest> {
|
||||||
private final BitmessageAddress identity;
|
private final BitmessageAddress identity;
|
||||||
|
|
||||||
@ -93,7 +116,6 @@ public class ProofOfWorkRequest implements Streamable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum Request {
|
public enum Request {
|
||||||
CALCULATE,
|
CALCULATE,
|
||||||
CALCULATING,
|
CALCULATING,
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
package ch.dissem.bitmessage.extensions;
|
package ch.dissem.bitmessage.extensions;
|
||||||
|
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
|
import ch.dissem.bitmessage.entity.CustomMessage;
|
||||||
import ch.dissem.bitmessage.entity.payload.GenericPayload;
|
import ch.dissem.bitmessage.entity.payload.GenericPayload;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
||||||
|
import ch.dissem.bitmessage.extensions.pow.ProofOfWorkRequest;
|
||||||
import ch.dissem.bitmessage.utils.TestBase;
|
import ch.dissem.bitmessage.utils.TestBase;
|
||||||
import ch.dissem.bitmessage.utils.TestUtils;
|
import ch.dissem.bitmessage.utils.TestUtils;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -33,7 +35,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
|
|
||||||
public class CryptoCustomMessageTest extends TestBase {
|
public class CryptoCustomMessageTest extends TestBase {
|
||||||
@Test
|
@Test
|
||||||
public void testEncryptThenDecrypt() throws Exception {
|
public void ensureEncryptThenDecryptYieldsSameObject() throws Exception {
|
||||||
PrivateKey privateKey = PrivateKey.read(TestUtils.getResource("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8.privkey"));
|
PrivateKey privateKey = PrivateKey.read(TestUtils.getResource("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8.privkey"));
|
||||||
BitmessageAddress sendingIdentity = new BitmessageAddress(privateKey);
|
BitmessageAddress sendingIdentity = new BitmessageAddress(privateKey);
|
||||||
|
|
||||||
@ -45,14 +47,40 @@ public class CryptoCustomMessageTest extends TestBase {
|
|||||||
messageBefore.write(out);
|
messageBefore.write(out);
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
|
||||||
CryptoCustomMessage<GenericPayload> messageAfter = CryptoCustomMessage.read(out.toByteArray(), new CryptoCustomMessage.Reader<GenericPayload>() {
|
CustomMessage customMessage = CustomMessage.read(in, out.size());
|
||||||
@Override
|
CryptoCustomMessage<GenericPayload> messageAfter = CryptoCustomMessage.read(customMessage,
|
||||||
public GenericPayload read(BitmessageAddress ignore, InputStream in) throws IOException {
|
new CryptoCustomMessage.Reader<GenericPayload>() {
|
||||||
return GenericPayload.read(0, in, 1, 100);
|
@Override
|
||||||
}
|
public GenericPayload read(BitmessageAddress ignore, InputStream in) throws IOException {
|
||||||
});
|
return GenericPayload.read(0, in, 1, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
GenericPayload payloadAfter = messageAfter.decrypt(sendingIdentity.getPublicDecryptionKey());
|
GenericPayload payloadAfter = messageAfter.decrypt(sendingIdentity.getPublicDecryptionKey());
|
||||||
|
|
||||||
assertEquals(payloadBefore, payloadAfter);
|
assertEquals(payloadBefore, payloadAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithActualRequest() throws Exception {
|
||||||
|
PrivateKey privateKey = PrivateKey.read(TestUtils.getResource("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8.privkey"));
|
||||||
|
final BitmessageAddress sendingIdentity = new BitmessageAddress(privateKey);
|
||||||
|
|
||||||
|
ProofOfWorkRequest requestBefore = new ProofOfWorkRequest(sendingIdentity, security().randomBytes(64),
|
||||||
|
ProofOfWorkRequest.Request.CALCULATE);
|
||||||
|
|
||||||
|
CryptoCustomMessage<ProofOfWorkRequest> messageBefore = new CryptoCustomMessage<>(requestBefore);
|
||||||
|
messageBefore.signAndEncrypt(sendingIdentity, security().createPublicKey(sendingIdentity.getPublicDecryptionKey()));
|
||||||
|
|
||||||
|
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
messageBefore.write(out);
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
|
||||||
|
CustomMessage customMessage = CustomMessage.read(in, out.size());
|
||||||
|
CryptoCustomMessage<ProofOfWorkRequest> messageAfter = CryptoCustomMessage.read(customMessage,
|
||||||
|
new ProofOfWorkRequest.Reader(sendingIdentity));
|
||||||
|
ProofOfWorkRequest requestAfter = messageAfter.decrypt(sendingIdentity.getPublicDecryptionKey());
|
||||||
|
|
||||||
|
assertEquals(requestBefore, requestAfter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user