mirror of
https://github.com/Qortal/qortal.git
synced 2025-03-14 11:32:32 +00:00
Added duplicate message filter for chat transactions.
This tracks the last 3 unique (unencrypted) messages for each address and fails validation if a duplicate is sent.
This commit is contained in:
parent
2f3e10e15a
commit
b0f963cca7
@ -0,0 +1,69 @@
|
||||
package org.qortal.chat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ChatDuplicateMessageFilter {
|
||||
|
||||
private static ChatDuplicateMessageFilter instance;
|
||||
private volatile boolean isStopping = false;
|
||||
|
||||
private static final int numberOfUniqueMessagesToMonitor = 3;
|
||||
|
||||
// Maintain a short list of recent chat messages for each address, to save having to query the database every time
|
||||
private Map<String, List<String>> recentMessages = new ConcurrentHashMap<>();
|
||||
|
||||
public ChatDuplicateMessageFilter() {
|
||||
|
||||
}
|
||||
|
||||
public static synchronized ChatDuplicateMessageFilter getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ChatDuplicateMessageFilter();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean isDuplicateMessage(String address, String message) {
|
||||
boolean isDuplicateMessage;
|
||||
boolean messagesUpdated = false;
|
||||
|
||||
// Add timestamp to array for address
|
||||
List<String> messages = new ArrayList<>();
|
||||
if (this.recentMessages.containsKey(address)) {
|
||||
messages = this.recentMessages.get(address);
|
||||
}
|
||||
|
||||
if (!messages.contains(message)) {
|
||||
messages.add(message);
|
||||
this.recentMessages.put(address, messages);
|
||||
messagesUpdated = true;
|
||||
isDuplicateMessage = false;
|
||||
}
|
||||
else {
|
||||
// Can't add message because it already exists
|
||||
isDuplicateMessage = true;
|
||||
}
|
||||
|
||||
// Ensure we're not tracking more messages than intended
|
||||
while (messages.size() > numberOfUniqueMessagesToMonitor) {
|
||||
messages.remove(0);
|
||||
messagesUpdated = true;
|
||||
}
|
||||
|
||||
if (messagesUpdated) {
|
||||
if (messages.size() > 0) {
|
||||
this.recentMessages.put(address, messages);
|
||||
}
|
||||
else {
|
||||
this.recentMessages.remove(address);
|
||||
}
|
||||
}
|
||||
|
||||
return isDuplicateMessage;
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.account.PublicKeyAccount;
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.chat.ChatDuplicateMessageFilter;
|
||||
import org.qortal.chat.ChatRateLimiter;
|
||||
import org.qortal.crypto.Crypto;
|
||||
import org.qortal.crypto.MemoryPoW;
|
||||
@ -19,6 +20,7 @@ import org.qortal.repository.Repository;
|
||||
import org.qortal.transform.TransformationException;
|
||||
import org.qortal.transform.transaction.ChatTransactionTransformer;
|
||||
import org.qortal.transform.transaction.TransactionTransformer;
|
||||
import org.qortal.utils.Base58;
|
||||
|
||||
public class ChatTransaction extends Transaction {
|
||||
|
||||
@ -166,6 +168,14 @@ public class ChatTransaction extends Transaction {
|
||||
if (rateLimiter.isAddressAboveRateLimit(chatTransactionData.getSender()))
|
||||
return ValidationResult.ADDRESS_ABOVE_RATE_LIMIT;
|
||||
|
||||
// Check for duplicate messages (unencrypted text messages only)
|
||||
if (!chatTransactionData.getIsEncrypted() && chatTransactionData.getIsText()) {
|
||||
ChatDuplicateMessageFilter duplicateFilter = ChatDuplicateMessageFilter.getInstance();
|
||||
String message58 = Base58.encode(chatTransactionData.getData());
|
||||
if (duplicateFilter.isDuplicateMessage(chatTransactionData.getSender(), message58))
|
||||
return ValidationResult.DUPLICATE_MESSAGE;
|
||||
}
|
||||
|
||||
return ValidationResult.OK;
|
||||
}
|
||||
|
||||
|
@ -249,6 +249,7 @@ public abstract class Transaction {
|
||||
INVALID_TIMESTAMP_SIGNATURE(95),
|
||||
ADDRESS_IN_BLACKLIST(96),
|
||||
ADDRESS_ABOVE_RATE_LIMIT(97),
|
||||
DUPLICATE_MESSAGE(98),
|
||||
INVALID_BUT_OK(999),
|
||||
NOT_YET_RELEASED(1000);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user