forked from Qortal/qortal
Limit to 250 CHAT messages per hour per account.
This commit is contained in:
parent
bb74b2d4f6
commit
2a4ac1ed24
@ -111,6 +111,12 @@ public class Settings {
|
|||||||
private int maxUnconfirmedPerAccount = 25;
|
private int maxUnconfirmedPerAccount = 25;
|
||||||
/** Max milliseconds into future for accepting new, unconfirmed transactions */
|
/** Max milliseconds into future for accepting new, unconfirmed transactions */
|
||||||
private int maxTransactionTimestampFuture = 30 * 60 * 1000; // milliseconds
|
private int maxTransactionTimestampFuture = 30 * 60 * 1000; // milliseconds
|
||||||
|
|
||||||
|
/** Maximum number of CHAT transactions allowed per account in recent timeframe */
|
||||||
|
private int maxRecentChatMessagesPerAccount = 250;
|
||||||
|
/** Maximum age of a CHAT transaction to be considered 'recent' */
|
||||||
|
private long recentChatMessagesMaxAge = 60 * 60 * 1000L; // milliseconds
|
||||||
|
|
||||||
/** Whether we check, fetch and install auto-updates */
|
/** Whether we check, fetch and install auto-updates */
|
||||||
private boolean autoUpdateEnabled = true;
|
private boolean autoUpdateEnabled = true;
|
||||||
/** How long between repository backups (ms), or 0 if disabled. */
|
/** How long between repository backups (ms), or 0 if disabled. */
|
||||||
@ -640,6 +646,14 @@ public class Settings {
|
|||||||
return this.maxTransactionTimestampFuture;
|
return this.maxTransactionTimestampFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getMaxRecentChatMessagesPerAccount() {
|
||||||
|
return this.maxRecentChatMessagesPerAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRecentChatMessagesMaxAge() {
|
||||||
|
return recentChatMessagesMaxAge;
|
||||||
|
}
|
||||||
|
|
||||||
public int getBlockCacheSize() {
|
public int getBlockCacheSize() {
|
||||||
return this.blockCacheSize;
|
return this.blockCacheSize;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package org.qortal.transaction;
|
package org.qortal.transaction;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.Account;
|
||||||
import org.qortal.account.PublicKeyAccount;
|
import org.qortal.account.PublicKeyAccount;
|
||||||
@ -16,6 +18,7 @@ import org.qortal.list.ResourceListManager;
|
|||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.GroupRepository;
|
import org.qortal.repository.GroupRepository;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
|
import org.qortal.settings.Settings;
|
||||||
import org.qortal.transform.TransformationException;
|
import org.qortal.transform.TransformationException;
|
||||||
import org.qortal.transform.transaction.ChatTransactionTransformer;
|
import org.qortal.transform.transaction.ChatTransactionTransformer;
|
||||||
import org.qortal.transform.transaction.TransactionTransformer;
|
import org.qortal.transform.transaction.TransactionTransformer;
|
||||||
@ -169,6 +172,14 @@ public class ChatTransaction extends Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PublicKeyAccount creator = this.getCreator();
|
||||||
|
if (creator == null)
|
||||||
|
return ValidationResult.MISSING_CREATOR;
|
||||||
|
|
||||||
|
// Reject if unconfirmed pile already has X recent CHAT transactions from same creator
|
||||||
|
if (countRecentChatTransactionsByCreator(creator) >= Settings.getInstance().getMaxRecentChatMessagesPerAccount())
|
||||||
|
return ValidationResult.TOO_MANY_UNCONFIRMED;
|
||||||
|
|
||||||
// If we exist in the repository then we've been imported as unconfirmed,
|
// If we exist in the repository then we've been imported as unconfirmed,
|
||||||
// but we don't want to make it into a block, so return fake non-OK result.
|
// but we don't want to make it into a block, so return fake non-OK result.
|
||||||
if (this.repository.getTransactionRepository().exists(this.chatTransactionData.getSignature()))
|
if (this.repository.getTransactionRepository().exists(this.chatTransactionData.getSignature()))
|
||||||
@ -219,6 +230,26 @@ public class ChatTransaction extends Transaction {
|
|||||||
return MemoryPoW.verify2(transactionBytes, POW_BUFFER_SIZE, difficulty, nonce);
|
return MemoryPoW.verify2(transactionBytes, POW_BUFFER_SIZE, difficulty, nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int countRecentChatTransactionsByCreator(PublicKeyAccount creator) throws DataException {
|
||||||
|
List<TransactionData> unconfirmedTransactions = repository.getTransactionRepository().getUnconfirmedTransactions();
|
||||||
|
final Long now = NTP.getTime();
|
||||||
|
long recentThreshold = Settings.getInstance().getRecentChatMessagesMaxAge();
|
||||||
|
|
||||||
|
// We only care about chat transactions, and only those that are considered 'recent'
|
||||||
|
Predicate<TransactionData> hasSameCreatorAndIsRecentChat = transactionData -> {
|
||||||
|
if (transactionData.getType() != TransactionType.CHAT)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (transactionData.getTimestamp() < now - recentThreshold)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return Arrays.equals(creator.getPublicKey(), transactionData.getCreatorPublicKey());
|
||||||
|
};
|
||||||
|
|
||||||
|
return (int) unconfirmedTransactions.stream().filter(hasSameCreatorAndIsRecentChat).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure there's at least a skeleton account so people
|
* Ensure there's at least a skeleton account so people
|
||||||
* can retrieve sender's public key using address, even if all their messages
|
* can retrieve sender's public key using address, even if all their messages
|
||||||
|
Loading…
x
Reference in New Issue
Block a user