mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-22 14:42:37 +01:00
Show connected Bitcoin network peer info
This commit is contained in:
parent
2178dbdc68
commit
c8cb7fff1e
5 changed files with 164 additions and 47 deletions
|
@ -122,6 +122,8 @@ public class WalletsSetup {
|
|||
private final File walletDir;
|
||||
private final int socks5DiscoverMode;
|
||||
private final IntegerProperty numPeers = new SimpleIntegerProperty(0);
|
||||
private final IntegerProperty chainHeight = new SimpleIntegerProperty(0);
|
||||
private final ObjectProperty<Peer> blocksDownloadedFromPeer = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<List<Peer>> connectedPeers = new SimpleObjectProperty<>();
|
||||
private final DownloadListener downloadListener = new DownloadListener();
|
||||
private final List<Runnable> setupCompletedHandlers = new ArrayList<>();
|
||||
|
@ -200,6 +202,7 @@ public class WalletsSetup {
|
|||
super.onSetupCompleted();
|
||||
|
||||
final PeerGroup peerGroup = walletConfig.peerGroup();
|
||||
final BlockChain chain = walletConfig.chain();
|
||||
|
||||
// We don't want to get our node white list polluted with nodes from AddressMessage calls.
|
||||
if (preferences.getBitcoinNodes() != null && !preferences.getBitcoinNodes().isEmpty())
|
||||
|
@ -215,6 +218,13 @@ public class WalletsSetup {
|
|||
numPeers.set(peerCount);
|
||||
connectedPeers.set(peerGroup.getConnectedPeers());
|
||||
});
|
||||
peerGroup.addBlocksDownloadedEventListener((peer, block, filteredBlock, blocksLeft) -> {
|
||||
blocksDownloadedFromPeer.set(peer);
|
||||
});
|
||||
chain.addNewBestBlockListener(block -> {
|
||||
connectedPeers.set(peerGroup.getConnectedPeers());
|
||||
chainHeight.set(block.getHeight());
|
||||
});
|
||||
|
||||
// Map to user thread
|
||||
UserThread.execute(() -> {
|
||||
|
@ -429,6 +439,14 @@ public class WalletsSetup {
|
|||
return connectedPeers;
|
||||
}
|
||||
|
||||
public ReadOnlyIntegerProperty chainHeightProperty() {
|
||||
return chainHeight;
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Peer> blocksDownloadedFromPeerProperty() {
|
||||
return blocksDownloadedFromPeer;
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty downloadPercentageProperty() {
|
||||
return downloadListener.percentageProperty();
|
||||
}
|
||||
|
|
|
@ -1060,6 +1060,10 @@ settings.net.receivedBytesColumn=Received
|
|||
settings.net.peerTypeColumn=Peer type
|
||||
settings.net.openTorSettingsButton=Open Tor settings
|
||||
|
||||
settings.net.versionColumn=Version
|
||||
settings.net.subVersionColumn=Subversion
|
||||
settings.net.heightColumn=Height
|
||||
|
||||
settings.net.needRestart=You need to restart the application to apply that change.\nDo you want to do that now?
|
||||
settings.net.notKnownYet=Not known yet...
|
||||
settings.net.sentReceived=Sent: {0}, received: {1}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.settings.network;
|
||||
|
||||
import org.bitcoinj.core.Peer;
|
||||
|
||||
public class BitcoinNetworkListItem {
|
||||
private final Peer peer;
|
||||
|
||||
public BitcoinNetworkListItem(Peer peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
public String getOnionAddress() {
|
||||
return peer.getAddress().toString();
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return String.valueOf(peer.getPeerVersionMessage().clientVersion);
|
||||
}
|
||||
|
||||
public String getSubVersion() {
|
||||
return peer.getPeerVersionMessage().subVer;
|
||||
}
|
||||
|
||||
public String getHeight() {
|
||||
return String.valueOf(peer.getBestHeight());
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@
|
|||
<?import bisq.desktop.components.AutoTooltipCheckBox?>
|
||||
<?import bisq.desktop.components.AutoTooltipLabel?>
|
||||
<?import bisq.desktop.components.AutoTooltipRadioButton?>
|
||||
<?import bisq.desktop.components.BisqTextArea?>
|
||||
<?import bisq.desktop.components.BisqTextField?>
|
||||
<?import bisq.desktop.components.InputTextField?>
|
||||
<?import bisq.desktop.components.TitledGroupBg?>
|
||||
|
@ -45,12 +44,34 @@
|
|||
</padding>
|
||||
|
||||
<TitledGroupBg fx:id="btcHeader" GridPane.rowSpan="5"/>
|
||||
<BisqTextArea fx:id="bitcoinPeersTextArea" GridPane.rowIndex="0" GridPane.hgrow="ALWAYS"
|
||||
GridPane.vgrow="SOMETIMES" editable="false" focusTraversable="false" labelFloat="true">
|
||||
<GridPane.margin>
|
||||
<Insets top="25"/>
|
||||
</GridPane.margin>
|
||||
</BisqTextArea>
|
||||
<VBox GridPane.rowIndex="0" GridPane.hgrow="ALWAYS" GridPane.vgrow="SOMETIMES">
|
||||
<AutoTooltipLabel fx:id="bitcoinPeersLabel" styleClass="small-text"/>
|
||||
<TableView fx:id="bitcoinPeersTableView">
|
||||
<columns>
|
||||
<TableColumn fx:id="bitcoinPeerAddressColumn" minWidth="220">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="onionAddress"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="bitcoinPeerVersionColumn" minWidth="80" maxWidth="90">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="version"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="bitcoinPeerSubVersionColumn" minWidth="180" maxWidth="180">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="subVersion"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="bitcoinPeerHeightColumn" minWidth="80" maxWidth="80">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="height"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
</columns>
|
||||
</TableView>
|
||||
<AutoTooltipLabel fx:id="localhostBtcNodeInfoLabel" styleClass="small-text"/>
|
||||
</VBox>
|
||||
|
||||
<AutoTooltipCheckBox fx:id="useTorForBtcJCheckBox" GridPane.rowIndex="1"/>
|
||||
|
||||
|
@ -91,7 +112,7 @@
|
|||
|
||||
<VBox GridPane.rowIndex="6" GridPane.hgrow="ALWAYS" GridPane.vgrow="SOMETIMES">
|
||||
<AutoTooltipLabel fx:id="p2PPeersLabel" styleClass="small-text"/>
|
||||
<TableView fx:id="tableView">
|
||||
<TableView fx:id="p2pPeersTableView">
|
||||
<columns>
|
||||
<TableColumn fx:id="onionAddressColumn" minWidth="220">
|
||||
<cellValueFactory>
|
||||
|
|
|
@ -44,8 +44,6 @@ import bisq.network.p2p.network.Statistic;
|
|||
import bisq.common.ClockWatcher;
|
||||
import bisq.common.UserThread;
|
||||
|
||||
import org.bitcoinj.core.Peer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -55,7 +53,6 @@ import javafx.scene.control.Label;
|
|||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Toggle;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
|
@ -73,7 +70,6 @@ import javafx.collections.FXCollections;
|
|||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -83,25 +79,28 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
@FXML
|
||||
TitledGroupBg p2pHeader, btcHeader;
|
||||
@FXML
|
||||
Label btcNodesLabel, bitcoinNodesLabel;
|
||||
Label btcNodesLabel, bitcoinNodesLabel, localhostBtcNodeInfoLabel;
|
||||
@FXML
|
||||
InputTextField btcNodesInputTextField;
|
||||
@FXML
|
||||
TextField onionAddress, totalTrafficTextField;
|
||||
@FXML
|
||||
TextArea bitcoinPeersTextArea;
|
||||
@FXML
|
||||
Label p2PPeersLabel;
|
||||
Label p2PPeersLabel, bitcoinPeersLabel;
|
||||
@FXML
|
||||
CheckBox useTorForBtcJCheckBox;
|
||||
@FXML
|
||||
RadioButton useProvidedNodesRadio, useCustomNodesRadio, usePublicNodesRadio;
|
||||
@FXML
|
||||
TableView<P2pNetworkListItem> tableView;
|
||||
TableView<P2pNetworkListItem> p2pPeersTableView;
|
||||
@FXML
|
||||
TableView<BitcoinNetworkListItem> bitcoinPeersTableView;
|
||||
@FXML
|
||||
TableColumn<P2pNetworkListItem, String> onionAddressColumn, connectionTypeColumn, creationDateColumn,
|
||||
roundTripTimeColumn, sentBytesColumn, receivedBytesColumn, peerTypeColumn;
|
||||
@FXML
|
||||
TableColumn<BitcoinNetworkListItem, String> bitcoinPeerAddressColumn, bitcoinPeerVersionColumn,
|
||||
bitcoinPeerSubVersionColumn, bitcoinPeerHeightColumn;
|
||||
@FXML
|
||||
Label reSyncSPVChainLabel;
|
||||
@FXML
|
||||
AutoTooltipButton reSyncSPVChainButton, openTorSettingsButton;
|
||||
|
@ -116,11 +115,16 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
private final WalletsSetup walletsSetup;
|
||||
private final P2PService p2PService;
|
||||
|
||||
private final ObservableList<P2pNetworkListItem> networkListItems = FXCollections.observableArrayList();
|
||||
private final SortedList<P2pNetworkListItem> sortedList = new SortedList<>(networkListItems);
|
||||
private final ObservableList<P2pNetworkListItem> p2pNetworkListItems = FXCollections.observableArrayList();
|
||||
private final SortedList<P2pNetworkListItem> p2pSortedList = new SortedList<>(p2pNetworkListItems);
|
||||
|
||||
private final ObservableList<BitcoinNetworkListItem> bitcoinNetworkListItems = FXCollections.observableArrayList();
|
||||
private final SortedList<BitcoinNetworkListItem> bitcoinSortedList = new SortedList<>(bitcoinNetworkListItems);
|
||||
|
||||
private Subscription numP2PPeersSubscription;
|
||||
private Subscription bitcoinPeersSubscription;
|
||||
private Subscription bitcoinBlockHeightSubscription;
|
||||
private Subscription bitcoinBlocksDownloadedSubscription;
|
||||
private Subscription nodeAddressSubscription;
|
||||
private ChangeListener<Boolean> btcNodesInputTextFieldFocusListener;
|
||||
private ToggleGroup bitcoinPeersToggleGroup;
|
||||
|
@ -156,9 +160,18 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
p2pHeader.setText(Res.get("settings.net.p2pHeader"));
|
||||
onionAddress.setPromptText(Res.get("settings.net.onionAddressLabel"));
|
||||
btcNodesLabel.setText(Res.get("settings.net.btcNodesLabel"));
|
||||
bitcoinPeersTextArea.setPromptText(Res.get("settings.net.bitcoinPeersLabel"));
|
||||
bitcoinPeersLabel.setText(Res.get("settings.net.bitcoinPeersLabel"));
|
||||
useTorForBtcJCheckBox.setText(Res.get("settings.net.useTorForBtcJLabel"));
|
||||
bitcoinNodesLabel.setText(Res.get("settings.net.bitcoinNodesLabel"));
|
||||
bitcoinPeerAddressColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.onionAddressColumn")));
|
||||
bitcoinPeerAddressColumn.getStyleClass().add("first-column");
|
||||
bitcoinPeerVersionColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.versionColumn")));
|
||||
bitcoinPeerSubVersionColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.subVersionColumn")));
|
||||
bitcoinPeerHeightColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.heightColumn")));
|
||||
localhostBtcNodeInfoLabel.setText(Res.get("settings.net.localhostBtcNodeInfo"));
|
||||
if (!bisqEnvironment.isBitcoinLocalhostNodeRunning()) {
|
||||
localhostBtcNodeInfoLabel.setVisible(false);
|
||||
}
|
||||
useProvidedNodesRadio.setText(Res.get("settings.net.useProvidedNodesRadio"));
|
||||
useCustomNodesRadio.setText(Res.get("settings.net.useCustomNodesRadio"));
|
||||
usePublicNodesRadio.setText(Res.get("settings.net.usePublicNodesRadio"));
|
||||
|
@ -177,16 +190,25 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
peerTypeColumn.getStyleClass().add("last-column");
|
||||
openTorSettingsButton.updateText(Res.get("settings.net.openTorSettingsButton"));
|
||||
|
||||
GridPane.setMargin(bitcoinPeersLabel, new Insets(4, 0, 0, 0));
|
||||
GridPane.setValignment(bitcoinPeersLabel, VPos.TOP);
|
||||
|
||||
GridPane.setMargin(p2PPeersLabel, new Insets(4, 0, 0, 0));
|
||||
GridPane.setValignment(p2PPeersLabel, VPos.TOP);
|
||||
|
||||
bitcoinPeersTextArea.setPrefRowCount(4);
|
||||
bitcoinPeersTableView.setMinHeight(180);
|
||||
bitcoinPeersTableView.setPrefHeight(180);
|
||||
bitcoinPeersTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
bitcoinPeersTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData")));
|
||||
bitcoinPeersTableView.getSortOrder().add(bitcoinPeerAddressColumn);
|
||||
bitcoinPeerAddressColumn.setSortType(TableColumn.SortType.ASCENDING);
|
||||
|
||||
tableView.setMinHeight(180);
|
||||
tableView.setPrefHeight(180);
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData")));
|
||||
tableView.getSortOrder().add(creationDateColumn);
|
||||
|
||||
p2pPeersTableView.setMinHeight(180);
|
||||
p2pPeersTableView.setPrefHeight(180);
|
||||
p2pPeersTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
p2pPeersTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData")));
|
||||
p2pPeersTableView.getSortOrder().add(creationDateColumn);
|
||||
creationDateColumn.setSortType(TableColumn.SortType.ASCENDING);
|
||||
|
||||
bitcoinPeersToggleGroup = new ToggleGroup();
|
||||
|
@ -267,7 +289,13 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
reSyncSPVChainButton.setOnAction(event -> GUIUtil.reSyncSPVChain(walletsSetup, preferences));
|
||||
|
||||
bitcoinPeersSubscription = EasyBind.subscribe(walletsSetup.connectedPeersProperty(),
|
||||
connectedPeers -> updateBitcoinPeersTextArea());
|
||||
connectedPeers -> updateBitcoinPeersTable());
|
||||
|
||||
bitcoinBlocksDownloadedSubscription = EasyBind.subscribe(walletsSetup.blocksDownloadedFromPeerProperty(),
|
||||
peer -> updateBitcoinPeersTable());
|
||||
|
||||
bitcoinBlockHeightSubscription = EasyBind.subscribe(walletsSetup.chainHeightProperty(),
|
||||
chainHeight -> updateBitcoinPeersTable());
|
||||
|
||||
nodeAddressSubscription = EasyBind.subscribe(p2PService.getNetworkNode().nodeAddressProperty(),
|
||||
nodeAddress -> onionAddress.setText(nodeAddress == null ?
|
||||
|
@ -280,8 +308,11 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
BSFormatter.formatBytes((long) sent),
|
||||
BSFormatter.formatBytes((long) received))));
|
||||
|
||||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||
tableView.setItems(sortedList);
|
||||
bitcoinSortedList.comparatorProperty().bind(bitcoinPeersTableView.comparatorProperty());
|
||||
bitcoinPeersTableView.setItems(bitcoinSortedList);
|
||||
|
||||
p2pSortedList.comparatorProperty().bind(p2pPeersTableView.comparatorProperty());
|
||||
p2pPeersTableView.setItems(p2pSortedList);
|
||||
|
||||
btcNodesInputTextField.setText(preferences.getBitcoinNodes());
|
||||
btcNodesInputTextField.setPromptText(Res.get("settings.net.ips"));
|
||||
|
@ -305,13 +336,20 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
if (bitcoinPeersSubscription != null)
|
||||
bitcoinPeersSubscription.unsubscribe();
|
||||
|
||||
if (bitcoinBlockHeightSubscription != null)
|
||||
bitcoinBlockHeightSubscription.unsubscribe();
|
||||
|
||||
if (bitcoinBlocksDownloadedSubscription != null)
|
||||
bitcoinBlocksDownloadedSubscription.unsubscribe();
|
||||
|
||||
if (numP2PPeersSubscription != null)
|
||||
numP2PPeersSubscription.unsubscribe();
|
||||
|
||||
totalTrafficTextField.textProperty().unbind();
|
||||
|
||||
sortedList.comparatorProperty().unbind();
|
||||
tableView.getItems().forEach(P2pNetworkListItem::cleanup);
|
||||
bitcoinSortedList.comparatorProperty().unbind();
|
||||
p2pSortedList.comparatorProperty().unbind();
|
||||
p2pPeersTableView.getItems().forEach(P2pNetworkListItem::cleanup);
|
||||
btcNodesInputTextField.focusedProperty().removeListener(btcNodesInputTextFieldFocusListener);
|
||||
btcNodesInputTextField.textProperty().removeListener(btcNodesInputTextFieldListener);
|
||||
|
||||
|
@ -422,26 +460,18 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
}
|
||||
|
||||
private void updateP2PTable() {
|
||||
tableView.getItems().forEach(P2pNetworkListItem::cleanup);
|
||||
networkListItems.clear();
|
||||
networkListItems.setAll(p2PService.getNetworkNode().getAllConnections().stream()
|
||||
p2pPeersTableView.getItems().forEach(P2pNetworkListItem::cleanup);
|
||||
p2pNetworkListItems.clear();
|
||||
p2pNetworkListItems.setAll(p2PService.getNetworkNode().getAllConnections().stream()
|
||||
.map(connection -> new P2pNetworkListItem(connection, clockWatcher, formatter))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private void updateBitcoinPeersTextArea() {
|
||||
bitcoinPeersTextArea.clear();
|
||||
List<Peer> peerList = walletsSetup.connectedPeersProperty().get();
|
||||
if (peerList != null) {
|
||||
peerList.stream().forEach(e -> {
|
||||
if (bitcoinPeersTextArea.getText().length() > 0)
|
||||
bitcoinPeersTextArea.appendText("\n");
|
||||
bitcoinPeersTextArea.appendText(e.toString());
|
||||
});
|
||||
}
|
||||
|
||||
if (bisqEnvironment.isBitcoinLocalhostNodeRunning())
|
||||
bitcoinPeersTextArea.appendText("\n\n" + Res.get("settings.net.localhostBtcNodeInfo"));
|
||||
private void updateBitcoinPeersTable() {
|
||||
bitcoinNetworkListItems.clear();
|
||||
bitcoinNetworkListItems.setAll(walletsSetup.getPeerGroup().getConnectedPeers().stream()
|
||||
.map(BitcoinNetworkListItem::new)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue