mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 07:15:54 -04:00
added jars, fixed tests
This commit is contained in:
parent
3711519e3a
commit
c5ee2c9186
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
23
core/pom.xml
23
core/pom.xml
@ -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>
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -68,7 +68,6 @@ class MarketViewModel extends ActivatableViewModel {
|
||||
protected void activate() {
|
||||
offerBookListItems.addListener(listChangeListener);
|
||||
offerBook.fillOfferBookListItems();
|
||||
//updateChartData(offerBookListItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
BIN
network/libs/java-0.0.3-SNAPSHOT.jar
Normal file
BIN
network/libs/java-0.0.3-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
network/libs/universal-0.0.3-SNAPSHOT.jar
Normal file
BIN
network/libs/universal-0.0.3-SNAPSHOT.jar
Normal file
Binary file not shown.
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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 + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user