diff --git a/core/src/main/java/bisq/core/proto/network/CoreNetworkProtoResolver.java b/core/src/main/java/bisq/core/proto/network/CoreNetworkProtoResolver.java
index 675011cec3d..afa177c6733 100644
--- a/core/src/main/java/bisq/core/proto/network/CoreNetworkProtoResolver.java
+++ b/core/src/main/java/bisq/core/proto/network/CoreNetworkProtoResolver.java
@@ -64,6 +64,8 @@
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;
@@ -224,6 +226,11 @@ public NetworkEnvelope fromProto(protobuf.NetworkEnvelope proto) throws Protobuf
case BUNDLE_OF_ENVELOPES:
return BundleOfEnvelopes.fromProto(proto.getBundleOfEnvelopes(), this, messageVersion);
+ case GET_INVENTORY_REQUEST:
+ return GetInventoryRequest.fromProto(proto.getGetInventoryRequest(), messageVersion);
+ case GET_INVENTORY_RESPONSE:
+ return GetInventoryResponse.fromProto(proto.getGetInventoryResponse(), messageVersion);
+
default:
throw new ProtobufferException("Unknown proto message case (PB.NetworkEnvelope). messageCase=" +
proto.getMessageCase() + "; proto raw data=" + proto.toString());
diff --git a/p2p/src/main/java/bisq/network/p2p/P2PService.java b/p2p/src/main/java/bisq/network/p2p/P2PService.java
index 8716c81d9d1..76396125462 100644
--- a/p2p/src/main/java/bisq/network/p2p/P2PService.java
+++ b/p2p/src/main/java/bisq/network/p2p/P2PService.java
@@ -19,6 +19,8 @@
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;
@@ -111,6 +113,8 @@ 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;
@@ -157,7 +161,9 @@ public P2PService(NetworkNode networkNode,
SeedNodeRepository seedNodeRepository,
Socks5ProxyProvider socks5ProxyProvider,
EncryptionService encryptionService,
- KeyRing keyRing) {
+ KeyRing keyRing,
+ GetInventoryRequestHandler getInventoryRequestHandler,
+ GetInventoryRequestManager getInventoryRequestManager) {
this.networkNode = networkNode;
this.peerManager = peerManager;
this.p2PDataStorage = p2PDataStorage;
@@ -169,6 +175,8 @@ public P2PService(NetworkNode networkNode,
this.socks5ProxyProvider = socks5ProxyProvider;
this.encryptionService = encryptionService;
this.keyRing = keyRing;
+ this.getInventoryRequestHandler = getInventoryRequestHandler;
+ this.getInventoryRequestManager = getInventoryRequestManager;
this.networkNode.addConnectionListener(this);
this.networkNode.addMessageListener(this);
@@ -259,6 +267,9 @@ private void doShutDown() {
} else {
shutDownResultHandlers.forEach(Runnable::run);
}
+
+ getInventoryRequestHandler.shutDown();
+ getInventoryRequestManager.shutDown();
}
diff --git a/p2p/src/main/java/bisq/network/p2p/inventory/GetInventoryRequestHandler.java b/p2p/src/main/java/bisq/network/p2p/inventory/GetInventoryRequestHandler.java
new file mode 100644
index 00000000000..8695e71b37e
--- /dev/null
+++ b/p2p/src/main/java/bisq/network/p2p/inventory/GetInventoryRequestHandler.java
@@ -0,0 +1,81 @@
+/*
+ * 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 .
+ */
+
+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 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);
+ }
+}
diff --git a/p2p/src/main/java/bisq/network/p2p/inventory/GetInventoryRequestManager.java b/p2p/src/main/java/bisq/network/p2p/inventory/GetInventoryRequestManager.java
new file mode 100644
index 00000000000..755f2912c03
--- /dev/null
+++ b/p2p/src/main/java/bisq/network/p2p/inventory/GetInventoryRequestManager.java
@@ -0,0 +1,69 @@
+/*
+ * 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 .
+ */
+
+package bisq.network.p2p.inventory;
+
+import bisq.network.p2p.NodeAddress;
+import bisq.network.p2p.network.NetworkNode;
+
+import bisq.common.handlers.ErrorMessageHandler;
+
+import javax.inject.Inject;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class GetInventoryRequestManager {
+ private final NetworkNode networkNode;
+ private final Map requesterMap = new HashMap<>();
+
+ @Inject
+ public GetInventoryRequestManager(NetworkNode networkNode) {
+ this.networkNode = networkNode;
+ }
+
+ public void request(NodeAddress nodeAddress,
+ Consumer