added jars, fixed tests

This commit is contained in:
Manfred Karrer 2015-11-03 15:34:04 +01:00
parent 3711519e3a
commit c5ee2c9186
36 changed files with 341 additions and 258 deletions

View File

@ -17,15 +17,10 @@
package io.bitsquare.common.crypto;
import io.bitsquare.app.Version;
import java.io.Serializable;
import java.security.PublicKey;
public final class DecryptedPayloadWithPubKey implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Serializable payload;
public final PublicKey sigPublicKey;

View File

@ -81,7 +81,6 @@ public class Encryption {
return cipher.doFinal(encryptedPayload);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| BadPaddingException | IllegalBlockSizeException | NoSuchProviderException e) {
e.printStackTrace();
throw new CryptoException(e);
}
}

View File

@ -34,7 +34,7 @@ import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.*;
// TODO: use a password protection for storage?
// TODO: use a password protection for key storage
public class KeyStorage {
private static final Logger log = LoggerFactory.getLogger(KeyStorage.class);
@ -140,6 +140,7 @@ public class KeyStorage {
if (!storageDir.exists())
storageDir.mkdir();
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + ".key")) {
fos.write(pkcs8EncodedKeySpec.getEncoded());

View File

@ -49,29 +49,6 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.msopentech.thali</groupId>
<artifactId>universal</artifactId>
<version>0.0.3-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.msopentech.thali</groupId>
<artifactId>java</artifactId>
<version>0.0.3-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>

View File

@ -173,18 +173,12 @@ public class ArbitratorManager {
.collect(Collectors.toMap(Arbitrator::getArbitratorAddress, Function.identity()));
arbitratorsObservableMap.putAll(filtered);
log.debug("filtered arbitrators: " + arbitratorsObservableMap.values());
log.trace("user.getAcceptedArbitrators(): " + user.getAcceptedArbitrators().toString());
// we need to remove accepted arbitrators which are not available anymore
if (user.getAcceptedArbitrators() != null) {
List<Arbitrator> removeList = user.getAcceptedArbitrators().stream()
.filter(e -> !arbitratorsObservableMap.containsValue(e))
.collect(Collectors.toList());
removeList.stream().forEach(user::removeAcceptedArbitrator);
log.trace("removeList arbitrators: " + removeList.toString());
log.trace("user.getAcceptedArbitrators(): " + user.getAcceptedArbitrators().toString());
// if we don't have any arbitrator anymore we set all matching
if (user.getAcceptedArbitrators().isEmpty()) {
@ -192,8 +186,6 @@ public class ArbitratorManager {
.filter(arbitrator -> user.hasMatchingLanguage(arbitrator))
.forEach(arbitrator -> user.addAcceptedArbitrator(arbitrator));
}
log.trace("user.getAcceptedArbitrators(): " + user.getAcceptedArbitrators().toString());
}
}

View File

@ -153,7 +153,8 @@ public class DisputeManager {
log.debug("decryptedMessageWithPubKey.message " + message);
if (message instanceof DisputeMessage) {
dispatchMessage((DisputeMessage) message);
p2PService.removeEntryFromMailbox(decryptedMessageWithPubKey);
//TODO
//p2PService.removeEntryFromMailbox(decryptedMessageWithPubKey);
}
});
decryptedMailboxMessageWithPubKeys.clear();

View File

@ -987,7 +987,7 @@ public class TradeWalletService {
private void verifyTransaction(Transaction transaction) throws TransactionVerificationException {
try {
log.trace("Verify transaction");
log.trace("Verify transaction " + transaction);
transaction.verify();
} catch (Throwable t) {
t.printStackTrace();

View File

@ -205,6 +205,7 @@ public class TradeManager {
// after we are authenticated we remove mailbox messages.
DecryptedMsgWithPubKey mailboxMessage = trade.getMailboxMessage();
if (mailboxMessage != null) {
log.trace("initPendingTrades/removeEntryFromMailbox mailboxMessage = " + mailboxMessage);
p2PService.removeEntryFromMailbox(mailboxMessage);
trade.setMailboxMessage(null);
}

View File

@ -82,8 +82,6 @@ public class DisputesView extends ActivatableViewAndModel<TabPane, Activatable>
boolean isArbitrator = arbitratorManager.getArbitratorsObservableMap().values().stream()
.filter(e -> e.getPubKeyRing() != null && e.getPubKeyRing().equals(keyRing.getPubKeyRing()))
.findAny().isPresent();
log.debug("arbitratorManager.getArbitratorsObservableMap() " + arbitratorManager.getArbitratorsObservableMap().size());
log.debug("updateArbitratorsDisputesTabDisableState isArbitrator=" + isArbitrator);
arbitratorsDisputesTab.setDisable(!isArbitrator);
if (arbitratorsDisputesTab.getContent() != null)
arbitratorsDisputesTab.getContent().setDisable(!isArbitrator);

View File

@ -68,7 +68,6 @@ class MarketViewModel extends ActivatableViewModel {
protected void activate() {
offerBookListItems.addListener(listChangeListener);
offerBook.fillOfferBookListItems();
//updateChartData(offerBookListItems);
}
@Override

View File

@ -122,8 +122,7 @@ class OfferBookViewModel extends ActivatableViewModel {
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
this.tradeCurrency = tradeCurrency;
tradeCurrencyCode.set(tradeCurrency.getCode());
/* if (!(tradeCurrency instanceof AllTradeCurrenciesEntry))*/
//offerBook.getOffers(tradeCurrencyCode.get());
filterList();
}
public void onSetPaymentMethod(PaymentMethod paymentMethod) {
@ -273,11 +272,12 @@ class OfferBookViewModel extends ActivatableViewModel {
filteredItems.setPredicate(offerBookListItem -> {
Offer offer = offerBookListItem.getOffer();
boolean directionResult = offer.getDirection() != direction;
boolean currencyResult = offer.getCurrencyCode().equals(tradeCurrency.getCode());
boolean paymentMethodResult = true;
if (!(paymentMethod instanceof AllPaymentMethodsEntry))
if (!(paymentMethod instanceof AllPaymentMethodsEntry))
paymentMethodResult = offer.getPaymentMethod().equals(paymentMethod);
return directionResult && paymentMethodResult;
return directionResult && currencyResult && paymentMethodResult;
});
}

Binary file not shown.

Binary file not shown.

View File

@ -22,6 +22,8 @@
<groupId>com.msopentech.thali</groupId>
<artifactId>universal</artifactId>
<version>0.0.3-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/libs/universal-0.0.3-SNAPSHOT.jar</systemPath>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@ -33,6 +35,8 @@
<groupId>com.msopentech.thali</groupId>
<artifactId>java</artifactId>
<version>0.0.3-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/libs/java-0.0.3-SNAPSHOT.jar</systemPath>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@ -1,10 +1,14 @@
package io.bitsquare.crypto;
import io.bitsquare.app.Version;
import io.bitsquare.common.crypto.SealedAndSigned;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.messaging.MailboxMessage;
public class SealedAndSignedMessage implements MailboxMessage {
public final class SealedAndSignedMessage implements MailboxMessage {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final SealedAndSigned sealedAndSigned;
public final Address peerAddress;

View File

@ -141,24 +141,24 @@ public class P2PService {
@Override
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
checkArgument(peerAddress.equals(connection.getPeerAddress()));
authenticatedPeerAddresses.add(peerAddress);
if (!authenticatedToFirstPeer) {
authenticatedToFirstPeer = true;
Address address = connection.getPeerAddress();
SettableFuture<Connection> future = sendMessage(address,
SettableFuture<Connection> future = sendMessage(peerAddress,
new GetDataSetMessage(addToListAndGetNonce()));
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
public void onSuccess(@Nullable Connection connection) {
log.info("onPeerAddressAuthenticated Send GetAllDataMessage to " + address + " succeeded.");
connectedSeedNodes.add(address);
log.info("onPeerAddressAuthenticated Send GetAllDataMessage to " + peerAddress + " succeeded.");
connectedSeedNodes.add(peerAddress);
}
@Override
public void onFailure(Throwable throwable) {
log.warn("onPeerAddressAuthenticated Send GetAllDataMessage to " + address + " failed. " +
log.warn("onPeerAddressAuthenticated Send GetAllDataMessage to " + peerAddress + " failed. " +
"Exception:" + throwable.getMessage());
}
});
@ -171,9 +171,8 @@ public class P2PService {
@Override
public void onDisconnect(Reason reason, Connection connection) {
Address peerAddress = connection.getPeerAddress();
if (peerAddress != null)
authenticatedPeerAddresses.remove(peerAddress);
if (connection.isAuthenticated())
authenticatedPeerAddresses.remove(connection.getPeerAddress());
}
@Override
@ -195,11 +194,15 @@ public class P2PService {
});
}
} else if (message instanceof DataSetMessage) {
log.trace("Received AllDataMessage: " + message);
DataSetMessage dataSetMessage = (DataSetMessage) message;
StringBuilder sb = new StringBuilder("Received DataSetMessage:\n\n");
dataSetMessage.set.stream().forEach(e -> sb.append(e.toString() + "\n"));
sb.append("\n");
log.trace(sb.toString());
// we keep that connection open as the bootstrapping peer will use that for the authentication
// as we are not authenticated yet the data adding will not be broadcasted
HashSet<ProtectedData> set = ((DataSetMessage) message).set;
HashSet<ProtectedData> set = dataSetMessage.set;
set.stream().forEach(e -> dataStorage.add(e, connection.getPeerAddress()));
dataReceived();
@ -664,7 +667,7 @@ public class P2PService {
e -> e.onMailboxMessageAdded(decryptedMsgWithPubKey, senderAddress)));
}
} catch (CryptoException e) {
log.trace("Decryption of SealedAndSignedMessage failed. That is expected if the message is not intended for us.");
log.trace("Decryption of SealedAndSignedMessage failed. That is expected if the message is not intended for us. " + e.getMessage());
}
}
}

View File

@ -90,6 +90,7 @@ public class Connection {
lastActivityDate = new Date();
log.trace("\nNew connection created " + this.toString());
connectionListener.onConnection(this);
}
@ -148,10 +149,6 @@ public class Connection {
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public Socket getSocket() {
return socket;
}
@Nullable
public Address getPeerAddress() {
return peerAddress;
@ -170,14 +167,6 @@ public class Connection {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setPeerAddress(Address peerAddress) {
this.peerAddress = peerAddress;
}
///////////////////////////////////////////////////////////////////////////////////////////
// ShutDown
///////////////////////////////////////////////////////////////////////////////////////////
@ -198,6 +187,7 @@ public class Connection {
if (!shutDownInProgress) {
log.info("\n\nShutDown connection:"
+ "\npeerAddress=" + peerAddress
+ "\nobjectId=" + getObjectId()
+ "\nuid=" + getUid()
+ "\nisAuthenticated=" + isAuthenticated
+ "\nsocket.getPort()=" + socket.getPort()
@ -205,9 +195,12 @@ public class Connection {
log.debug("ShutDown " + this.getObjectId());
log.debug("ShutDown connection requested. Connection=" + this.toString());
shutDownInProgress = true;
inputHandlerStopped = true;
if (!stopped) {
stopped = true;
shutDownInProgress = true;
inputHandlerStopped = true;
connectionListener.onDisconnect(ConnectionListener.Reason.SHUT_DOWN, Connection.this);
if (sendCloseConnectionMessage) {
sendMessage(new CloseConnectionMessage());
try {
@ -217,8 +210,6 @@ public class Connection {
Thread.currentThread().interrupt();
}
}
stopped = true;
connectionListener.onDisconnect(ConnectionListener.Reason.SHUT_DOWN, Connection.this);
try {
socket.close();
@ -282,7 +273,7 @@ public class Connection {
@Override
public String toString() {
return "Connection{" +
"OBJECT ID=" + super.toString().split("@")[1] +
"objectId=" + getObjectId() +
", uid=" + uid +
", port=" + port +
", isAuthenticated=" + isAuthenticated +
@ -310,7 +301,7 @@ public class Connection {
try {
log.trace("InputHandler waiting for incoming messages connection=" + Connection.this.getObjectId());
Object rawInputObject = in.readObject();
log.trace("New data arrived at inputHandler of connection=" + Connection.this.getObjectId()
log.trace("New data arrived at inputHandler of connection=" + Connection.this.toString()
+ " rawInputObject " + rawInputObject);
int size = ByteArrayUtils.objectToByteArray(rawInputObject).length;
@ -339,10 +330,12 @@ public class Connection {
if (serializable instanceof Message) {
lastActivityDate = new Date();
Message message = (Message) serializable;
if (message instanceof CloseConnectionMessage)
if (message instanceof CloseConnectionMessage) {
inputHandlerStopped = true;
shutDown(false);
else
} else {
executorService.submit(() -> messageListener.onMessage(message, Connection.this));
}
} else {
reportIllegalRequest(IllegalRequest.InvalidDataType);
}
@ -355,6 +348,9 @@ public class Connection {
reportIllegalRequest(IllegalRequest.MaxSizeExceeded);
}
} catch (IOException | ClassNotFoundException e) {
log.error("Exception at Connection.InputHandler. Connection=" + Connection.this.toString());
log.error("Exception=" + e.getMessage());
e.printStackTrace();
inputHandlerStopped = true;
handleConnectionException(e);
}

View File

@ -24,8 +24,8 @@ import java.util.function.Consumer;
public class LocalhostNetworkNode extends NetworkNode {
private static final Logger log = LoggerFactory.getLogger(LocalhostNetworkNode.class);
private static int simulateTorDelayTorNode = 0;
private static int simulateTorDelayHiddenService = 0;
private static int simulateTorDelayTorNode = 2 * 1000;
private static int simulateTorDelayHiddenService = 2 * 1000;
private Address address;
public static void setSimulateTorDelayTorNode(int simulateTorDelayTorNode) {
@ -94,7 +94,10 @@ public class LocalhostNetworkNode extends NetworkNode {
long ts = System.currentTimeMillis();
log.trace("[simulation] Create TorNode");
if (simulateTorDelayTorNode > 0) Thread.sleep(simulateTorDelayTorNode);
log.trace("\n\n##### TorNode created [simulation]. Took " + (System.currentTimeMillis() - ts) + " ms\n\n");
log.info("\n\n############################################################\n" +
"TorNode created [simulation]:" +
"\nTook " + (System.currentTimeMillis() - ts) + " ms"
+ "\n############################################################\n");
return null;
};
ListenableFuture<TorNode<JavaOnionProxyManager, JavaOnionProxyContext>> future = executorService.submit(task);
@ -114,7 +117,10 @@ public class LocalhostNetworkNode extends NetworkNode {
long ts = System.currentTimeMillis();
log.debug("[simulation] Create hidden service");
if (simulateTorDelayHiddenService > 0) Thread.sleep(simulateTorDelayHiddenService);
log.debug("\n\n##### Hidden service created [simulation]. Took " + (System.currentTimeMillis() - ts) + " ms\n\n");
log.info("\n\n############################################################\n" +
"Hidden service created [simulation]:" +
"\nTook " + (System.currentTimeMillis() - ts) + " ms"
+ "\n############################################################\n");
return null;
};
ListenableFuture<HiddenServiceDescriptor> future = executorService.submit(task);

View File

@ -11,9 +11,11 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import static com.google.common.base.Preconditions.checkNotNull;
@ -22,9 +24,8 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
private static final Logger log = LoggerFactory.getLogger(NetworkNode.class);
protected final int port;
private final Map<Address, Connection> outBoundConnections = new ConcurrentHashMap<>();
private final Map<Address, Connection> inBoundAuthenticatedConnections = new ConcurrentHashMap<>();
private final List<Connection> inBoundTempConnections = new CopyOnWriteArrayList<>();
private final List<Connection> outBoundConnections = new CopyOnWriteArrayList<>();
private final List<Connection> inBoundConnections = new CopyOnWriteArrayList<>();
private final List<MessageListener> messageListeners = new CopyOnWriteArrayList<>();
private final List<ConnectionListener> connectionListeners = new CopyOnWriteArrayList<>();
protected final List<SetupListener> setupListeners = new CopyOnWriteArrayList<>();
@ -58,32 +59,21 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
Callable<Connection> task = () -> {
Thread.currentThread().setName("Outgoing-connection-to-" + peerAddress);
Connection connection = outBoundConnections.get(peerAddress);
Optional<Connection> outboundConnectionOptional = getOutboundConnection(peerAddress);
Connection connection = outboundConnectionOptional.isPresent() ? outboundConnectionOptional.get() : null;
if (connection != null && connection.isStopped()) {
// can happen because of threading...
log.trace("We have a connection which is already stopped in outBoundConnections. Connection.uid=" + connection.getUid());
outBoundConnections.remove(peerAddress);
outBoundConnections.remove(connection);
connection = null;
}
if (connection == null) {
Optional<Connection> connectionOptional = inBoundAuthenticatedConnections.values().stream()
.filter(e -> peerAddress.equals(e.getPeerAddress()))
.findAny();
if (connectionOptional.isPresent())
connection = connectionOptional.get();
Optional<Connection> inboundConnectionOptional = getInboundConnection(peerAddress);
if (inboundConnectionOptional.isPresent()) connection = inboundConnectionOptional.get();
if (connection != null)
log.trace("We have found a connection in inBoundAuthenticatedConnections. Connection.uid=" + connection.getUid());
}
if (connection == null) {
Optional<Connection> connectionOptional = inBoundTempConnections.stream()
.filter(e -> peerAddress.equals(e.getPeerAddress()))
.findAny();
if (connectionOptional.isPresent())
connection = connectionOptional.get();
if (connection != null)
log.trace("We have found a connection in inBoundTempConnections. Connection.uid=" + connection.getUid());
log.trace("We have found a connection in inBoundConnections. Connection.uid=" + connection.getUid());
}
if (connection == null) {
@ -113,7 +103,11 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
NetworkNode.this.onError(throwable);
}
});
outBoundConnections.put(peerAddress, connection);
if (!outBoundConnections.contains(connection))
outBoundConnections.add(connection);
else
log.error("We have already that connection in our list. That must not happen. "
+ outBoundConnections + " / connection=" + connection);
log.info("\n\nNetworkNode created new outbound connection:"
+ "\npeerAddress=" + peerAddress.port
@ -144,6 +138,16 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
return resultFuture;
}
private Optional<Connection> getOutboundConnection(Address peerAddress) {
return outBoundConnections.stream()
.filter(e -> peerAddress.equals(e.getPeerAddress())).findAny();
}
private Optional<Connection> getInboundConnection(Address peerAddress) {
return inBoundConnections.stream()
.filter(e -> peerAddress.equals(e.getPeerAddress())).findAny();
}
public SettableFuture<Connection> sendMessage(Connection connection, Message message) {
final SettableFuture<Connection> resultFuture = SettableFuture.create();
@ -164,9 +168,8 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
}
public Set<Connection> getAllConnections() {
Set<Connection> set = new HashSet<>(inBoundAuthenticatedConnections.values());
set.addAll(outBoundConnections.values());
set.addAll(inBoundTempConnections);
Set<Connection> set = new HashSet<>(inBoundConnections);
set.addAll(outBoundConnections);
return set;
}
@ -226,22 +229,8 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
public void onDisconnect(Reason reason, Connection connection) {
Address peerAddress = connection.getPeerAddress();
log.trace("onDisconnect connection " + connection + ", peerAddress= " + peerAddress);
if (peerAddress != null) {
inBoundAuthenticatedConnections.remove(peerAddress);
outBoundConnections.remove(peerAddress);
} else {
// try to find if we have connection
outBoundConnections.values().stream()
.filter(e -> e.equals(connection))
.findAny()
.ifPresent(e -> outBoundConnections.remove(e.getPeerAddress()));
inBoundAuthenticatedConnections.values().stream()
.filter(e -> e.equals(connection))
.findAny()
.ifPresent(e -> inBoundAuthenticatedConnections.remove(e.getPeerAddress()));
}
inBoundTempConnections.remove(connection);
outBoundConnections.remove(connection);
inBoundConnections.remove(connection);
connectionListeners.stream().forEach(e -> e.onDisconnect(reason, connection));
}
@ -280,28 +269,21 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener
@Override
public void onConnection(Connection connection) {
// we still have not authenticated so put it to the temp list
inBoundTempConnections.add(connection);
if (!inBoundConnections.contains(connection))
inBoundConnections.add(connection);
NetworkNode.this.onConnection(connection);
}
@Override
public void onPeerAddressAuthenticated(Address peerAddress, Connection connection) {
NetworkNode.this.onPeerAddressAuthenticated(peerAddress, connection);
// now we know the the peers address is correct and we add it to inBoundConnections and
// remove it from tempConnections
inBoundAuthenticatedConnections.put(peerAddress, connection);
inBoundTempConnections.remove(connection);
}
@Override
public void onDisconnect(Reason reason, Connection connection) {
Address peerAddress = connection.getPeerAddress();
log.trace("onDisconnect at incoming connection to peerAddress " + peerAddress);
if (peerAddress != null)
inBoundAuthenticatedConnections.remove(peerAddress);
inBoundTempConnections.remove(connection);
inBoundConnections.remove(connection);
NetworkNode.this.onDisconnect(reason, connection);
}

View File

@ -44,7 +44,7 @@ public class TorNetworkNode extends NetworkNode {
private Timer shutDownTimeoutTimer, selfTestTimer, selfTestTimeoutTimer;
private TimerTask selfTestTimeoutTask, selfTestTask;
private AtomicBoolean selfTestRunning = new AtomicBoolean(false);
private int nonce;
private long nonce;
private int errorCounter;
private int restartCounter;
private Runnable shutDownCompleteHandler;
@ -79,7 +79,7 @@ public class TorNetworkNode extends NetworkNode {
selfTestTimeoutTimer.schedule(selfTestTimeoutTask, TIMEOUT);
// might be interrupted by timeout task
if (selfTestRunning.get()) {
nonce = random.nextInt();
nonce = random.nextLong();
log.trace("send msg with nonce " + nonce);
try {
@ -281,7 +281,10 @@ public class TorNetworkNode extends NetworkNode {
TorNode<JavaOnionProxyManager, JavaOnionProxyContext> torNode1 = new TorNode<JavaOnionProxyManager, JavaOnionProxyContext>(
torDir) {
};
log.trace("\n\n##### TorNode created. Took " + (System.currentTimeMillis() - ts) + " ms\n\n");
log.info("\n\n############################################################\n" +
"TorNode created:" +
"\nTook " + (System.currentTimeMillis() - ts) + " ms"
+ "\n############################################################\n");
return torNode1;
};
ListenableFuture<TorNode<JavaOnionProxyManager, JavaOnionProxyContext>> future = executorService.submit(task);
@ -303,7 +306,11 @@ public class TorNetworkNode extends NetworkNode {
long ts = System.currentTimeMillis();
log.debug("Create hidden service");
HiddenServiceDescriptor hiddenServiceDescriptor = torNode.createHiddenService(port);
log.debug("\n\n##### Hidden service created. Address = " + hiddenServiceDescriptor.getFullAddress() + ". Took " + (System.currentTimeMillis() - ts) + " ms\n\n");
log.info("\n\n############################################################\n" +
"Hidden service created:" +
"\nAddress=" + hiddenServiceDescriptor.getFullAddress() +
"\nTook " + (System.currentTimeMillis() - ts) + " ms"
+ "\n############################################################\n");
return hiddenServiceDescriptor;
};

View File

@ -7,9 +7,9 @@ public final class SelfTestMessage implements Message {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Integer nonce;
public final long nonce;
public SelfTestMessage(Integer nonce) {
public SelfTestMessage(long nonce) {
this.nonce = nonce;
}
}

View File

@ -1,26 +1,37 @@
package io.bitsquare.p2p.routing;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.network.Connection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Serializable;
import java.util.Random;
public class Neighbor implements Serializable {
private static final Logger log = LoggerFactory.getLogger(Neighbor.class);
public final Connection connection;
public final Address address;
private int pingNonce;
private long pingNonce;
public Neighbor(Address address) {
this.address = address;
public Neighbor(Connection connection) {
this.connection = connection;
this.address = connection.getPeerAddress();
pingNonce = new Random().nextLong();
}
public void setPingNonce(int pingNonce) {
this.pingNonce = pingNonce;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.defaultReadObject();
pingNonce = new Random().nextLong();
} catch (Throwable t) {
log.trace("Cannot be deserialized." + t.getMessage());
}
}
public int getPingNonce() {
public long getPingNonce() {
return pingNonce;
}

View File

@ -24,7 +24,15 @@ import java.util.stream.Collectors;
public class Routing {
private static final Logger log = LoggerFactory.getLogger(Routing.class);
private static int simulateAuthTorNode = 2 * 1000;
public static void setSimulateAuthTorNode(int simulateAuthTorNode) {
Routing.simulateAuthTorNode = simulateAuthTorNode;
}
private static int MAX_CONNECTIONS = 8;
private static int MAINTENANCE_INTERVAL = new Random().nextInt(15 * 60 * 1000) + 15 * 60 * 1000; // 15-30 min.
private static int PING_AFTER_CONNECTION_INACTIVITY = 5 * 60 * 1000; // 5 min
private long startAuthTs;
public static void setMaxConnections(int maxConnections) {
@ -33,10 +41,10 @@ public class Routing {
private final NetworkNode networkNode;
private final List<Address> seedNodes;
private final Map<Address, Integer> nonceMap = new ConcurrentHashMap<>();
private final Map<Address, Long> nonceMap = new ConcurrentHashMap<>();
private final List<RoutingListener> routingListeners = new CopyOnWriteArrayList<>();
private final Map<Address, Neighbor> connectedNeighbors = new ConcurrentHashMap<>();
private final Map<Address, Neighbor> reportedNeighbors = new ConcurrentHashMap<>();
private final List<Address> reportedNeighborAddresses = new CopyOnWriteArrayList<>();
private final Map<Address, Runnable> authenticationCompleteHandlers = new ConcurrentHashMap<>();
private final Timer maintenanceTimer = new Timer();
private final ExecutorService executorService = Executors.newCachedThreadPool();
@ -72,7 +80,7 @@ public class Routing {
@Override
public void onDisconnect(Reason reason, Connection connection) {
// only removes authenticated nodes
if (connection.getPeerAddress() != null)
if (connection.isAuthenticated())
removeNeighbor(connection.getPeerAddress());
}
@ -99,14 +107,13 @@ public class Routing {
}
});
int maintenanceInterval = new Random().nextInt(15 * 60 * 1000) + 15 * 60 * 1000; // 15-30 min.
maintenanceTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
disconnectOldConnections();
pingNeighbors();
}
}, maintenanceInterval, maintenanceInterval);
}, MAINTENANCE_INTERVAL, MAINTENANCE_INTERVAL);
}
private void disconnectOldConnections() {
@ -128,7 +135,30 @@ public class Routing {
}
private void pingNeighbors() {
log.trace("pingNeighbors");
List<Neighbor> connectedNeighborsList = new ArrayList<>(connectedNeighbors.values());
connectedNeighborsList.stream()
.filter(e -> (new Date().getTime() - e.connection.getLastActivityDate().getTime()) > PING_AFTER_CONNECTION_INACTIVITY)
.forEach(e -> {
SettableFuture<Connection> future = networkNode.sendMessage(e.connection, new PingMessage(e.getPingNonce()));
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
public void onSuccess(Connection connection) {
log.trace("PingMessage sent successfully");
}
@Override
public void onFailure(@NotNull Throwable throwable) {
log.info("PingMessage sending failed " + throwable.getMessage());
removeNeighbor(e.address);
}
});
try {
Thread.sleep(new Random().nextInt(5000) + 5000);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
});
}
@ -146,12 +176,13 @@ public class Routing {
}
}
public void broadcast(BroadcastMessage message, Address sender) {
public void broadcast(BroadcastMessage message, @Nullable Address sender) {
log.trace("Broadcast message to " + connectedNeighbors.values().size() + " neighbors.");
log.trace("message = " + message);
connectedNeighbors.values().parallelStream()
.filter(e -> !e.address.equals(sender))
.forEach(neighbor -> {
log.trace("Broadcast message " + message + " from " + getAddress() + " to " + neighbor.address + ".");
log.trace("Broadcast message from " + getAddress() + " to " + neighbor.address + ".");
SettableFuture<Connection> future = networkNode.sendMessage(neighbor.address, message);
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
@ -184,20 +215,18 @@ public class Routing {
routingListeners.remove(routingListener);
}
public Map<Address, Neighbor> getReportedNeighbors() {
return reportedNeighbors;
}
public Map<Address, Neighbor> getConnectedNeighbors() {
return connectedNeighbors;
}
public Map<Address, Neighbor> getAllNeighbors() {
Map<Address, Neighbor> hashMap = new ConcurrentHashMap<>(reportedNeighbors);
hashMap.putAll(connectedNeighbors);
// Use ArrayList not List as we need it serializable
public ArrayList<Address> getAllNeighborAddresses() {
ArrayList<Address> allNeighborAddresses = new ArrayList<>(reportedNeighborAddresses);
allNeighborAddresses.addAll(connectedNeighbors.values().stream()
.map(e -> e.address).collect(Collectors.toList()));
// remove own address and seed nodes
hashMap.remove(getAddress());
return hashMap;
allNeighborAddresses.remove(getAddress());
return allNeighborAddresses;
}
@ -239,7 +268,7 @@ public class Routing {
alreadyConnected[0] = true;
});
if (!alreadyConnected[0]) {
int nonce = addToMapAndGetNonce(address);
long nonce = addToMapAndGetNonce(address);
SettableFuture<Connection> future = networkNode.sendMessage(address, new RequestAuthenticationMessage(getAddress(), nonce));
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
@ -287,12 +316,17 @@ public class Routing {
// inconsistent state (removal of connection from NetworkNode.authenticatedConnections)
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
try {
if (simulateAuthTorNode > 0) Thread.sleep(simulateAuthTorNode);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
log.trace("processAuthenticationMessage: connection.shutDown complete. RequestAuthenticationMessage from " + peerAddress + " at " + getAddress());
int nonce = addToMapAndGetNonce(peerAddress);
long nonce = addToMapAndGetNonce(peerAddress);
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, new ChallengeMessage(getAddress(), requestAuthenticationMessage.nonce, nonce));
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
@ -324,12 +358,12 @@ public class Routing {
} else if (message instanceof ChallengeMessage) {
ChallengeMessage challengeMessage = (ChallengeMessage) message;
Address peerAddress = challengeMessage.address;
connection.setPeerAddress(peerAddress);
log.trace("ChallengeMessage from " + peerAddress + " at " + getAddress());
HashMap<Address, Long> tempNonceMap = new HashMap<>(nonceMap);
boolean verified = verifyNonceAndAuthenticatePeerAddress(challengeMessage.requesterNonce, peerAddress);
if (verified) {
HashMap<Address, Neighbor> allNeighbors = new HashMap<>(getAllNeighbors());
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, new GetNeighborsMessage(getAddress(), challengeMessage.challengerNonce, allNeighbors));
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress,
new GetNeighborsMessage(getAddress(), challengeMessage.challengerNonce, getAllNeighborAddresses()));
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
public void onSuccess(Connection connection) {
@ -346,6 +380,8 @@ public class Routing {
removeNeighbor(peerAddress);
}
});
} else {
log.warn("verifyNonceAndAuthenticatePeerAddress failed. challengeMessage=" + challengeMessage + " / nonceMap=" + tempNonceMap);
}
} else if (message instanceof GetNeighborsMessage) {
GetNeighborsMessage getNeighborsMessage = (GetNeighborsMessage) message;
@ -355,9 +391,10 @@ public class Routing {
if (verified) {
setAuthenticated(connection, peerAddress);
purgeReportedNeighbors();
HashMap<Address, Neighbor> allNeighbors = new HashMap<>(getAllNeighbors());
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, new NeighborsMessage(allNeighbors));
log.trace("sent NeighborsMessage to " + peerAddress + " from " + getAddress() + " with allNeighbors=" + allNeighbors.values());
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress,
new NeighborsMessage(getAllNeighborAddresses()));
log.trace("sent NeighborsMessage to " + peerAddress + " from " + getAddress()
+ " with allNeighbors=" + getAllNeighborAddresses());
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
public void onSuccess(Connection connection) {
@ -372,19 +409,19 @@ public class Routing {
});
// now we add the reported neighbors to our own set
final HashMap<Address, Neighbor> neighbors = ((GetNeighborsMessage) message).neighbors;
log.trace("Received neighbors: " + neighbors);
ArrayList<Address> neighborAddresses = ((GetNeighborsMessage) message).neighborAddresses;
log.trace("Received neighbors: " + neighborAddresses);
// remove ourselves
neighbors.remove(getAddress());
addToReportedNeighbors(neighbors, connection);
neighborAddresses.remove(getAddress());
addToReportedNeighbors(neighborAddresses, connection);
}
} else if (message instanceof NeighborsMessage) {
log.trace("NeighborsMessage from " + connection.getPeerAddress() + " at " + getAddress());
final HashMap<Address, Neighbor> neighbors = ((NeighborsMessage) message).neighbors;
log.trace("Received neighbors: " + neighbors);
ArrayList<Address> neighborAddresses = ((NeighborsMessage) message).neighborAddresses;
log.trace("Received neighbors: " + neighborAddresses);
// remove ourselves
neighbors.remove(getAddress());
addToReportedNeighbors(neighbors, connection);
neighborAddresses.remove(getAddress());
addToReportedNeighbors(neighborAddresses, connection);
log.info("\n\nAuthenticationComplete\nPeer with address " + connection.getPeerAddress().toString()
+ " authenticated (" + connection.getObjectId() + "). Took "
@ -398,36 +435,42 @@ public class Routing {
}
}
private void addToReportedNeighbors(HashMap<Address, Neighbor> neighbors, Connection connection) {
private void addToReportedNeighbors(ArrayList<Address> neighborAddresses, Connection connection) {
// we disconnect misbehaving nodes trying to send too many neighbors
// reported neighbors include the peers connected neighbors which is normally max. 8 but we give some headroom
// for safety
if (neighbors.size() > 1100) {
if (neighborAddresses.size() > 1100) {
connection.shutDown();
} else {
reportedNeighbors.putAll(neighbors);
reportedNeighborAddresses.addAll(neighborAddresses);
purgeReportedNeighbors();
}
}
private void purgeReportedNeighbors() {
int all = getAllNeighbors().size();
int all = getAllNeighborAddresses().size();
if (all > 1000) {
int diff = all - 100;
ArrayList<Neighbor> reportedNeighborsList = new ArrayList<>(reportedNeighbors.values());
List<Address> list = getNotConnectedNeighborAddresses();
for (int i = 0; i < diff; i++) {
Neighbor neighborToRemove = reportedNeighborsList.remove(new Random().nextInt(reportedNeighborsList.size()));
reportedNeighbors.remove(neighborToRemove.address);
Address neighborToRemove = list.remove(new Random().nextInt(list.size()));
reportedNeighborAddresses.remove(neighborToRemove);
}
}
}
private List<Address> getNotConnectedNeighborAddresses() {
ArrayList<Address> reportedNeighborsList = new ArrayList<>(getAllNeighborAddresses());
connectedNeighbors.values().stream().forEach(e -> reportedNeighborsList.remove(e.address));
return reportedNeighborsList;
}
private void authenticateToNextRandomNeighbor() {
if (getConnectedNeighbors().size() <= MAX_CONNECTIONS) {
Neighbor randomNotConnectedNeighbor = getRandomNotConnectedNeighbor();
if (randomNotConnectedNeighbor != null) {
log.info("We try to build an authenticated connection to a random neighbor. " + randomNotConnectedNeighbor);
authenticateToPeer(randomNotConnectedNeighbor.address, null, () -> authenticateToNextRandomNeighbor());
Address randomNotConnectedNeighborAddress = getRandomNotConnectedNeighborAddress();
if (randomNotConnectedNeighborAddress != null) {
log.info("We try to build an authenticated connection to a random neighbor. " + randomNotConnectedNeighborAddress);
authenticateToPeer(randomNotConnectedNeighborAddress, null, () -> authenticateToNextRandomNeighbor());
} else {
log.info("No more neighbors available for connecting.");
}
@ -442,7 +485,7 @@ public class Routing {
if (authenticationCompleteHandler != null)
authenticationCompleteHandlers.put(address, authenticationCompleteHandler);
int nonce = addToMapAndGetNonce(address);
long nonce = addToMapAndGetNonce(address);
SettableFuture<Connection> future = networkNode.sendMessage(address, new RequestAuthenticationMessage(getAddress(), nonce));
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
@ -459,34 +502,43 @@ public class Routing {
});
}
private int addToMapAndGetNonce(Address address) {
int nonce = new Random().nextInt();
private long addToMapAndGetNonce(Address peerAddress) {
long nonce = new Random().nextLong();
while (nonce == 0) {
nonce = new Random().nextInt();
nonce = new Random().nextLong();
}
nonceMap.put(address, nonce);
log.trace("addToMapAndGetNonce nonceMap=" + nonceMap + " / peerAddress=" + peerAddress);
nonceMap.put(peerAddress, nonce);
return nonce;
}
private boolean verifyNonceAndAuthenticatePeerAddress(int peersNonce, Address peerAddress) {
int nonce = nonceMap.remove(peerAddress);
private boolean verifyNonceAndAuthenticatePeerAddress(long peersNonce, Address peerAddress) {
log.trace("verifyNonceAndAuthenticatePeerAddress nonceMap=" + nonceMap + " / peerAddress=" + peerAddress);
long nonce = nonceMap.remove(peerAddress);
boolean result = nonce == peersNonce;
return result;
}
private void setAuthenticated(Connection connection, Address address) {
log.info("We got the connection from " + getAddress() + " to " + address + " authenticated.");
Neighbor neighbor = new Neighbor(address);
addConnectedNeighbor(address, neighbor);
private void setAuthenticated(Connection connection, Address peerAddress) {
log.info("\n\n############################################################\n" +
"We are authenticated to:" +
"\nconnection=" + connection
+ "\nmyAddress=" + getAddress()
+ "\npeerAddress= " + peerAddress
+ "\n############################################################\n");
connection.onAuthenticationComplete(peerAddress, connection);
Neighbor neighbor = new Neighbor(connection);
addConnectedNeighbor(peerAddress, neighbor);
connection.onAuthenticationComplete(address, connection);
routingListeners.stream().forEach(e -> e.onConnectionAuthenticated(connection));
log.debug("\n### setAuthenticated post connection " + connection);
}
private Neighbor getRandomNotConnectedNeighbor() {
List<Neighbor> list = reportedNeighbors.values().stream()
.filter(e -> !connectedNeighbors.values().contains(e))
.collect(Collectors.toList());
private Address getRandomNotConnectedNeighborAddress() {
List<Address> list = getNotConnectedNeighborAddresses();
if (list.size() > 0) {
Collections.shuffle(list);
return list.get(0);
@ -532,16 +584,17 @@ public class Routing {
// Neighbors
///////////////////////////////////////////////////////////////////////////////////////////
private void removeNeighbor(Address address) {
reportedNeighbors.remove(address);
private void removeNeighbor(@Nullable Address peerAddress) {
reportedNeighborAddresses.remove(peerAddress);
Neighbor disconnectedNeighbor;
disconnectedNeighbor = connectedNeighbors.remove(address);
disconnectedNeighbor = connectedNeighbors.remove(peerAddress);
if (disconnectedNeighbor != null)
UserThread.execute(() -> routingListeners.stream().forEach(e -> e.onNeighborRemoved(address)));
UserThread.execute(() -> routingListeners.stream().forEach(e -> e.onNeighborRemoved(peerAddress)));
nonceMap.remove(address);
log.trace("removeNeighbor nonceMap=" + nonceMap + " / peerAddress=" + peerAddress);
nonceMap.remove(peerAddress);
}
private void addConnectedNeighbor(Address address, Neighbor neighbor) {
@ -577,9 +630,9 @@ public class Routing {
}
public void printReportedNeighborsMap() {
StringBuilder result = new StringBuilder("\nReported neighbors for node " + getAddress() + ":");
reportedNeighbors.values().stream().forEach(e -> {
result.append("\n\t" + e.address);
StringBuilder result = new StringBuilder("\nReported neighborAddresses for node " + getAddress() + ":");
reportedNeighborAddresses.stream().forEach(e -> {
result.append("\n\t" + e);
});
result.append("\n");
log.info(result.toString());

View File

@ -8,10 +8,10 @@ public final class ChallengeMessage implements AuthenticationMessage {
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Address address;
public final int requesterNonce;
public final int challengerNonce;
public final long requesterNonce;
public final long challengerNonce;
public ChallengeMessage(Address address, int requesterNonce, int challengerNonce) {
public ChallengeMessage(Address address, long requesterNonce, long challengerNonce) {
this.address = address;
this.requesterNonce = requesterNonce;
this.challengerNonce = challengerNonce;

View File

@ -2,22 +2,21 @@ package io.bitsquare.p2p.routing.messages;
import io.bitsquare.app.Version;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.routing.Neighbor;
import java.util.HashMap;
import java.util.ArrayList;
public final class GetNeighborsMessage implements AuthenticationMessage {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Address address;
public final int challengerNonce;
public final HashMap<Address, Neighbor> neighbors;
public final long challengerNonce;
public final ArrayList<Address> neighborAddresses;
public GetNeighborsMessage(Address address, int challengerNonce, HashMap<Address, Neighbor> neighbors) {
public GetNeighborsMessage(Address address, long challengerNonce, ArrayList<Address> neighborAddresses) {
this.address = address;
this.challengerNonce = challengerNonce;
this.neighbors = neighbors;
this.neighborAddresses = neighborAddresses;
}
@Override
@ -25,7 +24,7 @@ public final class GetNeighborsMessage implements AuthenticationMessage {
return "GetNeighborsMessage{" +
"address=" + address +
", challengerNonce=" + challengerNonce +
", neighbors=" + neighbors +
", neighborAddresses=" + neighborAddresses +
'}';
}
}

View File

@ -2,23 +2,22 @@ package io.bitsquare.p2p.routing.messages;
import io.bitsquare.app.Version;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.routing.Neighbor;
import java.util.HashMap;
import java.util.ArrayList;
public final class NeighborsMessage implements AuthenticationMessage {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final HashMap<Address, Neighbor> neighbors;
public final ArrayList<Address> neighborAddresses;
public NeighborsMessage(HashMap<Address, Neighbor> neighbors) {
this.neighbors = neighbors;
public NeighborsMessage(ArrayList<Address> neighborAddresses) {
this.neighborAddresses = neighborAddresses;
}
@Override
public String toString() {
return "NeighborsMessage{" + "neighbors=" + neighbors + '}';
return "NeighborsMessage{" + "neighborAddresses=" + neighborAddresses + '}';
}
}

View File

@ -6,9 +6,9 @@ public final class PingMessage implements MaintenanceMessage {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final int nonce;
public final long nonce;
public PingMessage(int nonce) {
public PingMessage(long nonce) {
this.nonce = nonce;
}

View File

@ -6,9 +6,9 @@ public final class PongMessage implements MaintenanceMessage {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final int nonce;
public final long nonce;
public PongMessage(int nonce) {
public PongMessage(long nonce) {
this.nonce = nonce;
}

View File

@ -8,9 +8,9 @@ public final class RequestAuthenticationMessage implements AuthenticationMessage
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Address address;
public final int nonce;
public final long nonce;
public RequestAuthenticationMessage(Address address, int nonce) {
public RequestAuthenticationMessage(Address address, long nonce) {
this.address = address;
this.nonce = nonce;
}

View File

@ -15,6 +15,7 @@ import io.bitsquare.storage.Storage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
import java.math.BigInteger;
import java.security.KeyPair;
@ -69,6 +70,7 @@ public class ProtectedExpirableDataStorage {
}
} else {
log.warn("Connection is not authenticated yet. We don't accept storage operations form non-authenticated nodes.");
log.warn("Connection = " + connection);
connection.reportIllegalRequest(IllegalRequest.NotAuthenticated);
}
}
@ -103,7 +105,7 @@ public class ProtectedExpirableDataStorage {
this.authenticated = authenticated;
}
public boolean add(ProtectedData protectedData, Address sender) {
public boolean add(ProtectedData protectedData, @Nullable Address sender) {
BigInteger hashOfPayload = getHashAsBigInteger(protectedData.expirablePayload);
boolean containsKey = map.containsKey(hashOfPayload);
boolean result = checkPublicKeys(protectedData, true)
@ -119,9 +121,10 @@ public class ProtectedExpirableDataStorage {
log.trace("Data added to our map and it will be broadcasted to our neighbors.");
UserThread.execute(() -> hashMapChangedListeners.stream().forEach(e -> e.onAdded(protectedData)));
StringBuilder sb = new StringBuilder("\n\nSet after addProtectedExpirableData:\n");
map.values().stream().forEach(e -> sb.append(e.toString() + "\n\n"));
sb.append("\n\n");
StringBuilder sb = new StringBuilder("\n\n----------------------------------------------------\n" +
"Data set after addProtectedExpirableData:");
map.values().stream().forEach(e -> sb.append("\n\n").append(e.toString()));
sb.append("\n----------------------------------------------------\n\n");
log.trace(sb.toString());
if (!containsKey)
@ -130,12 +133,12 @@ public class ProtectedExpirableDataStorage {
sequenceNumberMap.put(hashOfPayload, protectedData.sequenceNumber);
storage.queueUpForSave();
} else {
log.debug("add failed");
log.trace("add failed");
}
return result;
}
public boolean remove(ProtectedData protectedData, Address sender) {
public boolean remove(ProtectedData protectedData, @Nullable Address sender) {
BigInteger hashOfPayload = getHashAsBigInteger(protectedData.expirablePayload);
boolean containsKey = map.containsKey(hashOfPayload);
if (!containsKey) log.debug("Remove data ignored as we don't have an entry for that data.");
@ -159,7 +162,7 @@ public class ProtectedExpirableDataStorage {
return result;
}
public boolean removeMailboxData(ProtectedMailboxData protectedMailboxData, Address sender) {
public boolean removeMailboxData(ProtectedMailboxData protectedMailboxData, @Nullable Address sender) {
BigInteger hashOfData = getHashAsBigInteger(protectedMailboxData.expirablePayload);
boolean containsKey = map.containsKey(hashOfData);
if (!containsKey) log.debug("Remove data ignored as we don't have an entry for that data.");
@ -245,7 +248,7 @@ public class ProtectedExpirableDataStorage {
int newSequenceNumber = data.sequenceNumber;
Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData);
if (sequenceNumberMap.containsKey(hashOfData) && newSequenceNumber <= storedSequenceNumber) {
log.warn("Sequence number is invalid. newSequenceNumber="
log.trace("Sequence number is invalid. newSequenceNumber="
+ newSequenceNumber + " / storedSequenceNumber=" + storedSequenceNumber);
return false;
} else {
@ -313,7 +316,7 @@ public class ProtectedExpirableDataStorage {
}
private void broadcast(BroadcastMessage message, Address sender) {
private void broadcast(BroadcastMessage message, @Nullable Address sender) {
if (authenticated) {
routing.broadcast(message, sender);
log.trace("Broadcast message " + message);

View File

@ -26,6 +26,7 @@ import io.bitsquare.common.util.Utilities;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.p2p.messaging.MailboxMessage;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@ -38,6 +39,7 @@ import java.io.File;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.cert.CertificateException;
import static org.junit.Assert.assertEquals;
@ -50,10 +52,13 @@ public class EncryptionServiceTests {
private PubKeyRing pubKeyRing;
private KeyRing keyRing;
private File dir = new File("/tmp/bitsquare_tests");
private File dir;
@Before
public void setup() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, CryptoException {
Security.addProvider(new BouncyCastleProvider());
dir = File.createTempFile("temp_tests", "");
dir.delete();
dir.mkdir();
KeyStorage keyStorage = new KeyStorage(dir);
keyRing = new KeyRing(keyStorage);

View File

@ -13,6 +13,7 @@ import io.bitsquare.p2p.seed.SeedNode;
import io.bitsquare.p2p.storage.data.DataAndSeqNr;
import io.bitsquare.p2p.storage.data.ProtectedData;
import io.bitsquare.p2p.storage.mocks.MockData;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -40,16 +41,27 @@ public class P2PServiceTest {
private EncryptionService encryptionService1, encryptionService2, encryptionService3;
private P2PService p2PService1, p2PService2, p2PService3;
private SeedNode seedNode1, seedNode2, seedNode3;
private File dir1, dir2, dir3;
@Before
public void setup() throws InterruptedException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, CryptoException {
Security.addProvider(new BouncyCastleProvider());
dir1 = File.createTempFile("temp_tests1", "");
dir1.delete();
dir1.mkdir();
dir2 = File.createTempFile("temp_tests2", "");
dir2.delete();
dir2.mkdir();
dir3 = File.createTempFile("temp_tests3", "");
dir3.delete();
dir3.mkdir();
LocalhostNetworkNode.setSimulateTorDelayTorNode(10);
LocalhostNetworkNode.setSimulateTorDelayHiddenService(100);
Routing.setMaxConnections(8);
keyRing1 = new KeyRing(new KeyStorage(new File("temp_keyStorage1")));
keyRing2 = new KeyRing(new KeyStorage(new File("temp_keyStorage2")));
keyRing3 = new KeyRing(new KeyStorage(new File("temp_keyStorage3")));
keyRing1 = new KeyRing(new KeyStorage(dir1));
keyRing2 = new KeyRing(new KeyStorage(dir2));
keyRing3 = new KeyRing(new KeyStorage(dir3));
encryptionService1 = new EncryptionService(keyRing1);
encryptionService2 = new EncryptionService(keyRing2);
encryptionService3 = new EncryptionService(keyRing3);

View File

@ -2,12 +2,15 @@ package io.bitsquare.p2p.network;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.routing.messages.RequestAuthenticationMessage;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.security.Security;
import java.util.concurrent.CountDownLatch;
// TorNode created. Took 6 sec.
@ -17,6 +20,12 @@ import java.util.concurrent.CountDownLatch;
public class LocalhostNetworkNodeTest {
private static final Logger log = LoggerFactory.getLogger(LocalhostNetworkNodeTest.class);
@Before
public void setup() {
Security.addProvider(new BouncyCastleProvider());
}
@Test
public void testMessage() throws InterruptedException, IOException {
CountDownLatch msgLatch = new CountDownLatch(2);

View File

@ -5,6 +5,8 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.mocks.MockMessage;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
@ -12,6 +14,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.security.Security;
import java.util.concurrent.CountDownLatch;
// TorNode created. Took 6 sec.
@ -22,6 +25,11 @@ public class TorNetworkNodeTest {
private static final Logger log = LoggerFactory.getLogger(TorNetworkNodeTest.class);
private CountDownLatch latch;
@Before
public void setup() {
Security.addProvider(new BouncyCastleProvider());
}
@Test
public void testTorNodeBeforeSecondReady() throws InterruptedException, IOException {
latch = new CountDownLatch(1);

View File

@ -107,7 +107,7 @@ public class RoutingTest {
P2PService p2PService1 = seedNode1.getP2PService();
latch.await();
Thread.sleep(500);
Assert.assertEquals(0, p2PService1.getRouting().getAllNeighbors().size());
Assert.assertEquals(0, p2PService1.getRouting().getAllNeighborAddresses().size());
}
@Test
@ -180,8 +180,8 @@ public class RoutingTest {
});
P2PService p2PService2 = seedNode2.getP2PService();
latch.await();
Assert.assertEquals(1, p2PService1.getRouting().getAllNeighbors().size());
Assert.assertEquals(1, p2PService2.getRouting().getAllNeighbors().size());
Assert.assertEquals(1, p2PService1.getRouting().getAllNeighborAddresses().size());
Assert.assertEquals(1, p2PService2.getRouting().getAllNeighborAddresses().size());
}
// @Test

View File

@ -15,6 +15,7 @@ import io.bitsquare.p2p.storage.data.ExpirableMailboxPayload;
import io.bitsquare.p2p.storage.data.ProtectedData;
import io.bitsquare.p2p.storage.data.ProtectedMailboxData;
import io.bitsquare.p2p.storage.mocks.MockData;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -44,13 +45,24 @@ public class ProtectedDataStorageTest {
private KeyRing keyRing1, keyRing2;
private MockData mockData;
private int sleepTime = 100;
private File dir1;
private File dir2;
@Before
public void setup() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
Security.addProvider(new BouncyCastleProvider());
dir1 = File.createTempFile("temp_tests1", "");
dir1.delete();
dir1.mkdir();
dir2 = File.createTempFile("temp_tests2", "");
dir2.delete();
dir2.mkdir();
UserThread.executor = Executors.newSingleThreadExecutor();
ProtectedExpirableDataStorage.CHECK_TTL_INTERVAL = 10 * 60 * 1000;
keyRing1 = new KeyRing(new KeyStorage(new File("temp_keyStorage1")));
keyRing1 = new KeyRing(new KeyStorage(dir1));
storageSignatureKeyPair1 = keyRing1.getSignatureKeyPair();
encryptionService1 = new EncryptionService(keyRing1);
networkNode1 = TestUtils.getAndStartSeedNode(8001, encryptionService1, keyRing1, useClearNet, seedNodes).getP2PService().getNetworkNode();
@ -58,7 +70,7 @@ public class ProtectedDataStorageTest {
dataStorage1 = new ProtectedExpirableDataStorage(routing1, new File("dummy"));
// for mailbox
keyRing2 = new KeyRing(new KeyStorage(new File("temp_keyStorage2")));
keyRing2 = new KeyRing(new KeyStorage(dir2));
storageSignatureKeyPair2 = keyRing2.getSignatureKeyPair();
encryptionService2 = new EncryptionService(keyRing2);
@ -148,11 +160,18 @@ public class ProtectedDataStorageTest {
dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.remove(dataToRemove, null));
// add to empty map, any seq nr. -> ok
newSequenceNumber = 2;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.add(dataToAdd, null));
// add with updated seq nr below previous -> failure
newSequenceNumber = 1;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertFalse(dataStorage1.add(dataToAdd, null));
// add with updated seq nr over previous -> ok