P2P network improvements

This commit is contained in:
Manfred Karrer 2016-01-02 22:04:30 +01:00
parent 97629cb0cd
commit 7c3732c0e5
36 changed files with 831 additions and 416 deletions

View file

@ -32,6 +32,7 @@ import io.bitsquare.gui.common.view.View;
import io.bitsquare.gui.common.view.ViewLoader;
import io.bitsquare.gui.common.view.guice.InjectorViewFactory;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.MainViewModel;
import io.bitsquare.gui.main.debug.DebugView;
import io.bitsquare.gui.popups.EmptyWalletPopup;
import io.bitsquare.gui.popups.Popup;
@ -304,15 +305,13 @@ public class BitsquareApp extends Application {
log.debug("gracefulShutDown");
try {
if (injector != null) {
ArbitratorManager arbitratorManager = injector.getInstance(ArbitratorManager.class);
arbitratorManager.shutDown();
OpenOfferManager openOfferManager = injector.getInstance(OpenOfferManager.class);
openOfferManager.shutDown(() -> {
P2PService p2PService = injector.getInstance(P2PService.class);
p2PService.shutDown(() -> {
WalletService walletService = injector.getInstance(WalletService.class);
walletService.shutDownDone.addListener((observable, oldValue, newValue) -> {
injector.getInstance(ArbitratorManager.class).shutDown();
injector.getInstance(MainViewModel.class).shutDown();
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
injector.getInstance(P2PService.class).shutDown(() -> {
injector.getInstance(WalletService.class).shutDownDone.addListener((ov, o, n) -> {
bitsquareAppModule.close(injector);
log.info("Graceful shutdown completed");
resultHandler.handleResult();
});
injector.getInstance(WalletService.class).shutDown();

View file

@ -46,7 +46,7 @@ public class Navigation implements Serializable {
// New listeners can be added during iteration so we use CopyOnWriteArrayList to
// prevent invalid array modification
transient private final CopyOnWriteArraySet<Listener> listeners = new CopyOnWriteArraySet<>();
transient private final Storage<Navigation> remoteStorage;
transient private final Storage<Navigation> storage;
transient private ViewPath currentPath;
// Used for returning to the last important view. After setup is done we want to
// return to the last opened view (e.g. sell/buy)
@ -57,14 +57,13 @@ public class Navigation implements Serializable {
@Inject
public Navigation(Storage<Navigation> remoteStorage) {
this.remoteStorage = remoteStorage;
public Navigation(Storage<Navigation> storage) {
this.storage = storage;
Navigation persisted = remoteStorage.initAndGetPersisted(this);
Navigation persisted = storage.initAndGetPersisted(this);
if (persisted != null) {
previousPath = persisted.getPreviousPath();
}
else
} else
previousPath = DEFAULT_VIEW_PATH;
// need to be null initially and not DEFAULT_VIEW_PATH to navigate through all items
@ -102,7 +101,7 @@ public class Navigation implements Serializable {
currentPath = newPath;
previousPath = currentPath;
remoteStorage.queueUpForSave();
storage.queueUpForSave(2000);
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
}

View file

@ -87,6 +87,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
private Label btcSplashInfo;
private List<String> persistedFilesCorrupted;
private static BorderPane baseApplicationContainer;
private Popup p2PNetworkWarnMsgPopup;
@Inject
public MainView(MainViewModel model, CachingViewLoader viewLoader, Navigation navigation, Transitions transitions,
@ -271,8 +272,10 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
splashP2PNetworkIndicator.progressProperty().bind(model.splashP2PNetworkProgress);
splashP2PNetworkErrorMsgListener = (ov, oldValue, newValue) -> {
splashP2PNetworkLabel.setId("splash-error-state-msg");
splashP2PNetworkIndicator.setVisible(false);
if (newValue != null) {
splashP2PNetworkLabel.setId("splash-error-state-msg");
splashP2PNetworkIndicator.setVisible(false);
}
};
model.p2PNetworkWarnMsg.addListener(splashP2PNetworkErrorMsgListener);
@ -392,14 +395,12 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
setRightAnchor(p2PNetworkIcon, 10d);
setBottomAnchor(p2PNetworkIcon, 7d);
p2PNetworkIcon.idProperty().bind(model.p2PNetworkIconId);
p2PNetworkLabel.idProperty().bind(model.p2PNetworkLabelId);
model.p2PNetworkWarnMsg.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
p2PNetworkLabel.setId("splash-error-state-msg");
new Popup().warning(newValue + "\nPlease check your internet connection or try to restart the application.")
.show();
} else {
p2PNetworkLabel.setId("footer-pane");
p2PNetworkWarnMsgPopup = new Popup().warning(newValue).show();
} else if (p2PNetworkWarnMsgPopup != null) {
p2PNetworkWarnMsgPopup.hide();
}
});

View file

@ -47,6 +47,7 @@ import io.bitsquare.trade.offer.OpenOfferManager;
import io.bitsquare.user.Preferences;
import io.bitsquare.user.User;
import javafx.beans.property.*;
import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
import org.bitcoinj.core.*;
import org.bitcoinj.store.BlockStoreException;
@ -65,7 +66,7 @@ import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class MainViewModel implements ViewModel {
public class MainViewModel implements ViewModel {
private static final Logger log = LoggerFactory.getLogger(MainViewModel.class);
private final WalletService walletService;
@ -105,12 +106,13 @@ class MainViewModel implements ViewModel {
final BooleanProperty showOpenDisputesNotification = new SimpleBooleanProperty();
private final BooleanProperty isSplashScreenRemoved = new SimpleBooleanProperty();
private final String btcNetworkAsString;
final StringProperty p2PNetworkLabelId = new SimpleStringProperty("footer-pane");
private MonadicBinding<Boolean> allServicesDone;
private User user;
private int numBTCPeers = 0;
private Timer checkForBtcSyncStateTimer;
private ChangeListener<Number> numAuthenticatedPeersListener, btcNumPeersListener;
///////////////////////////////////////////////////////////////////////////////////////////
@ -170,13 +172,24 @@ class MainViewModel implements ViewModel {
});
}
public void shutDown() {
if (numAuthenticatedPeersListener != null)
p2PService.getNumAuthenticatedPeers().removeListener(numAuthenticatedPeersListener);
if (btcNumPeersListener != null)
walletService.numPeersProperty().removeListener(btcNumPeersListener);
if (checkForBtcSyncStateTimer != null)
checkForBtcSyncStateTimer.stop();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Initialisation
///////////////////////////////////////////////////////////////////////////////////////////
private BooleanProperty initP2PNetwork() {
final BooleanProperty p2pNetWorkReady = new SimpleBooleanProperty();
final BooleanProperty p2pNetworkInitialized = new SimpleBooleanProperty();
p2PNetworkInfo.set("Connecting to Tor network...");
p2PService.start(new P2PServiceListener() {
@Override
@ -197,14 +210,26 @@ class MainViewModel implements ViewModel {
} else {
updateP2pNetworkInfoWithPeersChanged(p2PService.getNumAuthenticatedPeers().get());
}
p2pNetWorkReady.set(true);
p2pNetworkInitialized.set(true);
}
@Override
public void onNoSeedNodeAvailable() {
p2PNetworkWarnMsg.set("There are no seed nodes available.");
p2PNetworkInfo.set("No seed node available");
p2pNetWorkReady.set(true);
if (p2PService.getNumAuthenticatedPeers().get() == 0) {
p2PNetworkInfo.set("No seed nodes available");
}
p2pNetworkInitialized.set(true);
}
@Override
public void onNoPeersAvailable() {
if (p2PService.getNumAuthenticatedPeers().get() == 0) {
p2PNetworkWarnMsg.set("There are no seed nodes or persisted peers available for requesting data.\n" +
"Please check your internet connection or try to restart the application.");
p2PNetworkInfo.set("No seed nodes and peers available");
p2PNetworkLabelId.set("splash-error-state-msg");
}
p2pNetworkInitialized.set(true);
}
@Override
@ -216,18 +241,22 @@ class MainViewModel implements ViewModel {
@Override
public void onSetupFailed(Throwable throwable) {
p2PNetworkWarnMsg.set("Connecting to the P2P network failed (reported error: " + throwable.getMessage() + ").");
p2PNetworkWarnMsg.set("Connecting to the P2P network failed (reported error: "
+ throwable.getMessage() + ").\n" +
"Please check your internet connection or try to restart the application.");
splashP2PNetworkProgress.set(0);
if (p2PService.getNumAuthenticatedPeers().get() == 0)
p2PNetworkLabelId.set("splash-error-state-msg");
}
});
return p2pNetWorkReady;
return p2pNetworkInitialized;
}
private BooleanProperty initBitcoinWallet() {
EasyBind.subscribe(walletService.downloadPercentageProperty(), newValue -> setBitcoinNetworkSyncProgress((double) newValue));
walletService.numPeersProperty().addListener((observable, oldValue, newValue) -> {
btcNumPeersListener = (observable, oldValue, newValue) -> {
if ((int) oldValue > 0 && (int) newValue == 0)
walletServiceErrorMsg.set("You lost the connection to all bitcoin peers.");
else if ((int) oldValue == 0 && (int) newValue > 0)
@ -235,7 +264,8 @@ class MainViewModel implements ViewModel {
numBTCPeers = (int) newValue;
setBitcoinNetworkSyncProgress(walletService.downloadPercentageProperty().get());
});
};
walletService.numPeersProperty().addListener(btcNumPeersListener);
final BooleanProperty walletInitialized = new SimpleBooleanProperty();
walletService.initialize(null,
@ -341,14 +371,19 @@ class MainViewModel implements ViewModel {
.show();
// update nr of peers in footer
p2PService.getNumAuthenticatedPeers().addListener((observable, oldValue, newValue) -> {
if ((int) oldValue > 0 && (int) newValue == 0)
p2PNetworkWarnMsg.set("You lost the connection to all P2P network peers.");
else if ((int) oldValue == 0 && (int) newValue > 0)
numAuthenticatedPeersListener = (observable, oldValue, newValue) -> {
if ((int) oldValue > 0 && (int) newValue == 0) {
p2PNetworkWarnMsg.set("You lost the connection to all P2P network peers.\n" +
"Please check your internet connection or try to restart the application.");
p2PNetworkLabelId.set("splash-error-state-msg");
} else if ((int) oldValue == 0 && (int) newValue > 0) {
p2PNetworkWarnMsg.set(null);
p2PNetworkLabelId.set("footer-pane");
}
updateP2pNetworkInfoWithPeersChanged((int) newValue);
});
};
p2PService.getNumAuthenticatedPeers().addListener(numAuthenticatedPeersListener);
// now show app
showAppScreen.set(true);
@ -565,7 +600,6 @@ class MainViewModel implements ViewModel {
}
private void setBitcoinNetworkSyncProgress(double value) {
Log.traceCall("btcSyncProgress=" + value);
btcSyncProgress.set(value);
String numPeers = "Nr. of peers: " + numBTCPeers;
if (value == 1) {

View file

@ -185,6 +185,6 @@ class ArbitratorRegistrationViewModel extends ActivatableViewModel {
}
boolean isAuthenticated() {
return p2PService.getFirstPeerAuthenticated();
return p2PService.isAuthenticated();
}
}

View file

@ -486,7 +486,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
}
boolean isAuthenticated() {
return p2PService.getFirstPeerAuthenticated();
return p2PService.isAuthenticated();
}
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -158,7 +158,7 @@ class OfferBookViewModel extends ActivatableViewModel {
}
boolean isAuthenticated() {
return p2PService.getFirstPeerAuthenticated();
return p2PService.isAuthenticated();
}
public TradeCurrency getTradeCurrency() {

View file

@ -74,6 +74,6 @@ class OpenOffersViewModel extends ActivatableWithDataModel<OpenOffersDataModel>
}
boolean isAuthenticated() {
return p2PService.getFirstPeerAuthenticated();
return p2PService.isAuthenticated();
}
}

View file

@ -220,7 +220,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
public boolean isAuthenticated() {
return p2PService.getFirstPeerAuthenticated();
return p2PService.isAuthenticated();
}
// columns

View file

@ -120,7 +120,10 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
@Override
public void onNoSeedNodeAvailable() {
}
@Override
public void onNoPeersAvailable() {
}
@Override