From 0a419cb105200a968e5279cb0619660c6756bc3c Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 13 May 2022 11:13:39 +0100 Subject: [PATCH] Added "creator" parameter to GET /transactions/unconfirmed, to allow filtering unconfirmed transactions by creator's public key --- .../api/resource/TransactionsResource.java | 15 ++++++++- .../repository/TransactionRepository.java | 4 +-- .../HSQLDBTransactionRepository.java | 33 ++++++++++++++++--- .../qortal/test/api/TransactionsApiTests.java | 4 +-- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/TransactionsResource.java b/src/main/java/org/qortal/api/resource/TransactionsResource.java index 79195d7c..a35a5cf5 100644 --- a/src/main/java/org/qortal/api/resource/TransactionsResource.java +++ b/src/main/java/org/qortal/api/resource/TransactionsResource.java @@ -253,14 +253,27 @@ public class TransactionsResource { ApiError.REPOSITORY_ISSUE }) public List getUnconfirmedTransactions(@Parameter( + description = "Transaction creator's base58 encoded public key" + ) @QueryParam("creator") String creatorPublicKey58, @Parameter( ref = "limit" ) @QueryParam("limit") Integer limit, @Parameter( ref = "offset" ) @QueryParam("offset") Integer offset, @Parameter( ref = "reverse" ) @QueryParam("reverse") Boolean reverse) { + + // Decode public key if supplied + byte[] creatorPublicKey = null; + if (creatorPublicKey58 != null) { + try { + creatorPublicKey = Base58.decode(creatorPublicKey58); + } catch (NumberFormatException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PUBLIC_KEY, e); + } + } + try (final Repository repository = RepositoryManager.getRepository()) { - return repository.getTransactionRepository().getUnconfirmedTransactions(limit, offset, reverse); + return repository.getTransactionRepository().getUnconfirmedTransactions(creatorPublicKey, limit, offset, reverse); } catch (ApiException e) { throw e; } catch (DataException e) { diff --git a/src/main/java/org/qortal/repository/TransactionRepository.java b/src/main/java/org/qortal/repository/TransactionRepository.java index 20096eb8..645ca32c 100644 --- a/src/main/java/org/qortal/repository/TransactionRepository.java +++ b/src/main/java/org/qortal/repository/TransactionRepository.java @@ -257,7 +257,7 @@ public interface TransactionRepository { * @return list of transactions, or empty if none. * @throws DataException */ - public List getUnconfirmedTransactions(Integer limit, Integer offset, Boolean reverse) throws DataException; + public List getUnconfirmedTransactions(byte[] creatorPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException; /** * Returns list of unconfirmed transactions in timestamp-else-signature order. @@ -266,7 +266,7 @@ public interface TransactionRepository { * @throws DataException */ public default List getUnconfirmedTransactions() throws DataException { - return getUnconfirmedTransactions(null, null, null); + return getUnconfirmedTransactions(null, null, null, null); } /** 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 f228944e..6ba4154a 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java @@ -1213,11 +1213,34 @@ public class HSQLDBTransactionRepository implements TransactionRepository { } @Override - public List getUnconfirmedTransactions(Integer limit, Integer offset, Boolean reverse) throws DataException { - StringBuilder sql = new StringBuilder(256); - sql.append("SELECT signature FROM UnconfirmedTransactions "); + public List getUnconfirmedTransactions(byte[] creatorPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException { + List whereClauses = new ArrayList<>(); + List bindParams = new ArrayList<>(); - sql.append("ORDER BY created_when"); + if (creatorPublicKey != null) { + whereClauses.add("creator = ?"); + bindParams.add(creatorPublicKey); + } + + StringBuilder sql = new StringBuilder(256); + sql.append("SELECT signature FROM UnconfirmedTransactions"); + if (creatorPublicKey != null) { + sql.append(" JOIN Transactions USING (signature) "); + } + + 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)); + } + } + + sql.append(" ORDER BY created_when"); if (reverse != null && reverse) sql.append(" DESC"); @@ -1230,7 +1253,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository { List transactions = new ArrayList<>(); // Find transactions with no corresponding row in BlockTransactions - try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) { + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) { if (resultSet == null) return transactions; diff --git a/src/test/java/org/qortal/test/api/TransactionsApiTests.java b/src/test/java/org/qortal/test/api/TransactionsApiTests.java index 2cdd746b..bceb94ac 100644 --- a/src/test/java/org/qortal/test/api/TransactionsApiTests.java +++ b/src/test/java/org/qortal/test/api/TransactionsApiTests.java @@ -36,8 +36,8 @@ public class TransactionsApiTests extends ApiCommon { @Test public void testGetUnconfirmedTransactions() { - assertNotNull(this.transactionsResource.getUnconfirmedTransactions(null, null, null)); - assertNotNull(this.transactionsResource.getUnconfirmedTransactions(1, 1, true)); + assertNotNull(this.transactionsResource.getUnconfirmedTransactions(null, null, null, null)); + assertNotNull(this.transactionsResource.getUnconfirmedTransactions(null, 1, 1, true)); } @Test