Browse Source

Yet another rewrite of fetchAllTransactionsInvolvingName() - this time over 1000x faster since it doesn't involve joining the Transactions table.

block-minter-updates
CalDescent 3 years ago
parent
commit
9e571b87e8
  1. 31
      src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java
  2. 17
      src/main/java/org/qortal/repository/TransactionRepository.java
  3. 38
      src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java

31
src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java

@ -283,7 +283,36 @@ public class NamesDatabaseIntegrityCheck {
}
public List<TransactionData> fetchAllTransactionsInvolvingName(String name, Repository repository) throws DataException {
return repository.getTransactionRepository().getTransactionsInvolvingName(name, ConfirmationStatus.CONFIRMED);
List<byte[]> signatures = new ArrayList<>();
String reducedName = Unicode.sanitize(name);
List<byte[]> registerNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria(
TransactionType.REGISTER_NAME, Arrays.asList("(name = ? OR reduced_name = ?)"), Arrays.asList(name, reducedName));
signatures.addAll(registerNameTransactions);
List<byte[]> 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<byte[]> sellNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria(
TransactionType.SELL_NAME, Arrays.asList("name = ?"), Arrays.asList(name));
signatures.addAll(sellNameTransactions);
List<byte[]> buyNameTransactions = repository.getTransactionRepository().getSignaturesMatchingCustomCriteria(
TransactionType.BUY_NAME, Arrays.asList("name = ?"), Arrays.asList(name));
signatures.addAll(buyNameTransactions);
List<TransactionData> 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 {

17
src/main/java/org/qortal/repository/TransactionRepository.java

@ -108,6 +108,23 @@ public interface TransactionRepository {
public List<byte[]> getSignaturesMatchingCriteria(TransactionType txType, byte[] publicKey,
Integer minBlockHeight, Integer maxBlockHeight) throws DataException;
/**
* Returns signatures for transactions that match search criteria.
* <p>
* 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<byte[]> getSignaturesMatchingCustomCriteria(TransactionType txType, List<String> whereClauses,
List<Object> bindParams) throws DataException;
/**
* Returns signature for latest auto-update transaction.
* <p>

38
src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java

@ -656,6 +656,44 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
}
}
public List<byte[]> getSignaturesMatchingCustomCriteria(TransactionType txType, List<String> whereClauses,
List<Object> bindParams) throws DataException {
List<byte[]> 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);

Loading…
Cancel
Save