mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 15:10:44 +01:00
onUpdatedDataReceived must be called in the correct order.
We cannot use a listener at RequestDataManager as the order is not defined if doing so. So we use P2PService as our controlling entity to call further clients in the correct order.
This commit is contained in:
parent
3757ec36f7
commit
9041bf4938
3 changed files with 36 additions and 38 deletions
|
@ -147,7 +147,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
|
|
||||||
this.networkNode.addConnectionListener(this);
|
this.networkNode.addConnectionListener(this);
|
||||||
this.networkNode.addMessageListener(this);
|
this.networkNode.addMessageListener(this);
|
||||||
this.requestDataManager.addListener(this);
|
this.requestDataManager.setListener(this);
|
||||||
|
|
||||||
// We need to have both the initial data delivered and the hidden service published
|
// We need to have both the initial data delivered and the hidden service published
|
||||||
networkReadyBinding = EasyBind.combine(hiddenServicePublished, preliminaryDataReceived,
|
networkReadyBinding = EasyBind.combine(hiddenServicePublished, preliminaryDataReceived,
|
||||||
|
@ -317,6 +317,11 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
public void onUpdatedDataReceived() {
|
public void onUpdatedDataReceived() {
|
||||||
if (!isBootstrapped) {
|
if (!isBootstrapped) {
|
||||||
isBootstrapped = true;
|
isBootstrapped = true;
|
||||||
|
// We don't use a listener at mailboxMessageService as we require the correct
|
||||||
|
// order of execution. The p2pServiceListeners must be called after
|
||||||
|
// mailboxMessageService.onUpdatedDataReceived.
|
||||||
|
mailboxMessageService.onUpdatedDataReceived();
|
||||||
|
|
||||||
p2pServiceListeners.forEach(P2PServiceListener::onUpdatedDataReceived);
|
p2pServiceListeners.forEach(P2PServiceListener::onUpdatedDataReceived);
|
||||||
p2PDataStorage.onBootstrapComplete();
|
p2PDataStorage.onBootstrapComplete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class MailboxMessageService implements SetupListener, RequestDataManager.Listener, HashMapChangedListener,
|
public class MailboxMessageService implements SetupListener, HashMapChangedListener,
|
||||||
PersistedDataHost {
|
PersistedDataHost {
|
||||||
private static final long REPUBLISH_DELAY_SEC = TimeUnit.MINUTES.toSeconds(2);
|
private static final long REPUBLISH_DELAY_SEC = TimeUnit.MINUTES.toSeconds(2);
|
||||||
|
|
||||||
|
@ -155,7 +155,6 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.republishMailboxEntries = republishMailboxEntries;
|
this.republishMailboxEntries = republishMailboxEntries;
|
||||||
|
|
||||||
this.requestDataManager.addListener(this);
|
|
||||||
this.networkNode.addSetupListener(this);
|
this.networkNode.addSetupListener(this);
|
||||||
|
|
||||||
this.persistenceManager.initialize(mailboxMessageList, PersistenceManager.Source.PRIVATE_LOW_PRIO);
|
this.persistenceManager.initialize(mailboxMessageList, PersistenceManager.Source.PRIVATE_LOW_PRIO);
|
||||||
|
@ -224,6 +223,19 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
|
||||||
// API
|
// API
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// We don't listen on requestDataManager directly as we require the correct
|
||||||
|
// order of execution. The p2pService is handling the correct order of execution and we get called
|
||||||
|
// directly from there.
|
||||||
|
public void onUpdatedDataReceived() {
|
||||||
|
if (!isBootstrapped) {
|
||||||
|
isBootstrapped = true;
|
||||||
|
// Only now we start listening and processing. The p2PDataStorage is our cache for data we have received
|
||||||
|
// after the hidden service was ready.
|
||||||
|
addHashMapChangedListenerAndApply();
|
||||||
|
maybeRepublishMailBoxMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void sendEncryptedMailboxMessage(NodeAddress peer,
|
public void sendEncryptedMailboxMessage(NodeAddress peer,
|
||||||
PubKeyRing peersPubKeyRing,
|
PubKeyRing peersPubKeyRing,
|
||||||
MailboxMessage mailboxMessage,
|
MailboxMessage mailboxMessage,
|
||||||
|
@ -238,8 +250,9 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
|
||||||
"My node address must not be null at sendEncryptedMailboxMessage");
|
"My node address must not be null at sendEncryptedMailboxMessage");
|
||||||
checkArgument(!keyRing.getPubKeyRing().equals(peersPubKeyRing), "We got own keyring instead of that from peer");
|
checkArgument(!keyRing.getPubKeyRing().equals(peersPubKeyRing), "We got own keyring instead of that from peer");
|
||||||
|
|
||||||
if (!isBootstrapped)
|
if (!isBootstrapped) {
|
||||||
throw new NetworkNotReadyException();
|
throw new NetworkNotReadyException();
|
||||||
|
}
|
||||||
|
|
||||||
if (networkNode.getAllConnections().isEmpty()) {
|
if (networkNode.getAllConnections().isEmpty()) {
|
||||||
sendMailboxMessageListener.onFault("There are no P2P network nodes connected. " +
|
sendMailboxMessageListener.onFault("There are no P2P network nodes connected. " +
|
||||||
|
@ -349,30 +362,6 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RequestDataManager.Listener implementation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPreliminaryDataReceived() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdatedDataReceived() {
|
|
||||||
if (!isBootstrapped) {
|
|
||||||
isBootstrapped = true;
|
|
||||||
// Only now we start listening and processing. The p2PDataStorage is our cache for data we have received
|
|
||||||
// after the hidden service was ready.
|
|
||||||
addHashMapChangedListenerAndApply();
|
|
||||||
maybeRepublishMailBoxMessages();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDataReceived() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// HashMapChangedListener implementation for ProtectedStorageEntry items
|
// HashMapChangedListener implementation for ProtectedStorageEntry items
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -40,11 +40,9 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -53,6 +51,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RequestDataManager implements MessageListener, ConnectionListener, PeerManager.Listener {
|
public class RequestDataManager implements MessageListener, ConnectionListener, PeerManager.Listener {
|
||||||
|
@ -91,7 +90,10 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
private final P2PDataStorage dataStorage;
|
private final P2PDataStorage dataStorage;
|
||||||
private final PeerManager peerManager;
|
private final PeerManager peerManager;
|
||||||
private final List<NodeAddress> seedNodeAddresses;
|
private final List<NodeAddress> seedNodeAddresses;
|
||||||
private final Set<Listener> listeners = new HashSet<>();
|
|
||||||
|
// As we use Guice injection we cannot set the listener in our constructor but the P2PService calls the setListener
|
||||||
|
// in it's constructor so we can guarantee it is not null.
|
||||||
|
private Listener listener;
|
||||||
|
|
||||||
private final Map<NodeAddress, RequestDataHandler> handlerMap = new HashMap<>();
|
private final Map<NodeAddress, RequestDataHandler> handlerMap = new HashMap<>();
|
||||||
private final Map<String, GetDataRequestHandler> getDataRequestHandlers = new HashMap<>();
|
private final Map<String, GetDataRequestHandler> getDataRequestHandlers = new HashMap<>();
|
||||||
|
@ -147,8 +149,10 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
// API
|
// API
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void addListener(Listener listener) {
|
// We only support one listener as P2PService will manage calls on other clients in the correct order of execution.
|
||||||
listeners.add(listener);
|
// The listener is set from the P2PService constructor so we can guarantee it is not null.
|
||||||
|
public void setListener(Listener listener) {
|
||||||
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requestPreliminaryData() {
|
public boolean requestPreliminaryData() {
|
||||||
|
@ -334,16 +338,16 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
// We delay because it can be that we get the HS published before we receive the
|
// We delay because it can be that we get the HS published before we receive the
|
||||||
// preliminary data and the onPreliminaryDataReceived call triggers the
|
// preliminary data and the onPreliminaryDataReceived call triggers the
|
||||||
// dataUpdateRequested set to true, so we would also call the onUpdatedDataReceived.
|
// dataUpdateRequested set to true, so we would also call the onUpdatedDataReceived.
|
||||||
UserThread.runAfter(() -> listeners.forEach(Listener::onPreliminaryDataReceived), 100, TimeUnit.MILLISECONDS);
|
UserThread.runAfter(checkNotNull(listener)::onPreliminaryDataReceived, 100, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Later we get a response from requestUpdatesData
|
// 2. Later we get a response from requestUpdatesData
|
||||||
if (dataUpdateRequested) {
|
if (dataUpdateRequested) {
|
||||||
dataUpdateRequested = false;
|
dataUpdateRequested = false;
|
||||||
listeners.forEach(Listener::onUpdatedDataReceived);
|
checkNotNull(listener).onUpdatedDataReceived();
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners.forEach(Listener::onDataReceived);
|
checkNotNull(listener).onDataReceived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -371,9 +375,9 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
// Notify listeners
|
// Notify listeners
|
||||||
if (!nodeAddressOfPreliminaryDataRequest.isPresent()) {
|
if (!nodeAddressOfPreliminaryDataRequest.isPresent()) {
|
||||||
if (peerManager.isSeedNode(nodeAddress)) {
|
if (peerManager.isSeedNode(nodeAddress)) {
|
||||||
listeners.forEach(Listener::onNoSeedNodeAvailable);
|
checkNotNull(listener).onNoSeedNodeAvailable();
|
||||||
} else {
|
} else {
|
||||||
listeners.forEach(Listener::onNoPeersAvailable);
|
checkNotNull(listener).onNoPeersAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue