bwt preferences and connection handling improvements

This commit is contained in:
Craig Raw 2021-01-12 13:24:11 +02:00
parent 6637ea09bf
commit d847da9d61
10 changed files with 100 additions and 40 deletions

View file

@ -1268,11 +1268,13 @@ public class AppController implements Initializable {
@Subscribe
public void bwtBootStatus(BwtBootStatusEvent event) {
serverToggle.setDisable(true);
statusUpdated(new StatusEvent(event.getStatus()));
}
@Subscribe
public void bwtSyncStatus(BwtSyncStatusEvent event) {
serverToggle.setDisable(false);
if((AppServices.isConnecting() || AppServices.isConnected()) && !event.isCompleted()) {
statusUpdated(new StatusEvent(event.getStatus()));
}
@ -1280,11 +1282,25 @@ public class AppController implements Initializable {
@Subscribe
public void bwtScanStatus(BwtScanStatusEvent event) {
serverToggle.setDisable(true);
if((AppServices.isConnecting() || AppServices.isConnected()) && !event.isCompleted()) {
statusUpdated(new StatusEvent(event.getStatus()));
}
}
@Subscribe
public void bwtReadyStatus(BwtReadyStatusEvent event) {
serverToggle.setDisable(false);
}
@Subscribe
public void disconnection(DisconnectionEvent event) {
serverToggle.setDisable(false);
if(!AppServices.isConnecting() && !AppServices.isConnected() && !statusBar.getText().startsWith("Connection error")) {
statusUpdated(new StatusEvent("Disconnected"));
}
}
@Subscribe
public void newBlock(NewBlockEvent event) {
setServerToggleTooltip(event.getHeight());

View file

@ -108,7 +108,7 @@ public class AppServices {
service.cancel();
}
if(service.getState() == Worker.State.CANCELLED) {
if(service.getState() == Worker.State.CANCELLED || service.getState() == Worker.State.FAILED) {
service.reset();
}
@ -171,6 +171,8 @@ public class AppServices {
});
connectionService.setOnSucceeded(successEvent -> {
connectionService.setRestartOnFailure(true);
onlineProperty.removeListener(onlineServicesListener);
onlineProperty.setValue(true);
onlineProperty.addListener(onlineServicesListener);
@ -183,6 +185,10 @@ public class AppServices {
//Close connection here to create a new transport next time we try
connectionService.resetConnection();
if(failEvent.getSource().getException() instanceof ServerConfigException) {
connectionService.setRestartOnFailure(false);
}
onlineProperty.removeListener(onlineServicesListener);
onlineProperty.setValue(false);
onlineProperty.addListener(onlineServicesListener);
@ -303,7 +309,7 @@ public class AppServices {
}
public static boolean isConnecting() {
return onlineProperty.get() && get().connectionService.isConnecting();
return get().connectionService != null && get().connectionService.isConnecting();
}
public static boolean isConnected() {

View file

@ -2,7 +2,8 @@ package com.sparrowwallet.sparrow.event;
/**
* Empty class used to notify the bwt has shut down.
* Note this extends from DisconnectionEvent, which is the more general event fired on any type of disconnection.
*/
public class BwtShutdownEvent {
public class BwtShutdownEvent extends DisconnectionEvent {
}

View file

@ -0,0 +1,8 @@
package com.sparrowwallet.sparrow.event;
/**
* Empty class used to signal that the server has been disconnected from.
*/
public class DisconnectionEvent {
}

View file

@ -129,6 +129,7 @@ public class Bwt {
}
NativeBwtDaemon.shutdown(shutdownPtr);
this.terminating = false;
this.ready = false;
this.shutdownPtr = null;
Platform.runLater(() -> EventManager.get().post(new BwtShutdownEvent()));

View file

@ -10,6 +10,7 @@ import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.protocol.*;
import com.sparrowwallet.drongo.wallet.*;
import com.sparrowwallet.sparrow.AppServices;
import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.event.*;
import com.sparrowwallet.sparrow.io.Config;
import com.sparrowwallet.sparrow.wallet.SendController;
@ -54,7 +55,7 @@ public class ElectrumServer {
if(Config.get().getServerType() == ServerType.BITCOIN_CORE) {
if(bwtElectrumServer == null) {
throw new ServerException("Could not connect to Bitcoin Core RPC");
throw new ServerConfigException("Could not connect to Bitcoin Core RPC");
}
electrumServer = bwtElectrumServer;
} else if(Config.get().getServerType() == ServerType.ELECTRUM_SERVER) {
@ -64,16 +65,16 @@ public class ElectrumServer {
}
if(electrumServer == null) {
throw new ServerException("Electrum server URL not specified");
throw new ServerConfigException("Electrum server URL not specified");
}
if(electrumServerCert != null && !electrumServerCert.exists()) {
throw new ServerException("Electrum server certificate file not found");
throw new ServerConfigException("Electrum server certificate file not found");
}
Protocol protocol = Protocol.getProtocol(electrumServer);
if(protocol == null) {
throw new ServerException("Electrum server URL must start with " + Protocol.TCP.toUrlString() + " or " + Protocol.SSL.toUrlString());
throw new ServerConfigException("Electrum server URL must start with " + Protocol.TCP.toUrlString() + " or " + Protocol.SSL.toUrlString());
}
HostAndPort server = protocol.getServerHostAndPort(electrumServer);
@ -93,7 +94,7 @@ public class ElectrumServer {
}
}
} catch (Exception e) {
throw new ServerException(e);
throw new ServerConfigException(e);
}
}
@ -795,18 +796,6 @@ public class ElectrumServer {
ElectrumServer electrumServer = new ElectrumServer();
if(Config.get().getServerType() == ServerType.BITCOIN_CORE) {
if(bwt.isTerminating()) {
try {
bwtStartLock.lock();
bwtStartCondition.await();
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
return null;
} finally {
bwtStartLock.unlock();
}
}
if(!bwt.isRunning()) {
Bwt.ConnectionService bwtConnectionService = bwt.getConnectionService(subscribe ? AppServices.get().getOpenWallets().keySet() : null);
bwtConnectionService.setOnFailed(workerStateEvent -> {
@ -900,7 +889,7 @@ public class ElectrumServer {
public void resetConnection() {
try {
closeActiveConnection();
shutdownBwt();
shutdown();
firstCall = true;
} catch (ServerException e) {
log.error("Error closing connection during connection reset", e);
@ -919,7 +908,7 @@ public class ElectrumServer {
public boolean cancel() {
try {
closeActiveConnection();
shutdownBwt();
shutdown();
} catch (ServerException e) {
log.error("Error closing connection", e);
}
@ -927,8 +916,8 @@ public class ElectrumServer {
return super.cancel();
}
private void shutdownBwt() {
if(Config.get().getServerType() == ServerType.BITCOIN_CORE) {
private void shutdown() {
if(Config.get().getServerType() == ServerType.BITCOIN_CORE && bwt.isRunning()) {
Bwt.DisconnectionService disconnectionService = bwt.getDisconnectionService();
disconnectionService.setOnSucceeded(workerStateEvent -> {
ElectrumServer.bwtElectrumServer = null;
@ -937,6 +926,8 @@ public class ElectrumServer {
log.error("Failed to stop BWT", workerStateEvent.getSource().getException());
});
Platform.runLater(disconnectionService::start);
} else {
Platform.runLater(() -> EventManager.get().post(new DisconnectionEvent()));
}
}

View file

@ -0,0 +1,18 @@
package com.sparrowwallet.sparrow.net;
public class ServerConfigException extends ServerException {
public ServerConfigException() {
}
public ServerConfigException(String message) {
super(message);
}
public ServerConfigException(Throwable cause) {
super(cause);
}
public ServerConfigException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -28,6 +28,8 @@ public class PreferencesController implements Initializable {
private final BooleanProperty closing = new SimpleBooleanProperty(false);
private final BooleanProperty reconnectOnClosing = new SimpleBooleanProperty(false);
@Override
public void initialize(URL location, ResourceBundle resources) {
@ -64,6 +66,14 @@ public class PreferencesController implements Initializable {
return closing;
}
public boolean isReconnectOnClosing() {
return reconnectOnClosing.get();
}
public BooleanProperty reconnectOnClosingProperty() {
return reconnectOnClosing;
}
FXMLLoader setPreferencePane(String fxmlName) {
preferencesPane.getChildren().removeAll(preferencesPane.getChildren());

View file

@ -15,8 +15,6 @@ import org.controlsfx.tools.Borders;
import java.io.IOException;
public class PreferencesDialog extends Dialog<Boolean> {
private final boolean existingConnection;
public PreferencesDialog() {
this(null);
}
@ -51,10 +49,10 @@ public class PreferencesDialog extends Dialog<Boolean> {
dialogPane.setPrefWidth(650);
dialogPane.setPrefHeight(600);
existingConnection = ElectrumServer.isConnected();
preferencesController.reconnectOnClosingProperty().set(AppServices.isConnecting() || AppServices.isConnected());
setOnCloseRequest(event -> {
preferencesController.closingProperty().set(true);
if(existingConnection && !ElectrumServer.isConnected()) {
if(preferencesController.isReconnectOnClosing() && !(AppServices.isConnecting() || AppServices.isConnected())) {
EventManager.get().post(new RequestConnectEvent());
}
});

View file

@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.preferences;
import com.google.common.eventbus.Subscribe;
import com.google.common.net.HostAndPort;
import com.sparrowwallet.drongo.Network;
import com.sparrowwallet.sparrow.AppServices;
import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.control.TextFieldValidator;
import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch;
@ -251,9 +252,13 @@ public class ServerPreferencesController extends PreferencesDetailController {
}
});
boolean isConnected = ElectrumServer.isConnected();
boolean isConnected = AppServices.isConnecting() || AppServices.isConnected();
setFieldsEditable(!isConnected);
if(AppServices.isConnecting()) {
testResults.appendText("Connecting to server, please wait...");
}
testConnection.managedProperty().bind(testConnection.visibleProperty());
testConnection.setVisible(!isConnected);
setTestResultsFont();
@ -265,6 +270,7 @@ public class ServerPreferencesController extends PreferencesDetailController {
editConnection.managedProperty().bind(editConnection.visibleProperty());
editConnection.setVisible(isConnected);
editConnection.setDisable(AppServices.isConnecting());
editConnection.setOnAction(event -> {
EventManager.get().post(new RequestDisconnectEvent());
setFieldsEditable(true);
@ -364,6 +370,7 @@ public class ServerPreferencesController extends PreferencesDetailController {
EventManager.get().unregister(connectionService);
ConnectionEvent connectionEvent = (ConnectionEvent)connectionService.getValue();
showConnectionSuccess(connectionEvent.getServerVersion(), connectionEvent.getServerBanner());
getMasterController().reconnectOnClosingProperty().set(true);
connectionService.cancel();
});
connectionService.setOnFailed(workerStateEvent -> {
@ -377,24 +384,24 @@ public class ServerPreferencesController extends PreferencesDetailController {
private void setFieldsEditable(boolean editable) {
serverTypeToggleGroup.getToggles().forEach(toggle -> ((ToggleButton)toggle).setDisable(!editable));
coreHost.setEditable(editable);
corePort.setEditable(editable);
coreHost.setDisable(!editable);
corePort.setDisable(!editable);
coreAuthToggleGroup.getToggles().forEach(toggle -> ((ToggleButton)toggle).setDisable(!editable));
coreDataDir.setEditable(editable);
coreDataDir.setDisable(!editable);
coreDataDirSelect.setDisable(!editable);
coreUser.setEditable(editable);
corePass.setEditable(editable);
coreUser.setDisable(!editable);
corePass.setDisable(!editable);
coreMultiWallet.setDisable(!editable);
coreWallet.setEditable(editable);
coreWallet.setDisable(!editable);
electrumHost.setEditable(editable);
electrumPort.setEditable(editable);
electrumHost.setDisable(!editable);
electrumPort.setDisable(!editable);
electrumUseSsl.setDisable(!editable);
electrumCertificate.setEditable(editable);
electrumCertificate.setDisable(!editable);
electrumCertificateSelect.setDisable(!editable);
useProxy.setDisable(!editable);
proxyHost.setEditable(editable);
proxyPort.setEditable(editable);
proxyHost.setDisable(!editable);
proxyPort.setDisable(!editable);
}
private void showConnectionSuccess(List<String> serverVersion, String serverBanner) {
@ -624,10 +631,14 @@ public class ServerPreferencesController extends PreferencesDetailController {
if(!(event instanceof BwtSyncStatusEvent)) {
testResults.appendText("\n" + event.getStatus());
}
if(event instanceof BwtReadyStatusEvent) {
editConnection.setDisable(false);
}
}
@Subscribe
public void bwtSyncStatus(BwtSyncStatusEvent event) {
editConnection.setDisable(false);
if(connectionService != null && connectionService.isRunning() && event.getProgress() < 100) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
testResults.appendText("\nThe connection to the Bitcoin Core node was successful, but it is still syncing and cannot be used yet.");