Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 4685 with 4680 #4686

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
607f447
Extract method for filling seed nodes from property file
chimp1984 Oct 14, 2020
ca91ccf
Make config nullable and extract methods where config is used and app…
chimp1984 Oct 14, 2020
f86ca72
Add inventory module
chimp1984 Oct 14, 2020
283fb70
Move inventory package to core as we want to include other domain dat…
chimp1984 Oct 15, 2020
905a74d
Add signature to request to limit the feature to requests from truste…
chimp1984 Oct 15, 2020
0ec34d3
Add readableFileSize
chimp1984 Oct 15, 2020
6f1cdd7
Add readSeedNodePropertyFile method
chimp1984 Oct 15, 2020
0646e55
Add sparkjava dependency
chimp1984 Oct 15, 2020
81bf469
Remove signature from GetInventoryRequest (as monitor is public it do…
chimp1984 Oct 15, 2020
053f624
Add shadow plugin
chimp1984 Oct 16, 2020
6f6ea13
Make RequestInfo public
chimp1984 Oct 18, 2020
66647ab
Add InventoryItem enum
chimp1984 Oct 18, 2020
52028fd
Add nodes from mike
chimp1984 Oct 18, 2020
93d3b59
Shut down connection after response received
chimp1984 Oct 19, 2020
fb474a1
Add network node shutdown
chimp1984 Oct 19, 2020
1e31363
Add more warn/alert checks
chimp1984 Oct 21, 2020
19eb130
Add triggers for maxConnections and numConnections
chimp1984 Oct 21, 2020
a0fd819
Fix error handling
chimp1984 Oct 21, 2020
b8e60fa
Add peakNumConnections
chimp1984 Oct 21, 2020
5fcab37
Add numAllConnectionsLostEvents
chimp1984 Oct 21, 2020
1a6547e
Fix connection config for monitor
freimair Feb 20, 2020
d7dd359
Code cleanup
freimair Feb 20, 2020
e97c4c8
Added offer volume feed metric
freimair Feb 20, 2020
d568f06
Added offer-volume-distribution
freimair Feb 21, 2020
9621895
Added offers-per-trader metric
freimair Feb 21, 2020
9574f18
Added volume-per-trader metric
freimair Feb 21, 2020
af86093
Cleanup and refactoring
freimair Feb 21, 2020
af41fdd
Reorg imports, reformat code according to your style guide
chimp1984 Oct 22, 2020
ba800bc
Remove change in Connection (issue with config when not using guice is
chimp1984 Oct 22, 2020
aad7d41
Adopt to new Persistencemanager
chimp1984 Oct 22, 2020
f8aa1af
Make constructor public
chimp1984 Oct 22, 2020
5841491
Add ifPresent check at optional
chimp1984 Oct 22, 2020
b508241
Use networkPostfix for file name
chimp1984 Oct 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ configure([project(':cli'),
project(':seednode'),
project(':statsnode'),
project(':pricenode'),
project(':inventory'),
project(':apitest')]) {

apply plugin: 'application'
Expand Down Expand Up @@ -594,6 +595,21 @@ configure(project(':daemon')) {
}
}

configure(project(':inventory')) {
apply plugin: 'com.github.johnrengelman.shadow'

mainClassName = 'bisq.inventory.InventoryMonitorMain'

dependencies {
compile project(':core')
compile "com.google.guava:guava:$guavaVersion"
compile "com.sparkjava:spark-core:$sparkVersion"

compileOnly "org.projectlombok:lombok:$lombokVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
}
}

configure(project(':apitest')) {
mainClassName = 'bisq.apitest.ApiTestMain'

Expand Down
8 changes: 6 additions & 2 deletions common/src/main/java/bisq/common/util/Profiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ public static void printSystemLoad() {
}

public static long getUsedMemoryInMB() {
return getUsedMemoryInBytes() / 1024 / 1024;
}

public static long getUsedMemoryInBytes() {
Runtime runtime = Runtime.getRuntime();
long free = runtime.freeMemory() / 1024 / 1024;
long total = runtime.totalMemory() / 1024 / 1024;
long free = runtime.freeMemory();
long total = runtime.totalMemory();
return total - free;
}

Expand Down
9 changes: 9 additions & 0 deletions common/src/main/java/bisq/common/util/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;

import java.text.DecimalFormat;

import java.net.URI;
import java.net.URISyntaxException;

Expand Down Expand Up @@ -523,4 +525,11 @@ public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtr
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

public static String readableFileSize(long size) {
if (size <= 0) return "0";
String[] units = new String[]{"B", "kB", "MB", "GB", "TB"};
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
return new DecimalFormat("#,##0.###").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
@Slf4j
public class AccountAgeWitnessStore extends PersistableNetworkPayloadStore<AccountAgeWitness> {

AccountAgeWitnessStore() {
public AccountAgeWitnessStore() {
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.core.network.p2p.inventory;

public enum DeviationSeverity {
OK,
WARN,
ALERT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/*
* 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.core.network.p2p.inventory;

import bisq.core.dao.monitoring.BlindVoteStateMonitoringService;
import bisq.core.dao.monitoring.DaoStateMonitoringService;
import bisq.core.dao.monitoring.ProposalStateMonitoringService;
import bisq.core.dao.monitoring.model.BlindVoteStateBlock;
import bisq.core.dao.monitoring.model.DaoStateBlock;
import bisq.core.dao.monitoring.model.ProposalStateBlock;
import bisq.core.dao.state.DaoStateService;
import bisq.core.network.p2p.inventory.messages.GetInventoryRequest;
import bisq.core.network.p2p.inventory.messages.GetInventoryResponse;

import bisq.network.p2p.network.Connection;
import bisq.network.p2p.network.MessageListener;
import bisq.network.p2p.network.NetworkNode;
import bisq.network.p2p.network.Statistic;
import bisq.network.p2p.peers.PeerManager;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;

import bisq.common.app.Version;
import bisq.common.config.Config;
import bisq.common.proto.network.NetworkEnvelope;
import bisq.common.util.Profiler;
import bisq.common.util.Utilities;

import javax.inject.Inject;
import javax.inject.Named;

import com.google.common.base.Enums;
import com.google.common.base.Optional;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import java.lang.management.ManagementFactory;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class GetInventoryRequestHandler implements MessageListener {
private final NetworkNode networkNode;
private final PeerManager peerManager;
private final P2PDataStorage p2PDataStorage;
private final DaoStateService daoStateService;
private final DaoStateMonitoringService daoStateMonitoringService;
private final ProposalStateMonitoringService proposalStateMonitoringService;
private final BlindVoteStateMonitoringService blindVoteStateMonitoringService;
private final int maxConnections;
private final Set<String> permittedRequestersPubKey = new HashSet<>();

@Inject
public GetInventoryRequestHandler(NetworkNode networkNode,
PeerManager peerManager,
P2PDataStorage p2PDataStorage,
DaoStateService daoStateService,
DaoStateMonitoringService daoStateMonitoringService,
ProposalStateMonitoringService proposalStateMonitoringService,
BlindVoteStateMonitoringService blindVoteStateMonitoringService,
@Named(Config.MAX_CONNECTIONS) int maxConnections) {
this.networkNode = networkNode;
this.peerManager = peerManager;
this.p2PDataStorage = p2PDataStorage;
this.daoStateService = daoStateService;
this.daoStateMonitoringService = daoStateMonitoringService;
this.proposalStateMonitoringService = proposalStateMonitoringService;
this.blindVoteStateMonitoringService = blindVoteStateMonitoringService;
this.maxConnections = maxConnections;

this.networkNode.addMessageListener(this);
}

@Override
public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if (networkEnvelope instanceof GetInventoryRequest) {
if (permittedRequestersPubKey.isEmpty()) {
return;
}

// Data
GetInventoryRequest getInventoryRequest = (GetInventoryRequest) networkEnvelope;
Map<InventoryItem, Integer> dataObjects = new HashMap<>();
p2PDataStorage.getMapForDataResponse(getInventoryRequest.getVersion()).values().stream()
.map(e -> e.getClass().getSimpleName())
.forEach(className -> {
Optional<InventoryItem> optionalEnum = Enums.getIfPresent(InventoryItem.class, className);
if (optionalEnum.isPresent()) {
InventoryItem key = optionalEnum.get();
dataObjects.putIfAbsent(key, 0);
int prev = dataObjects.get(key);
dataObjects.put(key, prev + 1);
}
});
p2PDataStorage.getMap().values().stream()
.map(ProtectedStorageEntry::getProtectedStoragePayload)
.filter(Objects::nonNull)
.map(e -> e.getClass().getSimpleName())
.forEach(className -> {
Optional<InventoryItem> optionalEnum = Enums.getIfPresent(InventoryItem.class, className);
if (optionalEnum.isPresent()) {
InventoryItem key = optionalEnum.get();
dataObjects.putIfAbsent(key, 0);
int prev = dataObjects.get(key);
dataObjects.put(key, prev + 1);
}
});
Map<InventoryItem, String> inventory = new HashMap<>();
dataObjects.forEach((key, value) -> inventory.put(key, String.valueOf(value)));

// DAO
int numBsqBlocks = daoStateService.getBlocks().size();
inventory.put(InventoryItem.numBsqBlocks, String.valueOf(numBsqBlocks));

int daoStateChainHeight = daoStateService.getChainHeight();
inventory.put(InventoryItem.daoStateChainHeight, String.valueOf(daoStateChainHeight));

LinkedList<DaoStateBlock> daoStateBlockChain = daoStateMonitoringService.getDaoStateBlockChain();
if (!daoStateBlockChain.isEmpty()) {
String daoStateHash = Utilities.bytesAsHexString(daoStateBlockChain.getLast().getMyStateHash().getHash());
inventory.put(InventoryItem.daoStateHash, daoStateHash);
}

LinkedList<ProposalStateBlock> proposalStateBlockChain = proposalStateMonitoringService.getProposalStateBlockChain();
if (!proposalStateBlockChain.isEmpty()) {
String proposalHash = Utilities.bytesAsHexString(proposalStateBlockChain.getLast().getMyStateHash().getHash());
inventory.put(InventoryItem.proposalHash, proposalHash);
}

LinkedList<BlindVoteStateBlock> blindVoteStateBlockChain = blindVoteStateMonitoringService.getBlindVoteStateBlockChain();
if (!blindVoteStateBlockChain.isEmpty()) {
String blindVoteHash = Utilities.bytesAsHexString(blindVoteStateBlockChain.getLast().getMyStateHash().getHash());
inventory.put(InventoryItem.blindVoteHash, blindVoteHash);
}

// network
inventory.put(InventoryItem.maxConnections, String.valueOf(maxConnections));
inventory.put(InventoryItem.numConnections, String.valueOf(networkNode.getAllConnections().size()));
inventory.put(InventoryItem.peakNumConnections, String.valueOf(peerManager.getPeakNumConnections()));
inventory.put(InventoryItem.numAllConnectionsLostEvents, String.valueOf(peerManager.getNumAllConnectionsLostEvents()));
inventory.put(InventoryItem.sentBytes, String.valueOf(Statistic.totalSentBytesProperty().get()));
inventory.put(InventoryItem.sentBytesPerSec, String.valueOf(Statistic.totalSentBytesPerSecProperty().get()));
inventory.put(InventoryItem.receivedBytes, String.valueOf(Statistic.totalReceivedBytesProperty().get()));
inventory.put(InventoryItem.receivedBytesPerSec, String.valueOf(Statistic.totalReceivedBytesPerSecProperty().get()));
inventory.put(InventoryItem.receivedMessagesPerSec, String.valueOf(Statistic.numTotalReceivedMessagesPerSecProperty().get()));
inventory.put(InventoryItem.sentMessagesPerSec, String.valueOf(Statistic.numTotalSentMessagesPerSecProperty().get()));

// node
inventory.put(InventoryItem.version, Version.VERSION);
inventory.put(InventoryItem.usedMemory, String.valueOf(Profiler.getUsedMemoryInBytes()));
inventory.put(InventoryItem.jvmStartTime, String.valueOf(ManagementFactory.getRuntimeMXBean().getStartTime()));

log.info("Send inventory {} to {}", inventory, connection.getPeersNodeAddressOptional());
GetInventoryResponse getInventoryResponse = new GetInventoryResponse(inventory);
networkNode.sendMessage(connection, getInventoryResponse);
}
}

public void shutDown() {
networkNode.removeMessageListener(this);
}

public void addPermittedRequestersPubKey(String pubKey) {
permittedRequestersPubKey.add(pubKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.network.p2p.inventory;
package bisq.core.network.p2p.inventory;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.network.NetworkNode;
Expand All @@ -41,11 +41,12 @@ public GetInventoryRequestManager(NetworkNode networkNode) {
}

public void request(NodeAddress nodeAddress,
Consumer<Map<String, Integer>> resultHandler,
Consumer<Map<InventoryItem, String>> resultHandler,
ErrorMessageHandler errorMessageHandler) {
if (requesterMap.containsKey(nodeAddress)) {
log.warn("There is still an open request pending for {}", nodeAddress.getFullAddress());
return;
log.warn("There was still a pending request for {}. We shut it down and make a new request",
nodeAddress.getFullAddress());
requesterMap.get(nodeAddress).shutDown();
}

GetInventoryRequester getInventoryRequester = new GetInventoryRequester(networkNode,
Expand Down
Loading