mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-24 06:49:31 -05:00
synchronize P2PDataStorage to avoid race conditions
This commit is contained in:
parent
93a93d757c
commit
870630b381
@ -232,8 +232,10 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
|
||||
appendOnlyDataStoreService.readFromResources(postFix, () -> appendOnlyDataStoreServiceReady.set(true));
|
||||
protectedDataStoreService.readFromResources(postFix, () -> {
|
||||
synchronized (map) {
|
||||
map.putAll(protectedDataStoreService.getMap());
|
||||
protectedDataStoreServiceReady.set(true);
|
||||
}
|
||||
});
|
||||
resourceDataStoreService.readFromResources(postFix, () -> resourceDataStoreServiceReady.set(true));
|
||||
}
|
||||
@ -241,21 +243,25 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
// Uses synchronous execution on the userThread. Only used by tests. The async methods should be used by app code.
|
||||
@VisibleForTesting
|
||||
public void readFromResourcesSync(String postFix) {
|
||||
synchronized (map) {
|
||||
appendOnlyDataStoreService.readFromResourcesSync(postFix);
|
||||
protectedDataStoreService.readFromResourcesSync(postFix);
|
||||
resourceDataStoreService.readFromResourcesSync(postFix);
|
||||
|
||||
map.putAll(protectedDataStoreService.getMap());
|
||||
}
|
||||
}
|
||||
|
||||
// We get added mailbox message data from MailboxMessageService. We want to add those early so we can get it added
|
||||
// to our excluded keys to reduce initial data response data size.
|
||||
public void addProtectedMailboxStorageEntryToMap(ProtectedStorageEntry protectedStorageEntry) {
|
||||
synchronized (map) {
|
||||
ProtectedStoragePayload protectedStoragePayload = protectedStorageEntry.getProtectedStoragePayload();
|
||||
ByteArray hashOfPayload = get32ByteHashAsByteArray(protectedStoragePayload);
|
||||
map.put(hashOfPayload, protectedStorageEntry);
|
||||
//log.trace("## addProtectedMailboxStorageEntryToMap hashOfPayload={}, map={}", hashOfPayload, printMap());
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RequestData API
|
||||
@ -627,6 +633,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
|
||||
@VisibleForTesting
|
||||
void removeExpiredEntries() {
|
||||
synchronized (map) {
|
||||
// The moment when an object becomes expired will not be synchronous in the network and we could
|
||||
// get add network_messages after the object has expired. To avoid repeated additions of already expired
|
||||
// object when we get it sent from new peers, we don’t remove the sequence number from the map.
|
||||
@ -651,6 +658,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
requestPersistence();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBootstrapped() {
|
||||
removeExpiredEntriesTimer = UserThread.runPeriodically(this::removeExpiredEntries, CHECK_TTL_INTERVAL_SEC);
|
||||
@ -699,6 +707,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
NodeAddress peersNodeAddress = connection.getPeersNodeAddressOptional().get();
|
||||
|
||||
// Backdate all the eligible payloads based on the node that disconnected
|
||||
synchronized (map) {
|
||||
map.values().stream()
|
||||
.filter(protectedStorageEntry -> protectedStorageEntry.getProtectedStoragePayload() instanceof RequiresOwnerIsOnlinePayload)
|
||||
.filter(protectedStorageEntry -> ((RequiresOwnerIsOnlinePayload) protectedStorageEntry.getProtectedStoragePayload()).getOwnerNodeAddress().equals(peersNodeAddress))
|
||||
@ -716,6 +725,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
protectedStorageEntry.backDate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Client API
|
||||
@ -818,6 +828,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
@Nullable NodeAddress sender,
|
||||
@Nullable BroadcastHandler.Listener listener,
|
||||
boolean allowBroadcast) {
|
||||
synchronized (map) {
|
||||
ProtectedStoragePayload protectedStoragePayload = protectedStorageEntry.getProtectedStoragePayload();
|
||||
ByteArray hashOfPayload = get32ByteHashAsByteArray(protectedStoragePayload);
|
||||
|
||||
@ -894,6 +905,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We do not do all checks as it is used for republishing existing mailbox messages from seed nodes which
|
||||
@ -935,7 +947,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
*/
|
||||
public boolean refreshTTL(RefreshOfferMessage refreshTTLMessage,
|
||||
@Nullable NodeAddress sender) {
|
||||
|
||||
synchronized (map) {
|
||||
try {
|
||||
ByteArray hashOfPayload = new ByteArray(refreshTTLMessage.getHashOfPayload());
|
||||
ProtectedStorageEntry storedData = map.get(hashOfPayload);
|
||||
@ -980,6 +992,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a ProtectedStorageEntry from the local P2P data storage. If it is successful, it will broadcast that
|
||||
@ -991,6 +1004,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
*/
|
||||
public boolean remove(ProtectedStorageEntry protectedStorageEntry,
|
||||
@Nullable NodeAddress sender) {
|
||||
synchronized (map) {
|
||||
ProtectedStoragePayload protectedStoragePayload = protectedStorageEntry.getProtectedStoragePayload();
|
||||
ByteArray hashOfPayload = get32ByteHashAsByteArray(protectedStoragePayload);
|
||||
|
||||
@ -1034,6 +1048,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public ProtectedStorageEntry getProtectedStorageEntry(ProtectedStoragePayload protectedStoragePayload,
|
||||
KeyPair ownerStoragePubKey)
|
||||
@ -1107,6 +1122,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
}
|
||||
|
||||
private void removeFromMapAndDataStore(Collection<Map.Entry<ByteArray, ProtectedStorageEntry>> entriesToRemove) {
|
||||
synchronized (map) {
|
||||
if (entriesToRemove.isEmpty())
|
||||
return;
|
||||
|
||||
@ -1132,6 +1148,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
||||
|
||||
hashMapChangedListeners.forEach(e -> e.onRemoved(removedProtectedStorageEntries));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasSequenceNrIncreased(int newSequenceNumber, ByteArray hashOfData) {
|
||||
if (sequenceNumberMap.containsKey(hashOfData)) {
|
||||
|
Loading…
Reference in New Issue
Block a user