Skip to content

Commit

Permalink
Add monero connections manager
Browse files Browse the repository at this point in the history
  • Loading branch information
LumnitzF authored and woodser committed Jan 28, 2022
1 parent ed13047 commit a3586fd
Show file tree
Hide file tree
Showing 18 changed files with 1,230 additions and 33 deletions.
50 changes: 50 additions & 0 deletions core/src/main/java/bisq/core/api/CoreAccountService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package bisq.core.api;

import javax.inject.Singleton;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

/**
* @deprecated Should be replaced by actual implementation once it is available
*/
@Singleton
@Deprecated
public class CoreAccountService {


private static final String DEFAULT_PASSWORD = "abctesting123";

private String password = DEFAULT_PASSWORD;

private final List<PasswordChangeListener> listeners = new CopyOnWriteArrayList<>();


public String getPassword() {
return password;
}

public void setPassword(String newPassword) {
String oldPassword = password;
password = newPassword;
notifyListenerAboutPasswordChange(oldPassword, newPassword);
}

public void addPasswordChangeListener(PasswordChangeListener listener) {
Objects.requireNonNull(listener, "listener");
listeners.add(listener);
}

private void notifyListenerAboutPasswordChange(String oldPassword, String newPassword) {
for (PasswordChangeListener listener : listeners) {
listener.onPasswordChange(oldPassword, newPassword);
}
}

public interface PasswordChangeListener {

void onPasswordChange(String oldPassword, String newPassword);

}
}
58 changes: 57 additions & 1 deletion core/src/main/java/bisq/core/api/CoreApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@



import monero.common.MoneroRpcConnection;
import monero.wallet.model.MoneroDestination;
import monero.wallet.model.MoneroTxWallet;

Expand All @@ -81,6 +82,7 @@ public class CoreApi {
private final CoreWalletsService walletsService;
private final TradeStatisticsManager tradeStatisticsManager;
private final CoreNotificationService notificationService;
private final CoreMoneroConnectionsService coreMoneroConnectionsService;

@Inject
public CoreApi(Config config,
Expand All @@ -92,7 +94,8 @@ public CoreApi(Config config,
CoreTradesService coreTradesService,
CoreWalletsService walletsService,
TradeStatisticsManager tradeStatisticsManager,
CoreNotificationService notificationService) {
CoreNotificationService notificationService,
CoreMoneroConnectionsService coreMoneroConnectionsService) {
this.config = config;
this.coreDisputeAgentsService = coreDisputeAgentsService;
this.coreHelpService = coreHelpService;
Expand All @@ -103,6 +106,7 @@ public CoreApi(Config config,
this.walletsService = walletsService;
this.tradeStatisticsManager = tradeStatisticsManager;
this.notificationService = notificationService;
this.coreMoneroConnectionsService = coreMoneroConnectionsService;
}

@SuppressWarnings("SameReturnValue")
Expand Down Expand Up @@ -398,4 +402,56 @@ public List<TradeStatistics3> getTradeStatistics() {
public int getNumConfirmationsForMostRecentTransaction(String addressString) {
return walletsService.getNumConfirmationsForMostRecentTransaction(addressString);
}

///////////////////////////////////////////////////////////////////////////////////////////
// Monero Connections
///////////////////////////////////////////////////////////////////////////////////////////

public void addMoneroConnection(MoneroRpcConnection connection) {
coreMoneroConnectionsService.addConnection(connection);
}

public void removeMoneroConnection(String connectionUri) {
coreMoneroConnectionsService.removeConnection(connectionUri);
}

public MoneroRpcConnection getMoneroConnection() {
return coreMoneroConnectionsService.getConnection();
}

public List<MoneroRpcConnection> getMoneroConnections() {
return coreMoneroConnectionsService.getConnections();
}

public void setMoneroConnection(String connectionUri) {
coreMoneroConnectionsService.setConnection(connectionUri);
}

public void setMoneroConnection(MoneroRpcConnection connection) {
coreMoneroConnectionsService.setConnection(connection);
}

public MoneroRpcConnection checkMoneroConnection() {
return coreMoneroConnectionsService.checkConnection();
}

public List<MoneroRpcConnection> checkMoneroConnections() {
return coreMoneroConnectionsService.checkConnections();
}

public void startCheckingMoneroConnection(Long refreshPeriod) {
coreMoneroConnectionsService.startCheckingConnection(refreshPeriod);
}

public void stopCheckingMoneroConnection() {
coreMoneroConnectionsService.stopCheckingConnection();
}

public MoneroRpcConnection getBestAvailableMoneroConnection() {
return coreMoneroConnectionsService.getBestAvailableConnection();
}

public void setMoneroConnectionAutoSwitch(boolean autoSwitch) {
coreMoneroConnectionsService.setAutoSwitch(autoSwitch);
}
}
162 changes: 162 additions & 0 deletions core/src/main/java/bisq/core/api/CoreMoneroConnectionsService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package bisq.core.api;

import bisq.core.btc.model.EncryptedConnectionList;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import monero.common.MoneroConnectionManager;
import monero.common.MoneroConnectionManagerListener;
import monero.common.MoneroRpcConnection;

@Slf4j
@Singleton
public class CoreMoneroConnectionsService {

// TODO: this connection manager should update app status, don't poll in WalletsSetup every 30 seconds
private static final long DEFAULT_REFRESH_PERIOD = 15_000L; // check the connection every 15 seconds per default

// TODO (woodser): support each network type, move to config, remove localhost authentication
private static final List<MoneroRpcConnection> DEFAULT_CONNECTIONS = Arrays.asList(
new MoneroRpcConnection("http://localhost:38081", "superuser", "abctesting123").setPriority(1), // localhost is first priority
new MoneroRpcConnection("http://haveno.exchange:38081", "", "").setPriority(2)
);

private final Object lock = new Object();
private final MoneroConnectionManager connectionManager;
private final EncryptedConnectionList connectionList;

@Inject
public CoreMoneroConnectionsService(MoneroConnectionManager connectionManager,
EncryptedConnectionList connectionList) {
this.connectionManager = connectionManager;
this.connectionList = connectionList;
}

public void initialize() {
synchronized (lock) {

// load connections
connectionList.getConnections().forEach(connectionManager::addConnection);

// add default connections
for (MoneroRpcConnection connection : DEFAULT_CONNECTIONS) {
if (connectionList.hasConnection(connection.getUri())) continue;
addConnection(connection);
}

// restore last used connection
connectionList.getCurrentConnectionUri().ifPresentOrElse(connectionManager::setConnection, () -> {
connectionManager.setConnection(DEFAULT_CONNECTIONS.get(0).getUri()); // default to localhost
});

// restore configuration
connectionManager.setAutoSwitch(connectionList.getAutoSwitch());
long refreshPeriod = connectionList.getRefreshPeriod();
if (refreshPeriod > 0) connectionManager.startCheckingConnection(refreshPeriod);
else if (refreshPeriod == 0) connectionManager.startCheckingConnection(DEFAULT_REFRESH_PERIOD);
else checkConnection();

// register connection change listener
connectionManager.addListener(this::onConnectionChanged);
}
}

private void onConnectionChanged(MoneroRpcConnection currentConnection) {
synchronized (lock) {
if (currentConnection == null) {
connectionList.setCurrentConnectionUri(null);
} else {
connectionList.removeConnection(currentConnection.getUri());
connectionList.addConnection(currentConnection);
connectionList.setCurrentConnectionUri(currentConnection.getUri());
}
}
}

public void addConnectionListener(MoneroConnectionManagerListener listener) {
synchronized (lock) {
connectionManager.addListener(listener);
}
}

public void addConnection(MoneroRpcConnection connection) {
synchronized (lock) {
connectionList.addConnection(connection);
connectionManager.addConnection(connection);
}
}

public void removeConnection(String uri) {
synchronized (lock) {
connectionList.removeConnection(uri);
connectionManager.removeConnection(uri);
}
}

public MoneroRpcConnection getConnection() {
synchronized (lock) {
return connectionManager.getConnection();
}
}

public List<MoneroRpcConnection> getConnections() {
synchronized (lock) {
return connectionManager.getConnections();
}
}

public void setConnection(String connectionUri) {
synchronized (lock) {
connectionManager.setConnection(connectionUri); // listener will update connection list
}
}

public void setConnection(MoneroRpcConnection connection) {
synchronized (lock) {
connectionManager.setConnection(connection); // listener will update connection list
}
}

public MoneroRpcConnection checkConnection() {
synchronized (lock) {
connectionManager.checkConnection();
return getConnection();
}
}

public List<MoneroRpcConnection> checkConnections() {
synchronized (lock) {
connectionManager.checkConnections();
return getConnections();
}
}

public void startCheckingConnection(Long refreshPeriod) {
synchronized (lock) {
connectionManager.startCheckingConnection(refreshPeriod == null ? DEFAULT_REFRESH_PERIOD : refreshPeriod);
connectionList.setRefreshPeriod(refreshPeriod);
}
}

public void stopCheckingConnection() {
synchronized (lock) {
connectionManager.stopCheckingConnection();
connectionList.setRefreshPeriod(-1L);
}
}

public MoneroRpcConnection getBestAvailableConnection() {
synchronized (lock) {
return connectionManager.getBestAvailableConnection();
}
}

public void setAutoSwitch(boolean autoSwitch) {
synchronized (lock) {
connectionManager.setAutoSwitch(autoSwitch);
connectionList.setAutoSwitch(autoSwitch);
}
}
}
40 changes: 40 additions & 0 deletions core/src/main/java/bisq/core/api/model/EncryptedConnection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package bisq.core.api.model;

import bisq.common.proto.persistable.PersistablePayload;

import com.google.protobuf.ByteString;

import lombok.Builder;
import lombok.Value;


@Value
@Builder(toBuilder = true)
public class EncryptedConnection implements PersistablePayload {

String uri;
String username;
byte[] encryptedPassword;
byte[] encryptionSalt;
int priority;

@Override
public protobuf.EncryptedConnection toProtoMessage() {
return protobuf.EncryptedConnection.newBuilder()
.setUri(uri)
.setUsername(username)
.setEncryptedPassword(ByteString.copyFrom(encryptedPassword))
.setEncryptionSalt(ByteString.copyFrom(encryptionSalt))
.setPriority(priority)
.build();
}

public static EncryptedConnection fromProto(protobuf.EncryptedConnection encryptedConnection) {
return new EncryptedConnection(
encryptedConnection.getUri(),
encryptedConnection.getUsername(),
encryptedConnection.getEncryptedPassword().toByteArray(),
encryptedConnection.getEncryptionSalt().toByteArray(),
encryptedConnection.getPriority());
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/bisq/core/app/CoreModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.coin.ImmutableCoinFormatter;
import bisq.core.xmr.connection.MoneroConnectionModule;

import bisq.network.crypto.EncryptionServiceModule;
import bisq.network.p2p.P2PModule;
Expand Down Expand Up @@ -91,6 +92,7 @@ protected void configure() {
install(new AlertModule(config));
install(new FilterModule(config));
install(new CorePresentationModule(config));
install(new MoneroConnectionModule(config));
bind(PubKeyRing.class).toProvider(PubKeyRingProvider.class);
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/bisq/core/btc/BitcoinModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package bisq.core.btc;

import bisq.core.btc.model.AddressEntryList;
import bisq.core.btc.model.EncryptedConnectionList;
import bisq.core.btc.model.XmrAddressEntryList;
import bisq.core.btc.nodes.BtcNodes;
import bisq.core.btc.setup.RegTestHost;
Expand Down Expand Up @@ -83,6 +84,7 @@ protected void configure() {

bind(AddressEntryList.class).in(Singleton.class);
bind(XmrAddressEntryList.class).in(Singleton.class);
bind(EncryptedConnectionList.class).in(Singleton.class);
bind(WalletsSetup.class).in(Singleton.class);
bind(XmrWalletService.class).in(Singleton.class);
bind(BtcWalletService.class).in(Singleton.class);
Expand Down
Loading

0 comments on commit a3586fd

Please sign in to comment.