diff --git a/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java index b7678c7fa0c..9b8a0daab8c 100644 --- a/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java @@ -138,9 +138,13 @@ public String getDisplayString() { @Getter private final AccountAgeWitnessUtils accountAgeWitnessUtils; - @Getter private final Map accountAgeWitnessMap = new HashMap<>(); + // The accountAgeWitnessMap is very large (70k items) and access is a bit expensive. We usually only access less + // than 100 items, those who have offers online. So we use a cache for a fast lookup and only if + // not found there we use the accountAgeWitnessMap and put then the new item into our cache. + private final Map accountAgeWitnessCache = new HashMap<>(); + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -233,8 +237,17 @@ public void addToMap(AccountAgeWitness accountAgeWitness) { public void publishMyAccountAgeWitness(PaymentAccountPayload paymentAccountPayload) { AccountAgeWitness accountAgeWitness = getMyWitness(paymentAccountPayload); - if (!accountAgeWitnessMap.containsKey(accountAgeWitness.getHashAsByteArray())) + P2PDataStorage.ByteArray hash = accountAgeWitness.getHashAsByteArray(); + + // We use first our fast lookup cache. If its in accountAgeWitnessCache it is also in accountAgeWitnessMap + // and we do not publish. + if (accountAgeWitnessCache.containsKey(hash)) { + return; + } + + if (!accountAgeWitnessMap.containsKey(hash)) { p2PService.addPersistableNetworkPayload(accountAgeWitness, false); + } } public byte[] getPeerAccountAgeWitnessHash(Trade trade) { @@ -284,12 +297,21 @@ private Optional findTradePeerWitness(Trade trade) { private Optional getWitnessByHash(byte[] hash) { P2PDataStorage.ByteArray hashAsByteArray = new P2PDataStorage.ByteArray(hash); - final boolean containsKey = accountAgeWitnessMap.containsKey(hashAsByteArray); - if (!containsKey) - log.debug("hash not found in accountAgeWitnessMap"); + // First we look up in our fast lookup cache + if (accountAgeWitnessCache.containsKey(hashAsByteArray)) { + return Optional.of(accountAgeWitnessCache.get(hashAsByteArray)); + } + + if (accountAgeWitnessMap.containsKey(hashAsByteArray)) { + AccountAgeWitness accountAgeWitness = accountAgeWitnessMap.get(hashAsByteArray); + + // We add it to our fast lookup cache + accountAgeWitnessCache.put(hashAsByteArray, accountAgeWitness); - return accountAgeWitnessMap.containsKey(hashAsByteArray) ? - Optional.of(accountAgeWitnessMap.get(hashAsByteArray)) : Optional.empty(); + return Optional.of(accountAgeWitness); + } + + return Optional.empty(); } private Optional getWitnessByHashAsHex(String hashAsHex) {