Move inventory package to core as we want to include other domain data as well like DAO state

Add more data to inventory map and change type of value to String.
This commit is contained in:
chimp1984 2020-10-14 21:45:35 -05:00
parent 3521619e03
commit 9dab186086
No known key found for this signature in database
GPG Key ID: 9801B4EC591F90E3
12 changed files with 217 additions and 117 deletions

View File

@ -0,0 +1,176 @@
/*
* 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.btc.wallet.BtcWalletService;
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.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;
import bisq.common.proto.network.NetworkEnvelope;
import bisq.common.util.MathUtils;
import bisq.common.util.Profiler;
import bisq.common.util.Utilities;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class GetInventoryRequestHandler implements MessageListener {
private final NetworkNode networkNode;
private final P2PDataStorage p2PDataStorage;
private final DaoStateService daoStateService;
private final BtcWalletService btcWalletService;
private final DaoStateMonitoringService daoStateMonitoringService;
private final ProposalStateMonitoringService proposalStateMonitoringService;
private final BlindVoteStateMonitoringService blindVoteStateMonitoringService;
@Inject
public GetInventoryRequestHandler(NetworkNode networkNode,
P2PDataStorage p2PDataStorage,
DaoStateService daoStateService,
BtcWalletService btcWalletService,
DaoStateMonitoringService daoStateMonitoringService,
ProposalStateMonitoringService proposalStateMonitoringService,
BlindVoteStateMonitoringService blindVoteStateMonitoringService) {
this.networkNode = networkNode;
this.p2PDataStorage = p2PDataStorage;
this.daoStateService = daoStateService;
this.btcWalletService = btcWalletService;
this.daoStateMonitoringService = daoStateMonitoringService;
this.proposalStateMonitoringService = proposalStateMonitoringService;
this.blindVoteStateMonitoringService = blindVoteStateMonitoringService;
this.networkNode.addMessageListener(this);
}
@Override
public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if (networkEnvelope instanceof GetInventoryRequest) {
GetInventoryRequest getInventoryRequest = (GetInventoryRequest) networkEnvelope;
Map<String, Integer> dataObjects = new HashMap<>();
p2PDataStorage.getMapForDataResponse(getInventoryRequest.getVersion()).values().stream()
.map(e -> e.getClass().getSimpleName())
.forEach(className -> {
dataObjects.putIfAbsent(className, 0);
int prev = dataObjects.get(className);
dataObjects.put(className, prev + 1);
});
p2PDataStorage.getMap().values().stream()
.map(ProtectedStorageEntry::getProtectedStoragePayload)
.filter(Objects::nonNull)
.map(e -> e.getClass().getSimpleName())
.forEach(className -> {
dataObjects.putIfAbsent(className, 0);
int prev = dataObjects.get(className);
dataObjects.put(className, prev + 1);
});
Map<String, String> inventory = new HashMap<>();
dataObjects.forEach((key, value) -> inventory.put(key, String.valueOf(value)));
// DAO data
int numBsqBlocks = daoStateService.getBlocks().size();
inventory.put("numBsqBlocks", String.valueOf(numBsqBlocks));
int daoStateChainHeight = daoStateService.getChainHeight();
inventory.put("daoStateChainHeight", String.valueOf(daoStateChainHeight));
int walletChainHeight = btcWalletService.getBestChainHeight();
inventory.put("walletChainHeight", String.valueOf(walletChainHeight));
LinkedList<DaoStateBlock> daoStateBlockChain = daoStateMonitoringService.getDaoStateBlockChain();
if (!daoStateBlockChain.isEmpty()) {
String daoStateHash = Utilities.bytesAsHexString(daoStateBlockChain.getLast().getMyStateHash().getHash());
inventory.put("daoStateHash", daoStateHash);
} else {
inventory.put("daoStateHash", "n/a");
}
LinkedList<ProposalStateBlock> proposalStateBlockChain = proposalStateMonitoringService.getProposalStateBlockChain();
if (!proposalStateBlockChain.isEmpty()) {
String proposalHash = Utilities.bytesAsHexString(proposalStateBlockChain.getLast().getMyStateHash().getHash());
inventory.put("proposalHash", proposalHash);
} else {
inventory.put("proposalHash", "n/a");
}
LinkedList<BlindVoteStateBlock> blindVoteStateBlockChain = blindVoteStateMonitoringService.getBlindVoteStateBlockChain();
if (!blindVoteStateBlockChain.isEmpty()) {
String blindVoteHash = Utilities.bytesAsHexString(blindVoteStateBlockChain.getLast().getMyStateHash().getHash());
inventory.put("blindVoteHash", blindVoteHash);
} else {
inventory.put("blindVoteHash", "n/a");
}
// P2P network data
int numConnections = networkNode.getAllConnections().size();
inventory.put("numConnections", String.valueOf(numConnections));
long sentBytes = Statistic.totalSentBytesProperty().get();
inventory.put("sentBytes", String.valueOf(sentBytes));
long receivedBytes = Statistic.totalReceivedBytesProperty().get();
inventory.put("receivedBytes", String.valueOf(receivedBytes));
double receivedMessagesPerSec = MathUtils.roundDouble(Statistic.numTotalReceivedMessagesPerSecProperty().get(), 2);
inventory.put("receivedMessagesPerSec", String.valueOf(receivedMessagesPerSec));
double sentMessagesPerSec = MathUtils.roundDouble(Statistic.numTotalSentMessagesPerSecProperty().get(), 2);
inventory.put("sentMessagesPerSec", String.valueOf(sentMessagesPerSec));
// JVM info
long usedMemory = Profiler.getUsedMemoryInMB();
inventory.put("usedMemory", String.valueOf(usedMemory));
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
long startTime = runtimeBean.getStartTime();
inventory.put("jvmStartTime", String.valueOf(startTime));
log.info("Send inventory {} to {}", inventory, connection.getPeersNodeAddressOptional());
GetInventoryResponse getInventoryResponse = new GetInventoryResponse(inventory);
networkNode.sendMessage(connection, getInventoryResponse);
}
}
public void shutDown() {
networkNode.removeMessageListener(this);
}
}

View File

@ -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;
@ -41,7 +41,7 @@ public class GetInventoryRequestManager {
}
public void request(NodeAddress nodeAddress,
Consumer<Map<String, Integer>> resultHandler,
Consumer<Map<String, String>> resultHandler,
ErrorMessageHandler errorMessageHandler) {
if (requesterMap.containsKey(nodeAddress)) {
log.warn("There is still an open request pending for {}", nodeAddress.getFullAddress());

View File

@ -15,11 +15,12 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.network.p2p.inventory;
package bisq.core.network.p2p.inventory;
import bisq.core.network.p2p.inventory.messages.GetInventoryRequest;
import bisq.core.network.p2p.inventory.messages.GetInventoryResponse;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.inventory.messages.GetInventoryRequest;
import bisq.network.p2p.inventory.messages.GetInventoryResponse;
import bisq.network.p2p.network.Connection;
import bisq.network.p2p.network.MessageListener;
import bisq.network.p2p.network.NetworkNode;
@ -41,13 +42,13 @@ public class GetInventoryRequester implements MessageListener {
private final NetworkNode networkNode;
private final NodeAddress nodeAddress;
private final Consumer<Map<String, Integer>> resultHandler;
private final Consumer<Map<String, String>> resultHandler;
private final ErrorMessageHandler errorMessageHandler;
private Timer timer;
public GetInventoryRequester(NetworkNode networkNode,
NodeAddress nodeAddress,
Consumer<Map<String, Integer>> resultHandler,
Consumer<Map<String, String>> resultHandler,
ErrorMessageHandler errorMessageHandler) {
this.networkNode = networkNode;
this.nodeAddress = nodeAddress;
@ -72,7 +73,7 @@ public class GetInventoryRequester implements MessageListener {
connection.getPeersNodeAddressOptional().ifPresent(peer -> {
if (peer.equals(nodeAddress)) {
GetInventoryResponse getInventoryResponse = (GetInventoryResponse) networkEnvelope;
resultHandler.accept(getInventoryResponse.getNumPayloadsMap());
resultHandler.accept(getInventoryResponse.getInventory());
shutDown();
}
});

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.network.p2p.inventory.messages;
package bisq.core.network.p2p.inventory.messages;
import bisq.common.app.Version;

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.network.p2p.inventory.messages;
package bisq.core.network.p2p.inventory.messages;
import bisq.common.app.Version;
import bisq.common.proto.network.NetworkEnvelope;
@ -26,31 +26,31 @@ import lombok.Value;
@Value
public class GetInventoryResponse extends NetworkEnvelope {
private final Map<String, Integer> numPayloadsMap;
private final Map<String, String> inventory;
public GetInventoryResponse(Map<String, Integer> numPayloadsMap) {
this(numPayloadsMap, Version.getP2PMessageVersion());
public GetInventoryResponse(Map<String, String> inventory) {
this(inventory, Version.getP2PMessageVersion());
}
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
private GetInventoryResponse(Map<String, Integer> numPayloadsMap, int messageVersion) {
private GetInventoryResponse(Map<String, String> inventory, int messageVersion) {
super(messageVersion);
this.numPayloadsMap = numPayloadsMap;
this.inventory = inventory;
}
@Override
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
return getNetworkEnvelopeBuilder()
.setGetInventoryResponse(protobuf.GetInventoryResponse.newBuilder()
.putAllNumPayloadsMap(numPayloadsMap))
.putAllInventory(inventory))
.build();
}
public static GetInventoryResponse fromProto(protobuf.GetInventoryResponse proto, int messageVersion) {
return new GetInventoryResponse(proto.getNumPayloadsMapMap(), messageVersion);
return new GetInventoryResponse(proto.getInventoryMap(), messageVersion);
}
}

View File

@ -34,6 +34,8 @@ import bisq.core.dao.node.messages.GetBlocksRequest;
import bisq.core.dao.node.messages.GetBlocksResponse;
import bisq.core.dao.node.messages.NewBlockBroadcastMessage;
import bisq.core.filter.Filter;
import bisq.core.network.p2p.inventory.messages.GetInventoryRequest;
import bisq.core.network.p2p.inventory.messages.GetInventoryResponse;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.messages.OfferAvailabilityRequest;
import bisq.core.offer.messages.OfferAvailabilityResponse;
@ -64,8 +66,6 @@ import bisq.network.p2p.AckMessage;
import bisq.network.p2p.BundleOfEnvelopes;
import bisq.network.p2p.CloseConnectionMessage;
import bisq.network.p2p.PrefixedSealedAndSignedMessage;
import bisq.network.p2p.inventory.messages.GetInventoryRequest;
import bisq.network.p2p.inventory.messages.GetInventoryResponse;
import bisq.network.p2p.peers.getdata.messages.GetDataResponse;
import bisq.network.p2p.peers.getdata.messages.GetUpdatedDataRequest;
import bisq.network.p2p.peers.getdata.messages.PreliminaryGetDataRequest;

View File

@ -18,12 +18,12 @@
package bisq.inventory;
import bisq.core.network.p2p.inventory.GetInventoryRequestManager;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
import bisq.core.proto.network.CoreNetworkProtoResolver;
import bisq.network.p2p.NetworkNodeProvider;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.inventory.GetInventoryRequestManager;
import bisq.network.p2p.network.NetworkNode;
import bisq.network.p2p.network.SetupListener;
@ -150,7 +150,7 @@ public class InventoryMonitor {
log.info("nodeAddress={}, result={}", nodeAddress, result.toString());
long responseTime = System.currentTimeMillis();
requestInfo.setResponseTime(responseTime);
requestInfo.setResult(result);
requestInfo.setInventory(result);
String json = Utilities.objectToJson(requestInfo);
jsonFileManagerByNodeAddress.get(nodeAddress).writeToDisc(json, String.valueOf(responseTime));
},
@ -175,7 +175,7 @@ public class InventoryMonitor {
@Setter
private long responseTime;
@Setter
private Map<String, Integer> result;
private Map<String, String> inventory;
@Setter
private String errorMessage;

View File

@ -19,8 +19,6 @@ package bisq.network.p2p;
import bisq.network.Socks5ProxyProvider;
import bisq.network.crypto.EncryptionService;
import bisq.network.p2p.inventory.GetInventoryRequestHandler;
import bisq.network.p2p.inventory.GetInventoryRequestManager;
import bisq.network.p2p.messaging.DecryptedMailboxListener;
import bisq.network.p2p.network.CloseConnectionReason;
import bisq.network.p2p.network.Connection;
@ -113,8 +111,6 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
private final SeedNodeRepository seedNodeRepository;
private final EncryptionService encryptionService;
private final KeyRing keyRing;
private final GetInventoryRequestHandler getInventoryRequestHandler;
private final GetInventoryRequestManager getInventoryRequestManager;
private final NetworkNode networkNode;
private final PeerManager peerManager;
@ -161,9 +157,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
SeedNodeRepository seedNodeRepository,
Socks5ProxyProvider socks5ProxyProvider,
EncryptionService encryptionService,
KeyRing keyRing,
GetInventoryRequestHandler getInventoryRequestHandler,
GetInventoryRequestManager getInventoryRequestManager) {
KeyRing keyRing) {
this.networkNode = networkNode;
this.peerManager = peerManager;
this.p2PDataStorage = p2PDataStorage;
@ -175,8 +169,6 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
this.socks5ProxyProvider = socks5ProxyProvider;
this.encryptionService = encryptionService;
this.keyRing = keyRing;
this.getInventoryRequestHandler = getInventoryRequestHandler;
this.getInventoryRequestManager = getInventoryRequestManager;
this.networkNode.addConnectionListener(this);
this.networkNode.addMessageListener(this);
@ -267,9 +259,6 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
} else {
shutDownResultHandlers.forEach(Runnable::run);
}
getInventoryRequestHandler.shutDown();
getInventoryRequestManager.shutDown();
}

View File

@ -1,81 +0,0 @@
/*
* 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.network.p2p.inventory;
import bisq.network.p2p.inventory.messages.GetInventoryRequest;
import bisq.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.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.ProtectedStorageEntry;
import bisq.common.proto.network.NetworkEnvelope;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class GetInventoryRequestHandler implements MessageListener {
private final NetworkNode networkNode;
private final P2PDataStorage p2PDataStorage;
@Inject
public GetInventoryRequestHandler(NetworkNode networkNode, P2PDataStorage p2PDataStorage) {
this.networkNode = networkNode;
this.p2PDataStorage = p2PDataStorage;
networkNode.addMessageListener(this);
}
@Override
public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if (networkEnvelope instanceof GetInventoryRequest) {
GetInventoryRequest getInventoryRequest = (GetInventoryRequest) networkEnvelope;
Map<String, Integer> numPayloadsByClassName = new HashMap<>();
p2PDataStorage.getMapForDataResponse(getInventoryRequest.getVersion()).values().stream()
.map(e -> e.getClass().getSimpleName())
.forEach(className -> {
numPayloadsByClassName.putIfAbsent(className, 0);
int prev = numPayloadsByClassName.get(className);
numPayloadsByClassName.put(className, prev + 1);
});
p2PDataStorage.getMap().values().stream()
.map(ProtectedStorageEntry::getProtectedStoragePayload)
.filter(Objects::nonNull)
.map(e -> e.getClass().getSimpleName())
.forEach(className -> {
numPayloadsByClassName.putIfAbsent(className, 0);
int prev = numPayloadsByClassName.get(className);
numPayloadsByClassName.put(className, prev + 1);
});
GetInventoryResponse getInventoryResponse = new GetInventoryResponse(numPayloadsByClassName);
networkNode.sendMessage(connection, getInventoryResponse);
}
}
public void shutDown() {
networkNode.removeMessageListener(this);
}
}

View File

@ -147,7 +147,7 @@ message GetInventoryRequest {
}
message GetInventoryResponse {
map<string, uint32> num_payloads_map = 1;
map<string, string> inventory = 1;
}
// offer

View File

@ -19,6 +19,7 @@ package bisq.seednode;
import bisq.core.app.misc.AppSetup;
import bisq.core.app.misc.AppSetupWithP2PAndDAO;
import bisq.core.network.p2p.inventory.GetInventoryRequestHandler;
import com.google.inject.Injector;
@ -30,6 +31,7 @@ public class SeedNode {
@Setter
private Injector injector;
private AppSetup appSetup;
private GetInventoryRequestHandler getInventoryRequestHandler;
public SeedNode() {
}
@ -37,5 +39,11 @@ public class SeedNode {
public void startApplication() {
appSetup = injector.getInstance(AppSetupWithP2PAndDAO.class);
appSetup.start();
getInventoryRequestHandler = injector.getInstance(GetInventoryRequestHandler.class);
}
public void shutDown() {
getInventoryRequestHandler.shutDown();
}
}

View File

@ -27,6 +27,7 @@ import bisq.common.UserThread;
import bisq.common.app.AppModule;
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.handlers.ResultHandler;
import lombok.extern.slf4j.Slf4j;
@ -39,7 +40,7 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
super("Bisq Seednode", "bisq-seednode", "bisq_seednode", VERSION);
}
public static void main(String[] args) throws Exception {
public static void main(String[] args) {
log.info("SeedNode.VERSION: " + VERSION);
new SeedNodeMain().execute(args);
}
@ -138,4 +139,10 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
}
});
}
@Override
public void gracefulShutDown(ResultHandler resultHandler) {
seedNode.shutDown();
super.gracefulShutDown(resultHandler);
}
}