diff --git a/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java b/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java index 97b6ff9d..235732ee 100644 --- a/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java +++ b/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java @@ -283,7 +283,36 @@ public class NamesDatabaseIntegrityCheck { } public List fetchAllTransactionsInvolvingName(String name, Repository repository) throws DataException { - return repository.getTransactionRepository().getTransactionsInvolvingName(name, ConfirmationStatus.CONFIRMED); + List signatures = new ArrayList<>(); + String reducedName = Unicode.sanitize(name); + + List registerNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria( + TransactionType.REGISTER_NAME, Arrays.asList("(name = ? OR reduced_name = ?)"), Arrays.asList(name, reducedName)); + signatures.addAll(registerNameTransactions); + + List updateNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria( + TransactionType.UPDATE_NAME, + Arrays.asList("(name = ? OR new_name = ? OR (reduced_new_name != '' AND reduced_new_name = ?))"), + Arrays.asList(name, name, reducedName)); + signatures.addAll(updateNameTransactions); + + List sellNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria( + TransactionType.SELL_NAME, Arrays.asList("name = ?"), Arrays.asList(name)); + signatures.addAll(sellNameTransactions); + + List buyNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria( + TransactionType.BUY_NAME, Arrays.asList("name = ?"), Arrays.asList(name)); + signatures.addAll(buyNameTransactions); + + List transactions = new ArrayList<>(); + for (byte[] signature : signatures) { + TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); + // Filter out any unconfirmed transactions + if (transactionData.getBlockHeight() != null && transactionData.getBlockHeight() > 0) { + transactions.add(transactionData); + } + } + return transactions; } private TransactionData fetchLatestModificationTransactionInvolvingName(String registeredName, Repository repository) throws DataException { diff --git a/src/main/java/org/qortal/repository/TransactionRepository.java b/src/main/java/org/qortal/repository/TransactionRepository.java index 643de60a..20096eb8 100644 --- a/src/main/java/org/qortal/repository/TransactionRepository.java +++ b/src/main/java/org/qortal/repository/TransactionRepository.java @@ -108,6 +108,23 @@ public interface TransactionRepository { public List getSignaturesMatchingCriteria(TransactionType txType, byte[] publicKey, Integer minBlockHeight, Integer maxBlockHeight) throws DataException; + /** + * Returns signatures for transactions that match search criteria. + *

+ * Alternate version that allows for custom where clauses and bind params. + * Only use for very specific use cases, such as the names integrity check. + * Not advised to be used otherwise, given that it could be possible for + * unsanitized inputs to be passed in if not careful. + * + * @param txType + * @param whereClauses + * @param bindParams + * @return + * @throws DataException + */ + public List getSignaturesMatchingCustomCriteria(TransactionType txType, List whereClauses, + List bindParams) throws DataException; + /** * Returns signature for latest auto-update transaction. *

diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java index 141d5c1f..f228944e 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java @@ -656,6 +656,44 @@ public class HSQLDBTransactionRepository implements TransactionRepository { } } + + public List getSignaturesMatchingCustomCriteria(TransactionType txType, List whereClauses, + List bindParams) throws DataException { + List signatures = new ArrayList<>(); + + StringBuilder sql = new StringBuilder(1024); + sql.append(String.format("SELECT signature FROM %sTransactions", txType.className)); + + if (!whereClauses.isEmpty()) { + sql.append(" WHERE "); + + final int whereClausesSize = whereClauses.size(); + for (int wci = 0; wci < whereClausesSize; ++wci) { + if (wci != 0) + sql.append(" AND "); + + sql.append(whereClauses.get(wci)); + } + } + + LOGGER.trace(() -> String.format("Transaction search SQL: %s", sql)); + + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) { + if (resultSet == null) + return signatures; + + do { + byte[] signature = resultSet.getBytes(1); + + signatures.add(signature); + } while (resultSet.next()); + + return signatures; + } catch (SQLException e) { + throw new DataException("Unable to fetch matching transaction signatures from repository", e); + } + } + @Override public byte[] getLatestAutoUpdateTransaction(TransactionType txType, int txGroupId, Integer service) throws DataException { StringBuilder sql = new StringBuilder(1024);