From 9dba4b29681cbdcb7a7c1ead59311bc5d2865917 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 22 Apr 2023 16:05:12 +0100 Subject: [PATCH 01/74] Initial attempt at a database cache to hold arbitrary resources and metadata. --- .../api/resource/ArbitraryResource.java | 46 +- .../org/qortal/arbitrary/misc/Category.java | 5 +- .../org/qortal/controller/Controller.java | 21 + .../arbitrary/ArbitraryDataManager.java | 36 ++ .../arbitrary/ArbitraryMetadataManager.java | 56 +- ...ceInfo.java => ArbitraryResourceData.java} | 10 +- .../arbitrary/ArbitraryResourceMetadata.java | 47 ++ .../arbitrary/ArbitraryResourceNameInfo.java | 2 +- .../repository/ArbitraryRepository.java | 30 +- .../qortal/repository/RepositoryManager.java | 71 +++ .../hsqldb/HSQLDBArbitraryRepository.java | 478 ++++++++++++++---- .../hsqldb/HSQLDBDatabaseUpdates.java | 40 +- .../transaction/ArbitraryTransaction.java | 130 ++++- .../utils/ArbitraryTransactionUtils.java | 37 +- 14 files changed, 816 insertions(+), 193 deletions(-) rename src/main/java/org/qortal/data/arbitrary/{ArbitraryResourceInfo.java => ArbitraryResourceData.java} (80%) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index c617b517..1e243c51 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -86,12 +86,12 @@ public class ArbitraryResource { "- If default is set to true, only resources without identifiers will be returned.", responses = { @ApiResponse( - content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceInfo.class)) + content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceData.class)) ) } ) @ApiErrors({ApiError.REPOSITORY_ISSUE}) - public List getResources( + public List getResources( @QueryParam("service") Service service, @QueryParam("name") String name, @QueryParam("identifier") String identifier, @@ -133,8 +133,9 @@ public class ArbitraryResource { } } - List resources = repository.getArbitraryRepository() - .getArbitraryResources(service, identifier, names, defaultRes, followedOnly, excludeBlocked, limit, offset, reverse); + List resources = repository.getArbitraryRepository() + .getArbitraryResources(service, identifier, names, defaultRes, followedOnly, excludeBlocked, + includeMetadata, limit, offset, reverse); if (resources == null) { return new ArrayList<>(); @@ -143,9 +144,6 @@ public class ArbitraryResource { if (includeStatus != null && includeStatus) { resources = ArbitraryTransactionUtils.addStatusToResources(resources); } - if (includeMetadata != null && includeMetadata) { - resources = ArbitraryTransactionUtils.addMetadataToResources(resources); - } return resources; @@ -161,12 +159,12 @@ public class ArbitraryResource { "If default is set to true, only resources without identifiers will be returned.", responses = { @ApiResponse( - content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceInfo.class)) + content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceData.class)) ) } ) @ApiErrors({ApiError.REPOSITORY_ISSUE}) - public List searchResources( + public List searchResources( @QueryParam("service") Service service, @Parameter(description = "Query (searches both name and identifier fields)") @QueryParam("query") String query, @Parameter(description = "Identifier (searches identifier field only)") @QueryParam("identifier") String identifier, @@ -206,8 +204,9 @@ public class ArbitraryResource { names = null; } - List resources = repository.getArbitraryRepository() - .searchArbitraryResources(service, query, identifier, names, usePrefixOnly, exactMatchNames, defaultRes, followedOnly, excludeBlocked, limit, offset, reverse); + List resources = repository.getArbitraryRepository() + .searchArbitraryResources(service, query, identifier, names, usePrefixOnly, exactMatchNames, + defaultRes, followedOnly, excludeBlocked, includeMetadata, limit, offset, reverse); if (resources == null) { return new ArrayList<>(); @@ -216,9 +215,6 @@ public class ArbitraryResource { if (includeStatus != null && includeStatus) { resources = ArbitraryTransactionUtils.addStatusToResources(resources); } - if (includeMetadata != null && includeMetadata) { - resources = ArbitraryTransactionUtils.addMetadataToResources(resources); - } return resources; @@ -479,21 +475,20 @@ public class ArbitraryResource { summary = "List arbitrary resources hosted by this node", responses = { @ApiResponse( - content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceInfo.class)) + content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceData.class)) ) } ) @ApiErrors({ApiError.REPOSITORY_ISSUE}) - public List getHostedResources( + public List getHostedResources( @HeaderParam(Security.API_KEY_HEADER) String apiKey, @Parameter(description = "Include status") @QueryParam("includestatus") Boolean includeStatus, - @Parameter(description = "Include metadata") @QueryParam("includemetadata") Boolean includeMetadata, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @QueryParam("query") String query) { Security.checkApiCallAllowed(request); - List resources = new ArrayList<>(); + List resources = new ArrayList<>(); try (final Repository repository = RepositoryManager.getRepository()) { @@ -509,21 +504,18 @@ public class ArbitraryResource { if (transactionData.getService() == null) { continue; } - ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo(); - arbitraryResourceInfo.name = transactionData.getName(); - arbitraryResourceInfo.service = transactionData.getService(); - arbitraryResourceInfo.identifier = transactionData.getIdentifier(); - if (!resources.contains(arbitraryResourceInfo)) { - resources.add(arbitraryResourceInfo); + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.name = transactionData.getName(); + arbitraryResourceData.service = transactionData.getService(); + arbitraryResourceData.identifier = transactionData.getIdentifier(); + if (!resources.contains(arbitraryResourceData)) { + resources.add(arbitraryResourceData); } } if (includeStatus != null && includeStatus) { resources = ArbitraryTransactionUtils.addStatusToResources(resources); } - if (includeMetadata != null && includeMetadata) { - resources = ArbitraryTransactionUtils.addMetadataToResources(resources); - } return resources; diff --git a/src/main/java/org/qortal/arbitrary/misc/Category.java b/src/main/java/org/qortal/arbitrary/misc/Category.java index d56e3d5d..3a1489b8 100644 --- a/src/main/java/org/qortal/arbitrary/misc/Category.java +++ b/src/main/java/org/qortal/arbitrary/misc/Category.java @@ -67,9 +67,12 @@ public enum Category { /** * Same as valueOf() but with fallback to UNCATEGORIZED if there's no match * @param name - * @return a Category (using UNCATEGORIZED if no match found) + * @return a Category (using UNCATEGORIZED if no match found), or null if null name passed */ public static Category uncategorizedValueOf(String name) { + if (name == null) { + return null; + } try { return Category.valueOf(name); } diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index f0bd1ef5..e4944a66 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -47,6 +47,7 @@ import org.qortal.data.block.BlockData; import org.qortal.data.block.BlockSummaryData; import org.qortal.data.naming.NameData; import org.qortal.data.network.PeerData; +import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ChatTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.event.Event; @@ -400,6 +401,10 @@ public class Controller extends Thread { RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(getRepositoryUrl()); RepositoryManager.setRepositoryFactory(repositoryFactory); RepositoryManager.setRequestedCheckpoint(Boolean.TRUE); + + try (final Repository repository = RepositoryManager.getRepository()) { + RepositoryManager.buildInitialArbitraryResourcesCache(repository); + } } catch (DataException e) { // If exception has no cause then repository is in use by some other process. @@ -891,6 +896,7 @@ public class Controller extends Thread { if (now >= transaction.getDeadline()) { LOGGER.debug(() -> String.format("Deleting expired, unconfirmed transaction %s", Base58.encode(transactionData.getSignature()))); repository.getTransactionRepository().delete(transactionData); + this.onExpiredTransaction(transactionData); deletedCount++; } } @@ -1203,6 +1209,21 @@ public class Controller extends Thread { }); } + /** + * Callback for when we've deleted an expired, unconfirmed transaction. + *

+ * @implSpec performs actions in a new thread + */ + public void onExpiredTransaction(TransactionData transactionData) { + this.callbackExecutor.execute(() -> { + + // If this is an ARBITRARY transaction, we may need to update the cache + if (transactionData.getType() == TransactionType.ARBITRARY) { + ArbitraryDataManager.getInstance().onExpiredArbitraryTransaction((ArbitraryTransactionData)transactionData); + } + }); + } + public void onPeerHandshakeCompleted(Peer peer) { // Only send if outbound if (peer.isOutbound()) { diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index 9284e672..e32fcb0f 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -14,6 +14,7 @@ import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.Controller; +import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.network.Network; @@ -539,6 +540,41 @@ public class ArbitraryDataManager extends Thread { return true; } + public void onExpiredArbitraryTransaction(ArbitraryTransactionData arbitraryTransactionData) { + if (arbitraryTransactionData.getName() == null) { + // No name, so we don't care about this transaction + return; + } + + Service service = arbitraryTransactionData.getService(); + String name = arbitraryTransactionData.getName(); + String identifier = arbitraryTransactionData.getIdentifier(); + + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.service = service; + arbitraryResourceData.name = name; + arbitraryResourceData.identifier = identifier; + + try (final Repository repository = RepositoryManager.getRepository()) { + // Find next oldest transaction (which is now the latest transaction) + ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(name, service, null, identifier); + + if (latestTransactionData == null) { + // There are no transactions anymore, so we can delete from the cache entirely (this deletes metadata too) + repository.getArbitraryRepository().delete(arbitraryResourceData); + } + else { + // We found the next oldest transaction, so we can update the cache + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, latestTransactionData); + arbitraryTransaction.updateArbitraryResourceCache(); + arbitraryTransaction.updateArbitraryMetadataCache(); + } +; + } catch (DataException e) { + // Not much we can do, so ignore for now + } + } + public int getPowDifficulty() { return this.powDifficulty; } diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index 663bc22a..a496485b 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -15,6 +15,7 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.settings.Settings; +import org.qortal.transaction.ArbitraryTransaction; import org.qortal.utils.Base58; import org.qortal.utils.ListUtils; import org.qortal.utils.NTP; @@ -324,37 +325,44 @@ public class ArbitraryMetadataManager { Triple newEntry = new Triple<>(null, null, request.getC()); arbitraryMetadataRequests.put(message.getId(), newEntry); - ArbitraryTransactionData arbitraryTransactionData = null; - - // Forwarding - if (isRelayRequest && Settings.getInstance().isRelayModeEnabled()) { - - // Get transaction info - try (final Repository repository = RepositoryManager.getRepository()) { - TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); - if (!(transactionData instanceof ArbitraryTransactionData)) - return; - arbitraryTransactionData = (ArbitraryTransactionData) transactionData; - } catch (DataException e) { - LOGGER.error(String.format("Repository issue while finding arbitrary transaction metadata for peer %s", peer), e); + // Get transaction info + try (final Repository repository = RepositoryManager.getRepository()) { + TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); + if (!(transactionData instanceof ArbitraryTransactionData)) { + return; } + ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) transactionData; - // Check if the name is blocked - boolean isBlocked = (arbitraryTransactionData == null || ListUtils.isNameBlocked(arbitraryTransactionData.getName())); - if (!isBlocked) { - Peer requestingPeer = request.getB(); - if (requestingPeer != null) { + // Forwarding + if (isRelayRequest && Settings.getInstance().isRelayModeEnabled()) { - ArbitraryMetadataMessage forwardArbitraryMetadataMessage = new ArbitraryMetadataMessage(signature, arbitraryMetadataMessage.getArbitraryMetadataFile()); - forwardArbitraryMetadataMessage.setId(arbitraryMetadataMessage.getId()); + // Check if the name is blocked + boolean isBlocked = (arbitraryTransactionData == null || ListUtils.isNameBlocked(arbitraryTransactionData.getName())); + if (!isBlocked) { + Peer requestingPeer = request.getB(); + if (requestingPeer != null) { - // Forward to requesting peer - LOGGER.debug("Forwarding metadata to requesting peer: {}", requestingPeer); - if (!requestingPeer.sendMessage(forwardArbitraryMetadataMessage)) { - requestingPeer.disconnect("failed to forward arbitrary metadata"); + ArbitraryMetadataMessage forwardArbitraryMetadataMessage = new ArbitraryMetadataMessage(signature, arbitraryMetadataMessage.getArbitraryMetadataFile()); + forwardArbitraryMetadataMessage.setId(arbitraryMetadataMessage.getId()); + + // Forward to requesting peer + LOGGER.debug("Forwarding metadata to requesting peer: {}", requestingPeer); + if (!requestingPeer.sendMessage(forwardArbitraryMetadataMessage)) { + requestingPeer.disconnect("failed to forward arbitrary metadata"); + } } } } + + // Update arbitrary resource caches + if (arbitraryTransactionData != null) { + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, arbitraryTransactionData); + arbitraryTransaction.updateArbitraryResourceCache(); + arbitraryTransaction.updateArbitraryMetadataCache(); + } + + } catch (DataException e) { + LOGGER.error(String.format("Repository issue while finding arbitrary transaction metadata for peer %s", peer), e); } } diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceInfo.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java similarity index 80% rename from src/main/java/org/qortal/data/arbitrary/ArbitraryResourceInfo.java rename to src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java index a09fc5ff..4f636177 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceInfo.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java @@ -7,7 +7,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import java.util.Objects; @XmlAccessorType(XmlAccessType.FIELD) -public class ArbitraryResourceInfo { +public class ArbitraryResourceData { public String name; public Service service; @@ -15,11 +15,11 @@ public class ArbitraryResourceInfo { public ArbitraryResourceStatus status; public ArbitraryResourceMetadata metadata; - public Long size; + public Integer size; public Long created; public Long updated; - public ArbitraryResourceInfo() { + public ArbitraryResourceData() { } @Override @@ -32,10 +32,10 @@ public class ArbitraryResourceInfo { if (o == this) return true; - if (!(o instanceof ArbitraryResourceInfo)) + if (!(o instanceof ArbitraryResourceData)) return false; - ArbitraryResourceInfo other = (ArbitraryResourceInfo) o; + ArbitraryResourceData other = (ArbitraryResourceData) o; return Objects.equals(this.name, other.name) && Objects.equals(this.service, other.service) && diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java index a6aa6e26..614a8e69 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java @@ -18,6 +18,9 @@ public class ArbitraryResourceMetadata { private List files; private String mimeType; + // Only included when updating database + private ArbitraryResourceData arbitraryResourceData; + public ArbitraryResourceMetadata() { } @@ -60,4 +63,48 @@ public class ArbitraryResourceMetadata { public List getFiles() { return this.files; } + + public void setTitle(String title) { + this.title = title; + } + + public String getTitle() { + return this.title; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return this.description; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public List getTags() { + return this.tags; + } + + public void setCategory(Category category) { + this.category = category; + + // Also set categoryName + if (category != null) { + this.categoryName = category.getName(); + } + } + + public Category getCategory() { + return this.category; + } + + public void setArbitraryResourceData(ArbitraryResourceData arbitraryResourceData) { + this.arbitraryResourceData = arbitraryResourceData; + } + public ArbitraryResourceData getArbitraryResourceData() { + return this.arbitraryResourceData; + } } diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceNameInfo.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceNameInfo.java index b9be8034..0f91c2c2 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceNameInfo.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceNameInfo.java @@ -9,7 +9,7 @@ import java.util.List; public class ArbitraryResourceNameInfo { public String name; - public List resources = new ArrayList<>(); + public List resources = new ArrayList<>(); public ArbitraryResourceNameInfo() { } diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 9d9ed8ce..63729e46 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -1,9 +1,8 @@ package org.qortal.repository; import org.qortal.arbitrary.misc.Service; -import org.qortal.data.arbitrary.ArbitraryResourceInfo; -import org.qortal.data.arbitrary.ArbitraryResourceNameInfo; -import org.qortal.data.network.ArbitraryPeerData; +import org.qortal.data.arbitrary.ArbitraryResourceData; +import org.qortal.data.arbitrary.ArbitraryResourceMetadata; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; @@ -11,23 +10,42 @@ import java.util.List; public interface ArbitraryRepository { + // Utils + public boolean isDataLocal(byte[] signature) throws DataException; public byte[] fetchData(byte[] signature) throws DataException; + + // Transaction related + public void save(ArbitraryTransactionData arbitraryTransactionData) throws DataException; public void delete(ArbitraryTransactionData arbitraryTransactionData) throws DataException; public List getArbitraryTransactions(String name, Service service, String identifier, long since) throws DataException; + public ArbitraryTransactionData getInitialTransaction(String name, Service service, Method method, String identifier) throws DataException; + public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method, String identifier) throws DataException; - public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Integer limit, Integer offset, Boolean reverse) throws DataException; + // Resource related - public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Integer limit, Integer offset, Boolean reverse) throws DataException; + public ArbitraryResourceData getArbitraryResource(Service service, String name, String identifier) throws DataException; - public List getArbitraryResourceCreatorNames(Service service, String identifier, boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List getArbitraryResources(Integer limit, Integer offset, Boolean reverse) throws DataException; + public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException; + + public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException; + + + // Arbitrary resources cache save/load + + public void save(ArbitraryResourceData arbitraryResourceData) throws DataException; + public void delete(ArbitraryResourceData arbitraryResourceData) throws DataException; + + public void save(ArbitraryResourceMetadata metadata) throws DataException; + public void delete(ArbitraryResourceMetadata metadata) throws DataException; } diff --git a/src/main/java/org/qortal/repository/RepositoryManager.java b/src/main/java/org/qortal/repository/RepositoryManager.java index 9d76ccae..404b6b34 100644 --- a/src/main/java/org/qortal/repository/RepositoryManager.java +++ b/src/main/java/org/qortal/repository/RepositoryManager.java @@ -2,8 +2,16 @@ package org.qortal.repository; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.qortal.api.resource.TransactionsResource; +import org.qortal.controller.Controller; +import org.qortal.data.arbitrary.ArbitraryResourceData; +import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.settings.Settings; +import org.qortal.transaction.ArbitraryTransaction; +import org.qortal.transaction.Transaction; import java.sql.SQLException; +import java.util.List; import java.util.concurrent.TimeoutException; public abstract class RepositoryManager { @@ -56,6 +64,69 @@ public abstract class RepositoryManager { } } + public static boolean buildInitialArbitraryResourcesCache(Repository repository) throws DataException { + if (Settings.getInstance().isLite()) { + // Lite nodes have no blockchain + return false; + } + + try { + // Check if QDNResources table is empty + List resources = repository.getArbitraryRepository().getArbitraryResources(10, 0, false); + if (!resources.isEmpty()) { + // Resources exist in the cache, so assume complete. + // We avoid checkpointing and prevent the node from starting up in the case of a rebuild failure, so + // we shouldn't ever be left in a partially rebuilt state. + LOGGER.debug("Arbitrary resources cache already built"); + return false; + } + + LOGGER.info("Building arbitrary resources cache..."); + + final int batchSize = 100; + int offset = 0; + + // Loop through all ARBITRARY transactions, and determine latest state + while (!Controller.isStopping()) { + LOGGER.info("Fetching arbitrary transactions {} - {}", offset, offset+batchSize-1); + + List signatures = repository.getTransactionRepository().getSignaturesMatchingCriteria(null, null, null, List.of(Transaction.TransactionType.ARBITRARY), null, null, null, TransactionsResource.ConfirmationStatus.BOTH, batchSize, offset, false); + if (signatures.isEmpty()) { + // Complete + break; + } + + // Expand signatures to transactions + for (byte[] signature : signatures) { + ArbitraryTransactionData transactionData = (ArbitraryTransactionData) repository + .getTransactionRepository().fromSignature(signature); + + if (transactionData.getService() == null) { + // Unsupported service - ignore this resource + continue; + } + + // Update arbitrary resource caches + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); + arbitraryTransaction.updateArbitraryResourceCache(); + arbitraryTransaction.updateArbitraryMetadataCache(); + } + offset += batchSize; + } + + repository.saveChanges(); + LOGGER.info("Completed build of initial arbitrary resources cache."); + return true; + } + catch (DataException e) { + LOGGER.info("Unable to build initial arbitrary resources cache: {}. The database may have been left in an inconsistent state.", e.getMessage()); + + // Throw an exception so that the node startup is halted, allowing for a retry next time. + repository.discardChanges(); + throw new DataException("Build of initial arbitrary resources cache failed."); + } + } + public static void setRequestedCheckpoint(Boolean quick) { quickCheckpointRequested = quick; } diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 87841ca9..9c88e39c 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -2,10 +2,10 @@ package org.qortal.repository.hsqldb; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bouncycastle.util.Longs; +import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; -import org.qortal.data.arbitrary.ArbitraryResourceInfo; -import org.qortal.data.arbitrary.ArbitraryResourceNameInfo; +import org.qortal.data.arbitrary.ArbitraryResourceData; +import org.qortal.data.arbitrary.ArbitraryResourceMetadata; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; import org.qortal.data.transaction.BaseTransactionData; @@ -22,6 +22,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class HSQLDBArbitraryRepository implements ArbitraryRepository { @@ -41,6 +42,9 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { return (ArbitraryTransactionData) transactionData; } + + // Utils + @Override public boolean isDataLocal(byte[] signature) throws DataException { ArbitraryTransactionData transactionData = getTransactionData(signature); @@ -113,6 +117,9 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { return null; } + + // Transaction related + @Override public void save(ArbitraryTransactionData arbitraryTransactionData) throws DataException { // Already hashed? Nothing to do @@ -211,8 +218,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } - @Override - public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method, String identifier) throws DataException { + private ArbitraryTransactionData getSingleTransaction(String name, Service service, Method method, String identifier, boolean firstNotLast) throws DataException { StringBuilder sql = new StringBuilder(1024); sql.append("SELECT type, reference, signature, creator, created_when, fee, " + @@ -228,7 +234,16 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { sql.append(method.value); } - sql.append("ORDER BY created_when DESC LIMIT 1"); + sql.append(" ORDER BY created_when"); + + if (firstNotLast) { + sql.append(" ASC"); + } + else { + sql.append(" DESC"); + } + + sql.append(" LIMIT 1"); try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), name.toLowerCase(), service.value, identifier, identifier)) { if (resultSet == null) @@ -284,13 +299,189 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } @Override - public List getArbitraryResources(Service service, String identifier, List names, - boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, - Integer limit, Integer offset, Boolean reverse) throws DataException { + public ArbitraryTransactionData getInitialTransaction(String name, Service service, Method method, String identifier) throws DataException { + return this.getSingleTransaction(name, service, method, identifier, true); + } + + @Override + public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method, String identifier) throws DataException { + return this.getSingleTransaction(name, service, method, identifier, false); + } + + + // Resource related + + @Override + public ArbitraryResourceData getArbitraryResource(Service service, String name, String identifier) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, MAX(size) AS max_size FROM ArbitraryTransactions WHERE 1=1"); + // Name is required + if (name == null) { + return null; + } + + sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + + "FROM ArbitraryResourcesCache " + + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + + "WHERE service = ? AND name = ?"); + + bindParams.add(service.value); + bindParams.add(name); + + if (identifier != null) { + sql.append(" AND identifier = ?"); + bindParams.add(identifier); + } + else { + sql.append(" AND identifier IS NULL"); + } + + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) { + if (resultSet == null) + return null; + + String nameResult = resultSet.getString(1); + Service serviceResult = Service.valueOf(resultSet.getInt(2)); + String identifierResult = resultSet.getString(3); + Integer sizeResult = resultSet.getInt(4); + Long created = resultSet.getLong(5); + Long updated = resultSet.getLong(6); + + // Optional metadata fields + String title = resultSet.getString(7); + String description = resultSet.getString(8); + String category = resultSet.getString(9); + String tag1 = resultSet.getString(10); + String tag2 = resultSet.getString(11); + String tag3 = resultSet.getString(12); + String tag4 = resultSet.getString(13); + String tag5 = resultSet.getString(14); + + if (Objects.equals(identifierResult, "default")) { + // Map "default" back to null. This is optional but probably less confusing than returning "default". + identifierResult = null; + } + + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.name = nameResult; + arbitraryResourceData.service = serviceResult; + arbitraryResourceData.identifier = identifierResult; + arbitraryResourceData.size = sizeResult; + arbitraryResourceData.created = created; + arbitraryResourceData.updated = (updated == 0) ? null : updated; + + ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); + metadata.setTitle(title); + metadata.setDescription(description); + metadata.setCategory(Category.uncategorizedValueOf(category)); + + List tags = new ArrayList<>(); + if (tag1 != null) tags.add(tag1); + if (tag2 != null) tags.add(tag2); + if (tag3 != null) tags.add(tag3); + if (tag4 != null) tags.add(tag4); + if (tag5 != null) tags.add(tag5); + metadata.setTags(!tags.isEmpty() ? tags : null); + + arbitraryResourceData.metadata = metadata; + + return arbitraryResourceData; + } catch (SQLException e) { + throw new DataException("Unable to fetch arbitrary resource from repository", e); + } + } + @Override + public List getArbitraryResources(Integer limit, Integer offset, Boolean reverse) throws DataException { + StringBuilder sql = new StringBuilder(512); + List bindParams = new ArrayList<>(); + + sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + + "FROM ArbitraryResourcesCache " + + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + + "WHERE name IS NOT NULL ORDER BY created_when"); + + if (reverse != null && reverse) { + sql.append(" DESC"); + } + + HSQLDBRepository.limitOffsetSql(sql, limit, offset); + + List arbitraryResources = new ArrayList<>(); + + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) { + if (resultSet == null) + return arbitraryResources; + + do { + String nameResult = resultSet.getString(1); + Service serviceResult = Service.valueOf(resultSet.getInt(2)); + String identifierResult = resultSet.getString(3); + Integer sizeResult = resultSet.getInt(4); + Long created = resultSet.getLong(5); + Long updated = resultSet.getLong(6); + + // Optional metadata fields + String title = resultSet.getString(7); + String description = resultSet.getString(8); + String category = resultSet.getString(9); + String tag1 = resultSet.getString(10); + String tag2 = resultSet.getString(11); + String tag3 = resultSet.getString(12); + String tag4 = resultSet.getString(13); + String tag5 = resultSet.getString(14); + + if (Objects.equals(identifierResult, "default")) { + // Map "default" back to null. This is optional but probably less confusing than returning "default". + identifierResult = null; + } + + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.name = nameResult; + arbitraryResourceData.service = serviceResult; + arbitraryResourceData.identifier = identifierResult; + arbitraryResourceData.size = sizeResult; + arbitraryResourceData.created = created; + arbitraryResourceData.updated = (updated == 0) ? null : updated; + + ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); + metadata.setTitle(title); + metadata.setDescription(description); + metadata.setCategory(Category.uncategorizedValueOf(category)); + + List tags = new ArrayList<>(); + if (tag1 != null) tags.add(tag1); + if (tag2 != null) tags.add(tag2); + if (tag3 != null) tags.add(tag3); + if (tag4 != null) tags.add(tag4); + if (tag5 != null) tags.add(tag5); + metadata.setTags(!tags.isEmpty() ? tags : null); + + arbitraryResourceData.metadata = metadata; + + arbitraryResources.add(arbitraryResourceData); + } while (resultSet.next()); + + return arbitraryResources; + } catch (SQLException e) { + throw new DataException("Unable to fetch arbitrary resources from repository", e); + } + } + + @Override + public List getArbitraryResources(Service service, String identifier, List names, + boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, + Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException { + StringBuilder sql = new StringBuilder(512); + List bindParams = new ArrayList<>(); + + sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + + "FROM ArbitraryResourcesCache " + + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + + "WHERE name IS NOT NULL"); if (service != null) { sql.append(" AND service = "); @@ -351,7 +542,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } - sql.append(" GROUP BY name, service, identifier ORDER BY name COLLATE SQL_TEXT_UCC_NO_PAD"); + sql.append(" ORDER BY created_when"); if (reverse != null && reverse) { sql.append(" DESC"); @@ -359,49 +550,82 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { HSQLDBRepository.limitOffsetSql(sql, limit, offset); - List arbitraryResources = new ArrayList<>(); + List arbitraryResources = new ArrayList<>(); try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) { if (resultSet == null) - return null; + return arbitraryResources; do { String nameResult = resultSet.getString(1); Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); + Long created = resultSet.getLong(5); + Long updated = resultSet.getLong(6); - // We should filter out resources without names - if (nameResult == null) { - continue; + // Optional metadata fields + String title = resultSet.getString(7); + String description = resultSet.getString(8); + String category = resultSet.getString(9); + String tag1 = resultSet.getString(10); + String tag2 = resultSet.getString(11); + String tag3 = resultSet.getString(12); + String tag4 = resultSet.getString(13); + String tag5 = resultSet.getString(14); + + if (Objects.equals(identifierResult, "default")) { + // Map "default" back to null. This is optional but probably less confusing than returning "default". + identifierResult = null; } - ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo(); - arbitraryResourceInfo.name = nameResult; - arbitraryResourceInfo.service = serviceResult; - arbitraryResourceInfo.identifier = identifierResult; - arbitraryResourceInfo.size = Longs.valueOf(sizeResult); + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.name = nameResult; + arbitraryResourceData.service = serviceResult; + arbitraryResourceData.identifier = identifierResult; + arbitraryResourceData.size = sizeResult; + arbitraryResourceData.created = created; + arbitraryResourceData.updated = (updated == 0) ? null : updated; - arbitraryResources.add(arbitraryResourceInfo); + if (includeMetadata != null && includeMetadata) { + // TODO: we could avoid the join altogether + ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); + metadata.setTitle(title); + metadata.setDescription(description); + metadata.setCategory(Category.uncategorizedValueOf(category)); + + List tags = new ArrayList<>(); + if (tag1 != null) tags.add(tag1); + if (tag2 != null) tags.add(tag2); + if (tag3 != null) tags.add(tag3); + if (tag4 != null) tags.add(tag4); + if (tag5 != null) tags.add(tag5); + metadata.setTags(!tags.isEmpty() ? tags : null); + + arbitraryResourceData.metadata = metadata; + } + + arbitraryResources.add(arbitraryResourceData); } while (resultSet.next()); return arbitraryResources; } catch (SQLException e) { - throw new DataException("Unable to fetch arbitrary transactions from repository", e); + throw new DataException("Unable to fetch arbitrary resources from repository", e); } } @Override - public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, + public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List exactMatchNames, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, - Integer limit, Integer offset, Boolean reverse) throws DataException { + Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, MAX(size) AS max_size, MIN(created_when) AS date_created, MAX(created_when) AS date_updated " + - "FROM ArbitraryTransactions " + - "JOIN Transactions USING (signature) " + - "WHERE 1=1"); + sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + + "FROM ArbitraryResourcesCache " + + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + + "WHERE name IS NOT NULL"); if (service != null) { sql.append(" AND service = "); @@ -492,7 +716,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } - sql.append(" GROUP BY name, service, identifier ORDER BY date_created"); + sql.append(" ORDER BY created_when"); if (reverse != null && reverse) { sql.append(" DESC"); @@ -500,98 +724,156 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { HSQLDBRepository.limitOffsetSql(sql, limit, offset); - List arbitraryResources = new ArrayList<>(); + List arbitraryResources = new ArrayList<>(); try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) { if (resultSet == null) - return null; + return arbitraryResources; do { String nameResult = resultSet.getString(1); Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - long dateCreated = resultSet.getLong(5); - long dateUpdated = resultSet.getLong(6); + Long created = resultSet.getLong(5); + Long updated = resultSet.getLong(6); - // We should filter out resources without names - if (nameResult == null) { - continue; + // Optional metadata fields + String title = resultSet.getString(7); + String description = resultSet.getString(8); + String category = resultSet.getString(9); + String tag1 = resultSet.getString(10); + String tag2 = resultSet.getString(11); + String tag3 = resultSet.getString(12); + String tag4 = resultSet.getString(13); + String tag5 = resultSet.getString(14); + + if (Objects.equals(identifierResult, "default")) { + // Map "default" back to null. This is optional but probably less confusing than returning "default". + identifierResult = null; } - ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo(); - arbitraryResourceInfo.name = nameResult; - arbitraryResourceInfo.service = serviceResult; - arbitraryResourceInfo.identifier = identifierResult; - arbitraryResourceInfo.size = Longs.valueOf(sizeResult); - arbitraryResourceInfo.created = dateCreated; - arbitraryResourceInfo.updated = dateUpdated; + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.name = nameResult; + arbitraryResourceData.service = serviceResult; + arbitraryResourceData.identifier = identifierResult; + arbitraryResourceData.size = sizeResult; + arbitraryResourceData.created = created; + arbitraryResourceData.updated = (updated == 0) ? null : updated; - arbitraryResources.add(arbitraryResourceInfo); + if (includeMetadata != null && includeMetadata) { + // TODO: we could avoid the join altogether + ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); + metadata.setTitle(title); + metadata.setDescription(description); + metadata.setCategory(Category.uncategorizedValueOf(category)); + + List tags = new ArrayList<>(); + if (tag1 != null) tags.add(tag1); + if (tag2 != null) tags.add(tag2); + if (tag3 != null) tags.add(tag3); + if (tag4 != null) tags.add(tag4); + if (tag5 != null) tags.add(tag5); + metadata.setTags(!tags.isEmpty() ? tags : null); + + arbitraryResourceData.metadata = metadata; + } + + arbitraryResources.add(arbitraryResourceData); } while (resultSet.next()); return arbitraryResources; } catch (SQLException e) { - throw new DataException("Unable to fetch arbitrary transactions from repository", e); + throw new DataException("Unable to fetch arbitrary resources from repository", e); + } + } + + + // Arbitrary resources cache save/load + + @Override + public void save(ArbitraryResourceData arbitraryResourceData) throws DataException { + HSQLDBSaver saveHelper = new HSQLDBSaver("ArbitraryResourcesCache"); + + saveHelper.bind("service", arbitraryResourceData.service.value).bind("name", arbitraryResourceData.name) + .bind("identifier", arbitraryResourceData.identifier).bind("size", arbitraryResourceData.size) + .bind("created_when", arbitraryResourceData.created).bind("updated_when", arbitraryResourceData.updated); + + try { + saveHelper.execute(this.repository); + } catch (SQLException e) { + throw new DataException("Unable to save arbitrary resource info into repository", e); } } @Override - public List getArbitraryResourceCreatorNames(Service service, String identifier, - boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException { - StringBuilder sql = new StringBuilder(512); + public void delete(ArbitraryResourceData arbitraryResourceData) throws DataException { + // NOTE: arbitrary metadata are deleted automatically by the database thanks to "ON DELETE CASCADE" + // in ArbitraryMetadataCache' FOREIGN KEY definition. + try { + this.repository.delete("ArbitraryResourcesCache", "service = ? AND name = ? AND identifier = ?", + arbitraryResourceData.service.value, arbitraryResourceData.name, arbitraryResourceData.identifier); - sql.append("SELECT name FROM ArbitraryTransactions WHERE 1=1"); - - if (service != null) { - sql.append(" AND service = "); - sql.append(service.value); - } - - if (defaultResource) { - // Default resource requested - use NULL identifier - // The AND ? IS NULL AND ? IS NULL is a hack to make use of the identifier params in checkedExecute() - identifier = null; - sql.append(" AND (identifier IS NULL AND ? IS NULL AND ? IS NULL)"); - } - else { - // Non-default resource requested - // Use an exact match identifier, or list all if supplied identifier is null - sql.append(" AND (identifier = ? OR (? IS NULL))"); - } - - sql.append(" GROUP BY name ORDER BY name COLLATE SQL_TEXT_UCC_NO_PAD"); - - if (reverse != null && reverse) { - sql.append(" DESC"); - } - - HSQLDBRepository.limitOffsetSql(sql, limit, offset); - - List arbitraryResources = new ArrayList<>(); - - try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), identifier, identifier)) { - if (resultSet == null) - return null; - - do { - String name = resultSet.getString(1); - - // We should filter out resources without names - if (name == null) { - continue; - } - - ArbitraryResourceNameInfo arbitraryResourceNameInfo = new ArbitraryResourceNameInfo(); - arbitraryResourceNameInfo.name = name; - - arbitraryResources.add(arbitraryResourceNameInfo); - } while (resultSet.next()); - - return arbitraryResources; } catch (SQLException e) { - throw new DataException("Unable to fetch arbitrary transactions from repository", e); + throw new DataException("Unable to delete account from repository", e); } } + + /* Arbitrary metadata cache */ + + @Override + public void save(ArbitraryResourceMetadata metadata) throws DataException { + HSQLDBSaver saveHelper = new HSQLDBSaver("ArbitraryMetadataCache"); + + ArbitraryResourceData arbitraryResourceData = metadata.getArbitraryResourceData(); + if (arbitraryResourceData == null) { + throw new DataException("Can't save metadata without a referenced resource"); + } + + String tag1 = null; + String tag2 = null; + String tag3 = null; + String tag4 = null; + String tag5 = null; + + List tags = metadata.getTags(); + if (tags != null) { + if (tags.size() > 0) tag1 = tags.get(0); + if (tags.size() > 1) tag2 = tags.get(1); + if (tags.size() > 2) tag3 = tags.get(2); + if (tags.size() > 3) tag4 = tags.get(3); + if (tags.size() > 4) tag5 = tags.get(4); + } + + String category = metadata.getCategory() != null ? metadata.getCategory().toString() : null; + + saveHelper.bind("service", arbitraryResourceData.service.value).bind("name", arbitraryResourceData.name) + .bind("identifier", arbitraryResourceData.identifier).bind("title", metadata.getTitle()) + .bind("description", metadata.getDescription()).bind("category", category) + .bind("tag1", tag1).bind("tag2", tag2).bind("tag3", tag3).bind("tag4", tag4) + .bind("tag5", tag5); + + try { + saveHelper.execute(this.repository); + } catch (SQLException e) { + throw new DataException("Unable to save arbitrary metadata into repository", e); + } + } + + @Override + public void delete(ArbitraryResourceMetadata metadata) throws DataException { + ArbitraryResourceData arbitraryResourceData = metadata.getArbitraryResourceData(); + if (arbitraryResourceData == null) { + throw new DataException("Can't delete metadata without a referenced resource"); + } + + try { + this.repository.delete("ArbitraryMetadataCache", "service = ? AND name = ? AND identifier = ?", + arbitraryResourceData.service.value, arbitraryResourceData.name, arbitraryResourceData.identifier); + + } catch (SQLException e) { + throw new DataException("Unable to delete account from repository", e); + } + } } diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index aecac034..e3c705e8 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -901,7 +901,7 @@ public class HSQLDBDatabaseUpdates { case 37: // ARBITRARY transaction updates for off-chain data storage - // We may want to use a nonce rather than a transaction fee on the data chain + // We may want to use a nonce rather than a transaction fee for ARBITRARY transactions stmt.execute("ALTER TABLE ArbitraryTransactions ADD nonce INT NOT NULL DEFAULT 0"); // We need to know the total size of the data file(s) associated with each transaction stmt.execute("ALTER TABLE ArbitraryTransactions ADD size INT NOT NULL DEFAULT 0"); @@ -993,6 +993,44 @@ public class HSQLDBDatabaseUpdates { stmt.execute("ALTER TABLE CancelSellNameTransactions ADD sale_price QortalAmount"); break; + case 47: + // We need to keep a local cache of arbitrary resources (items published to QDN), for easier searching. + // IMPORTANT: this is a cache of the last known state of a resource (both confirmed + // and valid unconfirmed). It cannot be assumed that all nodes will contain the same state at a + // given block height, and therefore must NOT be used for any consensus/validation code. It is + // simply a cache, to avoid having to query the raw transactions and the metadata in flat files + // when serving API requests. + // ARBITRARY transactions aren't really suitable for updating resources in the same way we'd update + // names or groups for instance, as there is no distinction between creations and updates, and metadata + // is off-chain. Plus, QDN allows (valid) unconfirmed data to be queried and viewed. It is very + // easy to keep a cache of the latest transaction's data, but anything more than that would need + // considerable thought (and most likely a rewrite). + + stmt.execute("CREATE TABLE ArbitraryResourcesCache (service SMALLINT NOT NULL, " + + "name RegisteredName NOT NULL, identifier VARCHAR(64), size INT NOT NULL, " + + "created_when EpochMillis NOT NULL, updated_when EpochMillis, " + + "PRIMARY KEY (service, name, identifier))"); + // For finding resources by service. + stmt.execute("CREATE INDEX ArbitraryResourcesServiceIndex ON ArbitraryResourcesCache (service)"); + // For finding resources by name. + stmt.execute("CREATE INDEX ArbitraryResourcesNameIndex ON ArbitraryResourcesCache (name)"); + // For finding resources by identifier. + stmt.execute("CREATE INDEX ArbitraryResourcesIdentifierIndex ON ArbitraryResourcesCache (identifier)"); + // For finding resources by creation date (the default column when ordering). + stmt.execute("CREATE INDEX ArbitraryResourcesCreatedIndex ON ArbitraryResourcesCache (created_when)"); + // Use a separate table space as this table will be very large. + stmt.execute("SET TABLE ArbitraryResourcesCache NEW SPACE"); + + stmt.execute("CREATE TABLE ArbitraryMetadataCache (service SMALLINT NOT NULL, " + + "name RegisteredName NOT NULL, identifier VARCHAR(64), " + + "title VARCHAR(80), description VARCHAR(240), category VARCHAR(64), " + + "tag1 VARCHAR(20), tag2 VARCHAR(20), tag3 VARCHAR(20), tag4 VARCHAR(20), tag5 VARCHAR(20), " + + "PRIMARY KEY (service, name, identifier), FOREIGN KEY (service, name, identifier) " + + "REFERENCES ArbitraryResourcesCache (service, name, identifier) ON DELETE CASCADE)"); + // For finding metadata by title. + stmt.execute("CREATE INDEX ArbitraryMetadataTitleIndex ON ArbitraryMetadataCache (title)"); + break; + default: // nothing to do return false; diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 7034d7b8..88be95a2 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -1,18 +1,21 @@ package org.qortal.transaction; -import java.util.Arrays; +import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import org.qortal.account.Account; +import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; +import org.qortal.arbitrary.misc.Service; import org.qortal.block.BlockChain; import org.qortal.controller.arbitrary.ArbitraryDataManager; -import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; import org.qortal.crypto.Crypto; import org.qortal.crypto.MemoryPoW; import org.qortal.data.PaymentData; +import org.qortal.data.arbitrary.ArbitraryResourceData; +import org.qortal.data.arbitrary.ArbitraryResourceMetadata; import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; @@ -248,6 +251,10 @@ public class ArbitraryTransaction extends Transaction { ArbitraryDataManager.getInstance().invalidateCache(arbitraryTransactionData); } } + + // Add to arbitrary resource caches + this.updateArbitraryResourceCache(); + this.updateArbitraryMetadataCache(); } @Override @@ -304,4 +311,123 @@ public class ArbitraryTransaction extends Transaction { return null; } + /** + * Update the arbitrary resources cache. + * This finds the latest transaction and replaces the + * majority of the data in the cache. The current + * transaction is used for the created time, + * if it has a lower timestamp than the existing value. + * It's also used to identify the correct + * service/name/identifier combination. + * + * @throws DataException + */ + public void updateArbitraryResourceCache() throws DataException { + // Don't cache resources without a name (such as auto updates) + if (arbitraryTransactionData.getName() == null) { + return; + } + + // Get the latest transaction + ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(arbitraryTransactionData.getName(), arbitraryTransactionData.getService(), null, arbitraryTransactionData.getIdentifier()); + if (latestTransactionData == null) { + // We don't have a latest transaction, so give up + return; + } + + Service service = arbitraryTransactionData.getService(); + String name = arbitraryTransactionData.getName(); + String identifier = arbitraryTransactionData.getIdentifier(); + + // In the cache we store null identifiers as "default", as it is part of the primary key + if (identifier == null) { + identifier = "default"; + } + + // Get existing cached entry if it exists + ArbitraryResourceData existingArbitraryResourceData = repository.getArbitraryRepository() + .getArbitraryResource(service, name, identifier); + + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.service = service; + arbitraryResourceData.name = name; + arbitraryResourceData.identifier = identifier; + + // Check for existing cached data + if (existingArbitraryResourceData == null) { + // Nothing exists yet, so set everything from the newest transaction + arbitraryResourceData.created = latestTransactionData.getTimestamp(); + arbitraryResourceData.updated = null; + } + else { + // An entry already exists - update created time from current transaction if this is older + arbitraryResourceData.created = Math.min(existingArbitraryResourceData.created, arbitraryTransactionData.getTimestamp()); + + // Set updated time to the latest transaction's timestamp, unless it matches the creation time + if (existingArbitraryResourceData.created == latestTransactionData.getTimestamp()) { + // Latest transaction matches created time, so it hasn't been updated + arbitraryResourceData.updated = null; + } + else { + arbitraryResourceData.updated = latestTransactionData.getTimestamp(); + } + } + + arbitraryResourceData.size = latestTransactionData.getSize(); + + // Save + repository.getArbitraryRepository().save(arbitraryResourceData); + } + + public void updateArbitraryMetadataCache() throws DataException { + // Get the latest transaction + ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(arbitraryTransactionData.getName(), arbitraryTransactionData.getService(), null, arbitraryTransactionData.getIdentifier()); + if (latestTransactionData == null) { + // We don't have a latest transaction, so give up + return; + } + + Service service = latestTransactionData.getService(); + String name = latestTransactionData.getName(); + String identifier = latestTransactionData.getIdentifier(); + + // In the cache we store null identifiers as "default", as it is part of the primary key + if (identifier == null) { + identifier = "default"; + } + + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.service = service; + arbitraryResourceData.name = name; + arbitraryResourceData.identifier = identifier; + + // Update metadata for latest transaction if it is local + if (latestTransactionData.getMetadataHash() != null) { + ArbitraryDataFile metadataFile = ArbitraryDataFile.fromHash(latestTransactionData.getMetadataHash(), latestTransactionData.getSignature()); + if (metadataFile.exists()) { + ArbitraryDataTransactionMetadata transactionMetadata = new ArbitraryDataTransactionMetadata(metadataFile.getFilePath()); + try { + transactionMetadata.read(); + + ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); + metadata.setArbitraryResourceData(arbitraryResourceData); + metadata.setTitle(transactionMetadata.getTitle()); + metadata.setDescription(transactionMetadata.getDescription()); + metadata.setCategory(transactionMetadata.getCategory()); + metadata.setTags(transactionMetadata.getTags()); + repository.getArbitraryRepository().save(metadata); + + } catch (IOException e) { + // Ignore, as we can add it again later + } + } else { + // We don't have a local copy of this metadata file, so delete it from the cache + // It will be re-added if the file later arrives via the network + ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); + metadata.setArbitraryResourceData(arbitraryResourceData); + repository.getArbitraryRepository().delete(metadata); + } + } + } + } diff --git a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java index efd84110..15ade240 100644 --- a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java +++ b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java @@ -4,10 +4,8 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.arbitrary.*; -import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; -import org.qortal.data.arbitrary.ArbitraryResourceInfo; -import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; @@ -258,8 +256,7 @@ public class ArbitraryTransactionUtils { "chunks if needed", Base58.encode(completeHash)); ArbitraryTransactionUtils.deleteCompleteFile(arbitraryTransactionData, now, cleanupAfter); - } - else { + } else { // File might be in use. It's best to leave it and it it will be cleaned up later. } } @@ -271,6 +268,7 @@ public class ArbitraryTransactionUtils { * When first uploaded, files go into a _misc folder as they are not yet associated with a * transaction signature. Once the transaction is broadcast, they need to be moved to the * correct location, keyed by the transaction signature. + * * @param arbitraryTransactionData * @return * @throws DataException @@ -356,8 +354,7 @@ public class ArbitraryTransactionUtils { file.createNewFile(); } } - } - catch (DataException | IOException e) { + } catch (DataException | IOException e) { LOGGER.info("Unable to check and relocate all files for signature {}: {}", Base58.encode(arbitraryTransactionData.getSignature()), e.getMessage()); } @@ -366,7 +363,7 @@ public class ArbitraryTransactionUtils { } public static List limitOffsetTransactions(List transactions, - Integer limit, Integer offset) { + Integer limit, Integer offset) { if (limit != null && limit == 0) { limit = null; } @@ -389,6 +386,7 @@ public class ArbitraryTransactionUtils { /** * Lookup status of resource + * * @param service * @param name * @param identifier @@ -413,10 +411,10 @@ public class ArbitraryTransactionUtils { return resource.getStatus(false); } - public static List addStatusToResources(List resources) { + public static List addStatusToResources(List resources) { // Determine and add the status of each resource - List updatedResources = new ArrayList<>(); - for (ArbitraryResourceInfo resourceInfo : resources) { + List updatedResources = new ArrayList<>(); + for (ArbitraryResourceData resourceInfo : resources) { try { ArbitraryDataResource resource = new ArbitraryDataResource(resourceInfo.name, ArbitraryDataFile.ResourceIdType.NAME, resourceInfo.service, resourceInfo.identifier); @@ -433,21 +431,4 @@ public class ArbitraryTransactionUtils { } return updatedResources; } - - public static List addMetadataToResources(List resources) { - // Add metadata fields to each resource if they exist - List updatedResources = new ArrayList<>(); - for (ArbitraryResourceInfo resourceInfo : resources) { - ArbitraryDataResource resource = new ArbitraryDataResource(resourceInfo.name, ArbitraryDataFile.ResourceIdType.NAME, - resourceInfo.service, resourceInfo.identifier); - ArbitraryDataTransactionMetadata transactionMetadata = resource.getLatestTransactionMetadata(); - ArbitraryResourceMetadata resourceMetadata = ArbitraryResourceMetadata.fromTransactionMetadata(transactionMetadata, false); - if (resourceMetadata != null) { - resourceInfo.metadata = resourceMetadata; - } - updatedResources.add(resourceInfo); - } - return updatedResources; - } - } From eb7a29dd2eefa2cbf748140cd54eedc6ca55f848 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 30 Apr 2023 10:58:27 +0100 Subject: [PATCH 02/74] Fixed bugs. --- .../arbitrary/ArbitraryDataManager.java | 1 + .../arbitrary/ArbitraryMetadataManager.java | 1 + .../hsqldb/HSQLDBArbitraryRepository.java | 20 ++++++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index e32fcb0f..60bf63b3 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -570,6 +570,7 @@ public class ArbitraryDataManager extends Thread { arbitraryTransaction.updateArbitraryMetadataCache(); } ; + repository.saveChanges(); } catch (DataException e) { // Not much we can do, so ignore for now } diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index a496485b..f99ec953 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -359,6 +359,7 @@ public class ArbitraryMetadataManager { ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, arbitraryTransactionData); arbitraryTransaction.updateArbitraryResourceCache(); arbitraryTransaction.updateArbitraryMetadataCache(); + repository.saveChanges(); } } catch (DataException e) { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 9c88e39c..2ee49fa0 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -2,6 +2,7 @@ package org.qortal.repository.hsqldb; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceData; @@ -219,6 +220,11 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } private ArbitraryTransactionData getSingleTransaction(String name, Service service, Method method, String identifier, boolean firstNotLast) throws DataException { + if (name == null || service == null) { + // Required fields + return null; + } + StringBuilder sql = new StringBuilder(1024); sql.append("SELECT type, reference, signature, creator, created_when, fee, " + @@ -490,7 +496,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (defaultResource) { // Default resource requested - use NULL identifier - sql.append(" AND identifier IS NULL"); + sql.append(" AND identifier='default'"); } else { // Non-default resource requested @@ -641,7 +647,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (defaultResource) { // Default resource requested - use NULL identifier and search name only - sql.append(" AND LCASE(name) LIKE ? AND identifier IS NULL"); + sql.append(" AND LCASE(name) LIKE ? AND identifier='default'"); bindParams.add(queryWildcard); } else { // Non-default resource requested @@ -831,13 +837,17 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { throw new DataException("Can't save metadata without a referenced resource"); } + // Trim metadata values if they are too long to fit in the db + String title = ArbitraryDataTransactionMetadata.limitTitle(metadata.getTitle()); + String description = ArbitraryDataTransactionMetadata.limitTitle(metadata.getDescription()); + List tags = ArbitraryDataTransactionMetadata.limitTags(metadata.getTags()); + String tag1 = null; String tag2 = null; String tag3 = null; String tag4 = null; String tag5 = null; - List tags = metadata.getTags(); if (tags != null) { if (tags.size() > 0) tag1 = tags.get(0); if (tags.size() > 1) tag2 = tags.get(1); @@ -849,8 +859,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { String category = metadata.getCategory() != null ? metadata.getCategory().toString() : null; saveHelper.bind("service", arbitraryResourceData.service.value).bind("name", arbitraryResourceData.name) - .bind("identifier", arbitraryResourceData.identifier).bind("title", metadata.getTitle()) - .bind("description", metadata.getDescription()).bind("category", category) + .bind("identifier", arbitraryResourceData.identifier).bind("title", title) + .bind("description", description).bind("category", category) .bind("tag1", tag1).bind("tag2", tag2).bind("tag3", tag3).bind("tag4", tag4) .bind("tag5", tag5); From 200b0f3412867da03ba2dc8375d64136b3e6467a Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 11:43:48 +0100 Subject: [PATCH 03/74] Added `POST /arbitrary/resources/cache/rebuild` endpoint to allow a rebuild of the cache. --- .../api/resource/ArbitraryResource.java | 30 +++++++++++++++++++ .../org/qortal/controller/Controller.java | 2 +- .../qortal/repository/RepositoryManager.java | 4 +-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 1e243c51..9a2fceaa 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -1119,6 +1119,36 @@ public class ArbitraryResource { } + @POST + @Path("/resources/cache/rebuild") + @Operation( + summary = "Rebuild arbitrary resources cache from transactions", + responses = { + @ApiResponse( + description = "true on success", + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "boolean" + ) + ) + ) + } + ) + @SecurityRequirement(name = "apiKey") + public String rebuildCache(@HeaderParam(Security.API_KEY_HEADER) String apiKey) { + Security.checkApiCallAllowed(request); + + try (final Repository repository = RepositoryManager.getRepository()) { + RepositoryManager.buildArbitraryResourcesCache(repository, true); + + return "true"; + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.REPOSITORY_ISSUE, e.getMessage()); + } + } + + // Shared methods private String preview(String directoryPath, Service service) { diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index e4944a66..1de6f776 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -403,7 +403,7 @@ public class Controller extends Thread { RepositoryManager.setRequestedCheckpoint(Boolean.TRUE); try (final Repository repository = RepositoryManager.getRepository()) { - RepositoryManager.buildInitialArbitraryResourcesCache(repository); + RepositoryManager.buildArbitraryResourcesCache(repository, false); } } catch (DataException e) { diff --git a/src/main/java/org/qortal/repository/RepositoryManager.java b/src/main/java/org/qortal/repository/RepositoryManager.java index 404b6b34..e4a287c0 100644 --- a/src/main/java/org/qortal/repository/RepositoryManager.java +++ b/src/main/java/org/qortal/repository/RepositoryManager.java @@ -64,7 +64,7 @@ public abstract class RepositoryManager { } } - public static boolean buildInitialArbitraryResourcesCache(Repository repository) throws DataException { + public static boolean buildArbitraryResourcesCache(Repository repository, boolean forceRebuild) throws DataException { if (Settings.getInstance().isLite()) { // Lite nodes have no blockchain return false; @@ -73,7 +73,7 @@ public abstract class RepositoryManager { try { // Check if QDNResources table is empty List resources = repository.getArbitraryRepository().getArbitraryResources(10, 0, false); - if (!resources.isEmpty()) { + if (!resources.isEmpty() && !forceRebuild) { // Resources exist in the cache, so assume complete. // We avoid checkpointing and prevent the node from starting up in the case of a rebuild failure, so // we shouldn't ever be left in a partially rebuilt state. From 94f4c501fa1fe4aaf3b69383d5e86dc7cf345341 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 11:49:57 +0100 Subject: [PATCH 04/74] Update caches where possible when processing arbitrary transactions. --- .../transaction/ArbitraryTransaction.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 88be95a2..2a3c78af 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.qortal.account.Account; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; @@ -32,6 +34,8 @@ import org.qortal.utils.NTP; public class ArbitraryTransaction extends Transaction { + private static final Logger LOGGER = LogManager.getLogger(ArbitraryTransaction.class); + // Properties private ArbitraryTransactionData arbitraryTransactionData; @@ -274,6 +278,30 @@ public class ArbitraryTransaction extends Transaction { public void process() throws DataException { // Wrap and delegate payment processing to Payment class. new Payment(this.repository).process(arbitraryTransactionData.getSenderPublicKey(), arbitraryTransactionData.getPayments()); + + // Update caches + this.updateCaches(); + } + + private void updateCaches() { + try { + // If the data is local, we need to perform a few actions + if (isDataLocal()) { + + // We have the data for this transaction, so invalidate the file cache + if (arbitraryTransactionData.getName() != null) { + ArbitraryDataManager.getInstance().invalidateCache(arbitraryTransactionData); + } + } + + // Add/update arbitrary resource caches + this.updateArbitraryResourceCache(); + this.updateArbitraryMetadataCache(); + + } catch (Exception e) { + // Log and ignore all exceptions. The cache is updated from other places too, and can be rebuilt if needed. + LOGGER.info("Unable to update arbitrary caches", e); + } } @Override From c0f29f848ff74232f797e9a4822acbda1453fd67 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 12:27:51 +0100 Subject: [PATCH 05/74] Fixed more bugs. --- .../arbitrary/ArbitraryResourceMetadata.java | 4 ++++ .../org/qortal/repository/RepositoryManager.java | 6 +++--- .../hsqldb/HSQLDBArbitraryRepository.java | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java index 614a8e69..c6f0ae62 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceMetadata.java @@ -101,6 +101,10 @@ public class ArbitraryResourceMetadata { return this.category; } + public boolean hasMetadata() { + return title != null || description != null || tags != null || category != null || files != null || mimeType != null; + } + public void setArbitraryResourceData(ArbitraryResourceData arbitraryResourceData) { this.arbitraryResourceData = arbitraryResourceData; } diff --git a/src/main/java/org/qortal/repository/RepositoryManager.java b/src/main/java/org/qortal/repository/RepositoryManager.java index e4a287c0..d7608401 100644 --- a/src/main/java/org/qortal/repository/RepositoryManager.java +++ b/src/main/java/org/qortal/repository/RepositoryManager.java @@ -115,15 +115,15 @@ public abstract class RepositoryManager { } repository.saveChanges(); - LOGGER.info("Completed build of initial arbitrary resources cache."); + LOGGER.info("Completed build of arbitrary resources cache."); return true; } catch (DataException e) { - LOGGER.info("Unable to build initial arbitrary resources cache: {}. The database may have been left in an inconsistent state.", e.getMessage()); + LOGGER.info("Unable to build arbitrary resources cache: {}. The database may have been left in an inconsistent state.", e.getMessage()); // Throw an exception so that the node startup is halted, allowing for a retry next time. repository.discardChanges(); - throw new DataException("Build of initial arbitrary resources cache failed."); + throw new DataException("Build of arbitrary resources cache failed."); } } diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 2ee49fa0..05633e0a 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -391,7 +391,9 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (tag5 != null) tags.add(tag5); metadata.setTags(!tags.isEmpty() ? tags : null); - arbitraryResourceData.metadata = metadata; + if (metadata.hasMetadata()) { + arbitraryResourceData.metadata = metadata; + } return arbitraryResourceData; } catch (SQLException e) { @@ -465,7 +467,9 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (tag5 != null) tags.add(tag5); metadata.setTags(!tags.isEmpty() ? tags : null); - arbitraryResourceData.metadata = metadata; + if (metadata.hasMetadata()) { + arbitraryResourceData.metadata = metadata; + } arbitraryResources.add(arbitraryResourceData); } while (resultSet.next()); @@ -608,7 +612,9 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (tag5 != null) tags.add(tag5); metadata.setTags(!tags.isEmpty() ? tags : null); - arbitraryResourceData.metadata = metadata; + if (metadata.hasMetadata()) { + arbitraryResourceData.metadata = metadata; + } } arbitraryResources.add(arbitraryResourceData); @@ -782,7 +788,9 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (tag5 != null) tags.add(tag5); metadata.setTags(!tags.isEmpty() ? tags : null); - arbitraryResourceData.metadata = metadata; + if (metadata.hasMetadata()) { + arbitraryResourceData.metadata = metadata; + } } arbitraryResources.add(arbitraryResourceData); From 865d3d8aff7120d36799bdfca46e16649b9bf1c4 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 12:46:01 +0100 Subject: [PATCH 06/74] Fixed ordering, to keep consistency with existing approach. --- .../org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 05633e0a..3061b7b0 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -552,7 +552,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } - sql.append(" ORDER BY created_when"); + sql.append(" ORDER BY name COLLATE SQL_TEXT_UCC_NO_PAD"); if (reverse != null && reverse) { sql.append(" DESC"); From 961aa9eefd2ffe48adf8f3027a06327f40d4f4eb Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 13:02:22 +0100 Subject: [PATCH 07/74] Show splash screen when building QDN cache. --- src/main/java/org/qortal/repository/RepositoryManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/qortal/repository/RepositoryManager.java b/src/main/java/org/qortal/repository/RepositoryManager.java index d7608401..26eb49e3 100644 --- a/src/main/java/org/qortal/repository/RepositoryManager.java +++ b/src/main/java/org/qortal/repository/RepositoryManager.java @@ -6,6 +6,7 @@ import org.qortal.api.resource.TransactionsResource; import org.qortal.controller.Controller; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.gui.SplashFrame; import org.qortal.settings.Settings; import org.qortal.transaction.ArbitraryTransaction; import org.qortal.transaction.Transaction; @@ -82,6 +83,7 @@ public abstract class RepositoryManager { } LOGGER.info("Building arbitrary resources cache..."); + SplashFrame.getInstance().updateStatus("Building QDN cache - please wait..."); final int batchSize = 100; int offset = 0; From d03a2d7da931b5f460a4b5c587bc31d09d846c1f Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 15:50:19 +0100 Subject: [PATCH 08/74] Resource statuses moved to the db, so they don't have to be calculated on demand for every API call. --- .../api/gateway/resource/GatewayResource.java | 2 +- .../api/resource/ArbitraryResource.java | 17 +-- .../ArbitraryDataBuildQueueItem.java | 4 + .../qortal/arbitrary/ArbitraryDataReader.java | 2 +- .../arbitrary/ArbitraryDataResource.java | 32 +++-- .../PirateChainWalletController.java | 2 +- .../arbitrary/ArbitraryDataBuilderThread.java | 12 ++ .../data/arbitrary/ArbitraryResourceData.java | 21 ++++ .../arbitrary/ArbitraryResourceStatus.java | 39 ++++-- .../repository/ArbitraryRepository.java | 2 + .../hsqldb/HSQLDBArbitraryRepository.java | 112 +++++++++++------- .../hsqldb/HSQLDBDatabaseUpdates.java | 2 +- .../transaction/ArbitraryTransaction.java | 8 ++ .../utils/ArbitraryTransactionUtils.java | 25 +--- 14 files changed, 176 insertions(+), 104 deletions(-) diff --git a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java index 9c77753f..7d76be3d 100644 --- a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java +++ b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java @@ -70,7 +70,7 @@ public class GatewayResource { } ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.getStatus(false); + return resource.getStatus(); } diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 9a2fceaa..2b3b986f 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -141,10 +141,6 @@ public class ArbitraryResource { return new ArrayList<>(); } - if (includeStatus != null && includeStatus) { - resources = ArbitraryTransactionUtils.addStatusToResources(resources); - } - return resources; } catch (DataException e) { @@ -212,10 +208,6 @@ public class ArbitraryResource { return new ArrayList<>(); } - if (includeStatus != null && includeStatus) { - resources = ArbitraryTransactionUtils.addStatusToResources(resources); - } - return resources; } catch (DataException e) { @@ -243,7 +235,7 @@ public class ArbitraryResource { if (!Settings.getInstance().isQDNAuthBypassEnabled()) Security.requirePriorAuthorizationOrApiKey(request, name, service, null, apiKey); - return ArbitraryTransactionUtils.getStatus(service, name, null, build); + return ArbitraryTransactionUtils.getStatus(service, name, null, build, true); } @GET @@ -290,7 +282,7 @@ public class ArbitraryResource { if (!Settings.getInstance().isQDNAuthBypassEnabled()) Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier, apiKey); - return ArbitraryTransactionUtils.getStatus(service, name, identifier, build); + return ArbitraryTransactionUtils.getStatus(service, name, identifier, build, true); } @@ -482,7 +474,6 @@ public class ArbitraryResource { @ApiErrors({ApiError.REPOSITORY_ISSUE}) public List getHostedResources( @HeaderParam(Security.API_KEY_HEADER) String apiKey, - @Parameter(description = "Include status") @QueryParam("includestatus") Boolean includeStatus, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @QueryParam("query") String query) { @@ -513,10 +504,6 @@ public class ArbitraryResource { } } - if (includeStatus != null && includeStatus) { - resources = ArbitraryTransactionUtils.addStatusToResources(resources); - } - return resources; } catch (DataException e) { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java index 4a02f092..465d1391 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java @@ -4,6 +4,7 @@ import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.ArbitraryDataFile.*; import org.qortal.arbitrary.misc.Service; import org.qortal.repository.DataException; +import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.NTP; import java.io.IOException; @@ -51,6 +52,9 @@ public class ArbitraryDataBuildQueueItem extends ArbitraryDataResource { arbitraryDataReader.loadSynchronously(true); } finally { this.buildEndTimestamp = NTP.getTime(); + + // Update status after build + ArbitraryTransactionUtils.getStatus(service, resourceId, identifier, false, true); } } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java index b9e62e56..f281cec5 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java @@ -240,7 +240,7 @@ public class ArbitraryDataReader { try { Files.createDirectories(this.workingPath); } catch (IOException e) { - throw new DataException("Unable to create temp directory"); + throw new DataException(String.format("Unable to create temp directory %s: %s", this.workingPath, e.getMessage())); } } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java index a4650dfc..4aed21fc 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java @@ -9,6 +9,7 @@ import org.qortal.arbitrary.misc.Service; import org.qortal.controller.arbitrary.ArbitraryDataBuildManager; import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; +import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.repository.DataException; @@ -57,17 +58,34 @@ public class ArbitraryDataResource { this.identifier = identifier; } - public ArbitraryResourceStatus getStatus(boolean quick) { - // Calculate the chunk counts - // Avoid this for "quick" statuses, to speed things up - if (!quick) { - this.calculateChunkCounts(); + public ArbitraryResourceStatus getStatusAndUpdateCache(boolean updateCache) { + ArbitraryResourceStatus arbitraryResourceStatus = this.getStatus(); - if (!this.exists) { - return new ArbitraryResourceStatus(Status.NOT_PUBLISHED, this.localChunkCount, this.totalChunkCount); + if (updateCache) { + // Update cache if possible + ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); + + try (final Repository repository = RepositoryManager.getRepository()) { + repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); + repository.saveChanges(); + + } catch (DataException e) { + LOGGER.info("Unable to update status cache for resource {}: {}", arbitraryResourceData, e.getMessage()); } } + return arbitraryResourceStatus; + } + + public ArbitraryResourceStatus getStatus() { + // Calculate the chunk counts + this.calculateChunkCounts(); + + if (!this.exists) { + return new ArbitraryResourceStatus(Status.NOT_PUBLISHED, this.localChunkCount, this.totalChunkCount); + } + if (resourceIdType != ResourceIdType.NAME) { // We only support statuses for resources with a name return new ArbitraryResourceStatus(Status.UNSUPPORTED, this.localChunkCount, this.totalChunkCount); diff --git a/src/main/java/org/qortal/controller/PirateChainWalletController.java b/src/main/java/org/qortal/controller/PirateChainWalletController.java index 90e65329..e009d531 100644 --- a/src/main/java/org/qortal/controller/PirateChainWalletController.java +++ b/src/main/java/org/qortal/controller/PirateChainWalletController.java @@ -187,7 +187,7 @@ public class PirateChainWalletController extends Thread { // Check its status ArbitraryResourceStatus status = ArbitraryTransactionUtils.getStatus( - t.getService(), t.getName(), t.getIdentifier(), false); + t.getService(), t.getName(), t.getIdentifier(), false, true); if (status.getStatus() != ArbitraryResourceStatus.Status.READY) { LOGGER.info("Not ready yet: {}", status.getTitle()); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java index 0fb685a3..a2165a9e 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java @@ -5,13 +5,17 @@ import org.apache.logging.log4j.Logger; import org.qortal.arbitrary.ArbitraryDataBuildQueueItem; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.controller.Controller; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.repository.DataException; +import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.NTP; import java.io.IOException; import java.util.Comparator; import java.util.Map; +import static org.qortal.data.arbitrary.ArbitraryResourceStatus.Status.*; + public class ArbitraryDataBuilderThread implements Runnable { @@ -69,6 +73,14 @@ public class ArbitraryDataBuilderThread implements Runnable { continue; } + // Get status before build + ArbitraryResourceStatus arbitraryResourceStatus = ArbitraryTransactionUtils.getStatus(queueItem.getService(), queueItem.getResourceId(), queueItem.getIdentifier(), false, true); + if (arbitraryResourceStatus.getStatus() == NOT_PUBLISHED) { + // No point in building a non-existent resource + this.removeFromQueue(queueItem); + continue; + } + // Set the start timestamp, to prevent other threads from building it at the same time queueItem.prepareForBuild(); } diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java index 4f636177..ffd30209 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java @@ -6,6 +6,8 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import java.util.Objects; +import static org.qortal.data.arbitrary.ArbitraryResourceStatus.Status; + @XmlAccessorType(XmlAccessType.FIELD) public class ArbitraryResourceData { @@ -22,11 +24,30 @@ public class ArbitraryResourceData { public ArbitraryResourceData() { } + public ArbitraryResourceData(Service service, String name, String identifier) { + if (identifier == null) { + identifier = "default"; + } + + this.service = service; + this.name = name; + this.identifier = identifier; + } + @Override public String toString() { return String.format("%s %s %s", name, service, identifier); } + public void setStatus(Status status) { + if (status == null) { + this.status = null; + } + else { + this.status = new ArbitraryResourceStatus(status); + } + } + @Override public boolean equals(Object o) { if (o == this) diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java index 54dd2af6..6513776a 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java @@ -2,29 +2,46 @@ package org.qortal.data.arbitrary; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import java.util.Map; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; @XmlAccessorType(XmlAccessType.FIELD) public class ArbitraryResourceStatus { public enum Status { - PUBLISHED("Published", "Published but not yet downloaded"), - NOT_PUBLISHED("Not published", "Resource does not exist"), - DOWNLOADING("Downloading", "Locating and downloading files..."), - DOWNLOADED("Downloaded", "Files downloaded"), - BUILDING("Building", "Building..."), - READY("Ready", "Ready"), - MISSING_DATA("Missing data", "Unable to locate all files. Please try again later"), - BUILD_FAILED("Build failed", "Build failed. Please try again later"), - UNSUPPORTED("Unsupported", "Unsupported request"), - BLOCKED("Blocked", "Name is blocked so content cannot be served"); + // Note: integer values must not be updated, as they are stored in the db + PUBLISHED(1, "Published", "Published but not yet downloaded"), + NOT_PUBLISHED(2, "Not published", "Resource does not exist"), + DOWNLOADING(3, "Downloading", "Locating and downloading files..."), + DOWNLOADED(4, "Downloaded", "Files downloaded"), + BUILDING(5, "Building", "Building..."), + READY(6, "Ready", "Ready"), + MISSING_DATA(7, "Missing data", "Unable to locate all files. Please try again later"), + BUILD_FAILED(8, "Build failed", "Build failed. Please try again later"), + UNSUPPORTED(9, "Unsupported", "Unsupported request"), + BLOCKED(10, "Blocked", "Name is blocked so content cannot be served"); + public int value; private String title; private String description; - Status(String title, String description) { + private static final Map map = stream(Status.values()) + .collect(toMap(status -> status.value, status -> status)); + + Status(int value, String title, String description) { + this.value = value; this.title = title; this.description = description; } + + public static Status valueOf(Integer value) { + if (value == null) { + return null; + } + return map.get(value); + } } private Status status; diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 63729e46..7a21a1a2 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -3,6 +3,7 @@ package org.qortal.repository; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; @@ -44,6 +45,7 @@ public interface ArbitraryRepository { // Arbitrary resources cache save/load public void save(ArbitraryResourceData arbitraryResourceData) throws DataException; + public void setStatus(ArbitraryResourceData arbitraryResourceData, ArbitraryResourceStatus.Status status) throws DataException; public void delete(ArbitraryResourceData arbitraryResourceData) throws DataException; public void save(ArbitraryResourceMetadata metadata) throws DataException; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 3061b7b0..5564d1d3 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -7,6 +7,7 @@ import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; import org.qortal.data.transaction.BaseTransactionData; @@ -327,7 +328,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { return null; } - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -352,18 +353,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -375,6 +377,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -405,7 +408,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -428,18 +431,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -451,6 +455,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -487,7 +492,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -571,18 +576,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -594,6 +600,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -633,7 +640,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -747,18 +754,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -770,6 +778,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -809,6 +818,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { public void save(ArbitraryResourceData arbitraryResourceData) throws DataException { HSQLDBSaver saveHelper = new HSQLDBSaver("ArbitraryResourcesCache"); + // "status" isn't saved here as we update this field separately saveHelper.bind("service", arbitraryResourceData.service.value).bind("name", arbitraryResourceData.name) .bind("identifier", arbitraryResourceData.identifier).bind("size", arbitraryResourceData.size) .bind("created_when", arbitraryResourceData.created).bind("updated_when", arbitraryResourceData.updated); @@ -820,6 +830,20 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } + @Override + public void setStatus(ArbitraryResourceData arbitraryResourceData, ArbitraryResourceStatus.Status status) throws DataException { + if (status == null) { + return; + } + String updateSql = "UPDATE ArbitraryResourcesCache SET status = ? WHERE service = ? AND name = ? AND identifier = ?"; + + try { + this.repository.executeCheckedUpdate(updateSql, status.value, arbitraryResourceData.service.value, arbitraryResourceData.name, arbitraryResourceData.identifier); + } catch (SQLException e) { + throw new DataException("Unable to set status for arbitrary resource", e); + } + } + @Override public void delete(ArbitraryResourceData arbitraryResourceData) throws DataException { // NOTE: arbitrary metadata are deleted automatically by the database thanks to "ON DELETE CASCADE" diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index e3c705e8..b54f4b08 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -1008,7 +1008,7 @@ public class HSQLDBDatabaseUpdates { stmt.execute("CREATE TABLE ArbitraryResourcesCache (service SMALLINT NOT NULL, " + "name RegisteredName NOT NULL, identifier VARCHAR(64), size INT NOT NULL, " - + "created_when EpochMillis NOT NULL, updated_when EpochMillis, " + + "status INTEGER, created_when EpochMillis NOT NULL, updated_when EpochMillis, " + "PRIMARY KEY (service, name, identifier))"); // For finding resources by service. stmt.execute("CREATE INDEX ArbitraryResourcesServiceIndex ON ArbitraryResourcesCache (service)"); diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 2a3c78af..b2954dd9 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -8,6 +8,7 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; +import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.block.BlockChain; @@ -18,6 +19,7 @@ import org.qortal.crypto.MemoryPoW; import org.qortal.data.PaymentData; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; @@ -405,6 +407,12 @@ public class ArbitraryTransaction extends Transaction { // Save repository.getArbitraryRepository().save(arbitraryResourceData); + + // Update status + ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); + ArbitraryResourceStatus arbitraryResourceStatus = resource.getStatus(); + ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; + repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); } public void updateArbitraryMetadataCache() throws DataException { diff --git a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java index 15ade240..bf7e2aa6 100644 --- a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java +++ b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java @@ -393,7 +393,7 @@ public class ArbitraryTransactionUtils { * @param build * @return */ - public static ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build) { + public static ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build, boolean updateCache) { // If "build" has been specified, build the resource before returning its status if (build != null && build == true) { @@ -408,27 +408,6 @@ public class ArbitraryTransactionUtils { } ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); - return resource.getStatus(false); - } - - public static List addStatusToResources(List resources) { - // Determine and add the status of each resource - List updatedResources = new ArrayList<>(); - for (ArbitraryResourceData resourceInfo : resources) { - try { - ArbitraryDataResource resource = new ArbitraryDataResource(resourceInfo.name, ArbitraryDataFile.ResourceIdType.NAME, - resourceInfo.service, resourceInfo.identifier); - ArbitraryResourceStatus status = resource.getStatus(true); - if (status != null) { - resourceInfo.status = status; - } - updatedResources.add(resourceInfo); - - } catch (Exception e) { - // Catch and log all exceptions, since some systems are experiencing 500 errors when including statuses - LOGGER.info("Caught exception when adding status to resource {}: {}", resourceInfo, e.toString()); - } - } - return updatedResources; + return resource.getStatusAndUpdateCache(updateCache); } } From cdcb268bd9ae45977edd43ef0da0c7f3a94eaa9d Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 17:21:41 +0100 Subject: [PATCH 09/74] Exclude status if includeStatus != true --- .../qortal/api/resource/ArbitraryResource.java | 4 ++-- .../qortal/repository/ArbitraryRepository.java | 4 ++-- .../hsqldb/HSQLDBArbitraryRepository.java | 15 +++++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 2b3b986f..08a9b73c 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -135,7 +135,7 @@ public class ArbitraryResource { List resources = repository.getArbitraryRepository() .getArbitraryResources(service, identifier, names, defaultRes, followedOnly, excludeBlocked, - includeMetadata, limit, offset, reverse); + includeMetadata, includeStatus, limit, offset, reverse); if (resources == null) { return new ArrayList<>(); @@ -202,7 +202,7 @@ public class ArbitraryResource { List resources = repository.getArbitraryRepository() .searchArbitraryResources(service, query, identifier, names, usePrefixOnly, exactMatchNames, - defaultRes, followedOnly, excludeBlocked, includeMetadata, limit, offset, reverse); + defaultRes, followedOnly, excludeBlocked, includeMetadata, includeStatus, limit, offset, reverse); if (resources == null) { return new ArrayList<>(); diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 7a21a1a2..572d2a59 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -37,9 +37,9 @@ public interface ArbitraryRepository { public List getArbitraryResources(Integer limit, Integer offset, Boolean reverse) throws DataException; - public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; // Arbitrary resources cache save/load diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 5564d1d3..71428cb6 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -488,7 +488,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, - Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException { + Boolean includeMetadata, Boolean includeStatus, + Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); @@ -600,10 +601,13 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; - arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; + if (includeStatus != null && includeStatus) { + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); + } + if (includeMetadata != null && includeMetadata) { // TODO: we could avoid the join altogether ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); @@ -636,7 +640,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List exactMatchNames, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, - Boolean includeMetadata, Integer limit, Integer offset, Boolean reverse) throws DataException { + Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); @@ -778,10 +782,13 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; - arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; + if (includeStatus != null && includeStatus) { + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); + } + if (includeMetadata != null && includeMetadata) { // TODO: we could avoid the join altogether ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); From 2fd5bfb11a320607a7c087595f9d3274cefb52a1 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 17:57:14 +0100 Subject: [PATCH 10/74] Support title/description metadata searching in `GET /arbitrary/resources/search` "query" searches name, identifier, title and description fields "title" searches title only "description" searches description only All support "&prefix=true", to indicate searching by prefix only. --- .../api/resource/ArbitraryResource.java | 6 ++-- .../repository/ArbitraryRepository.java | 2 +- .../hsqldb/HSQLDBArbitraryRepository.java | 31 ++++++++++++++----- src/main/resources/q-apps/q-apps.js | 2 ++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 08a9b73c..8762a7f1 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -162,9 +162,11 @@ public class ArbitraryResource { @ApiErrors({ApiError.REPOSITORY_ISSUE}) public List searchResources( @QueryParam("service") Service service, - @Parameter(description = "Query (searches both name and identifier fields)") @QueryParam("query") String query, + @Parameter(description = "Query (searches name, identifier, title and description fields)") @QueryParam("query") String query, @Parameter(description = "Identifier (searches identifier field only)") @QueryParam("identifier") String identifier, @Parameter(description = "Name (searches name field only)") @QueryParam("name") List names, + @Parameter(description = "Title (searches title metadata field only)") @QueryParam("title") String title, + @Parameter(description = "Description (searches description metadata field only)") @QueryParam("description") String description, @Parameter(description = "Prefix only (if true, only the beginning of fields are matched)") @QueryParam("prefix") Boolean prefixOnly, @Parameter(description = "Exact match names only (if true, partial name matches are excluded)") @QueryParam("exactmatchnames") Boolean exactMatchNamesOnly, @Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource, @@ -201,7 +203,7 @@ public class ArbitraryResource { } List resources = repository.getArbitraryRepository() - .searchArbitraryResources(service, query, identifier, names, usePrefixOnly, exactMatchNames, + .searchArbitraryResources(service, query, identifier, names, title, description, usePrefixOnly, exactMatchNames, defaultRes, followedOnly, excludeBlocked, includeMetadata, includeStatus, limit, offset, reverse); if (resources == null) { diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 572d2a59..590aa3b8 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -39,7 +39,7 @@ public interface ArbitraryRepository { public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; // Arbitrary resources cache save/load diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 71428cb6..45706e11 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -638,7 +638,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } @Override - public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, + public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List exactMatchNames, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); @@ -669,9 +669,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } else { // Non-default resource requested // In this case we search the identifier as well as the name - sql.append(" AND (LCASE(name) LIKE ? OR LCASE(identifier) LIKE ?)"); - bindParams.add(queryWildcard); - bindParams.add(queryWildcard); + sql.append(" AND (LCASE(name) LIKE ? OR LCASE(identifier) LIKE ? OR LCASE(title) LIKE ? OR LCASE(description) LIKE ?)"); + bindParams.add(queryWildcard); bindParams.add(queryWildcard); bindParams.add(queryWildcard); bindParams.add(queryWildcard); } } @@ -683,6 +682,22 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { bindParams.add(queryWildcard); } + // Handle title metadata matches + if (title != null) { + // Search anywhere in the title, unless "prefixOnly" has been requested + String queryWildcard = prefixOnly ? String.format("%s%%", title.toLowerCase()) : String.format("%%%s%%", title.toLowerCase()); + sql.append(" AND LCASE(title) LIKE ?"); + bindParams.add(queryWildcard); + } + + // Handle description metadata matches + if (description != null) { + // Search anywhere in the description, unless "prefixOnly" has been requested + String queryWildcard = prefixOnly ? String.format("%s%%", description.toLowerCase()) : String.format("%%%s%%", description.toLowerCase()); + sql.append(" AND LCASE(description) LIKE ?"); + bindParams.add(queryWildcard); + } + // Handle name searches if (names != null && !names.isEmpty()) { sql.append(" AND ("); @@ -763,8 +778,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(8); - String description = resultSet.getString(9); + String titleResult = resultSet.getString(8); + String descriptionResult = resultSet.getString(9); String category = resultSet.getString(10); String tag1 = resultSet.getString(11); String tag2 = resultSet.getString(12); @@ -792,8 +807,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (includeMetadata != null && includeMetadata) { // TODO: we could avoid the join altogether ArbitraryResourceMetadata metadata = new ArbitraryResourceMetadata(); - metadata.setTitle(title); - metadata.setDescription(description); + metadata.setTitle(titleResult); + metadata.setDescription(descriptionResult); metadata.setCategory(Category.uncategorizedValueOf(category)); List tags = new ArrayList<>(); diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js index 86493b48..6c72a410 100644 --- a/src/main/resources/q-apps/q-apps.js +++ b/src/main/resources/q-apps/q-apps.js @@ -218,6 +218,8 @@ window.addEventListener("message", (event) => { if (data.identifier != null) url = url.concat("&identifier=" + data.identifier); if (data.name != null) url = url.concat("&name=" + data.name); if (data.names != null) data.names.forEach((x, i) => url = url.concat("&name=" + x)); + if (data.title != null) url = url.concat("&title=" + data.title); + if (data.description != null) url = url.concat("&description=" + data.description); if (data.prefix != null) url = url.concat("&prefix=" + new Boolean(data.prefix).toString()); if (data.exactMatchNames != null) url = url.concat("&exactmatchnames=" + new Boolean(data.exactMatchNames).toString()); if (data.default != null) url = url.concat("&default=" + new Boolean(data.default).toString()); From 8fa344125c6a0364324c271cc335f8ad3218bb22 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Mon, 8 May 2023 09:49:10 +0100 Subject: [PATCH 11/74] Fixed issue updating cache when receiving metadata via the network. --- .../controller/arbitrary/ArbitraryMetadataManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index f99ec953..02cf12c9 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -321,7 +321,7 @@ public class ArbitraryMetadataManager { return; } - // Update requests map to reflect that we've received all chunks + // Update requests map to reflect that we've received this metadata Triple newEntry = new Triple<>(null, null, request.getC()); arbitraryMetadataRequests.put(message.getId(), newEntry); @@ -356,6 +356,7 @@ public class ArbitraryMetadataManager { // Update arbitrary resource caches if (arbitraryTransactionData != null) { + repository.discardChanges(); ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, arbitraryTransactionData); arbitraryTransaction.updateArbitraryResourceCache(); arbitraryTransaction.updateArbitraryMetadataCache(); @@ -363,7 +364,7 @@ public class ArbitraryMetadataManager { } } catch (DataException e) { - LOGGER.error(String.format("Repository issue while finding arbitrary transaction metadata for peer %s", peer), e); + LOGGER.error(String.format("Repository issue while saving arbitrary transaction metadata from peer %s", peer), e); } } From 0ec661431c40221b0aaa3baf6837a3e86087fb7a Mon Sep 17 00:00:00 2001 From: CalDescent Date: Mon, 8 May 2023 12:46:15 +0100 Subject: [PATCH 12/74] Added optional "before" and "after" params to `GET /arbitrary/resources/search` --- Q-Apps.md | 2 ++ .../org/qortal/api/resource/ArbitraryResource.java | 7 +++++-- .../org/qortal/repository/ArbitraryRepository.java | 2 +- .../repository/hsqldb/HSQLDBArbitraryRepository.java | 12 +++++++++++- src/main/resources/q-apps/q-apps.js | 2 ++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Q-Apps.md b/Q-Apps.md index 177fee2d..41d5d756 100644 --- a/Q-Apps.md +++ b/Q-Apps.md @@ -367,6 +367,8 @@ let res = await qortalRequest({ nameListFilter: "QApp1234Subscriptions", // Optional - will only return results if they are from a name included in supplied list followedOnly: false, // Optional - include followed names only excludeBlocked: false, // Optional - exclude blocked content + // before: 1683546000000, // Optional - limit to resources created before timestamp + // after: 1683546000000, // Optional - limit to resources created after timestamp limit: 100, offset: 0, reverse: true diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 8762a7f1..b3fd6d6d 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -175,6 +175,8 @@ public class ArbitraryResource { @Parameter(description = "Exclude blocked content") @QueryParam("excludeblocked") Boolean excludeBlocked, @Parameter(description = "Include status") @QueryParam("includestatus") Boolean includeStatus, @Parameter(description = "Include metadata") @QueryParam("includemetadata") Boolean includeMetadata, + @Parameter(description = "Creation date before timestamp") @QueryParam("before") Long before, + @Parameter(description = "Creation date after timestamp") @QueryParam("after") Long after, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse) { @@ -203,8 +205,9 @@ public class ArbitraryResource { } List resources = repository.getArbitraryRepository() - .searchArbitraryResources(service, query, identifier, names, title, description, usePrefixOnly, exactMatchNames, - defaultRes, followedOnly, excludeBlocked, includeMetadata, includeStatus, limit, offset, reverse); + .searchArbitraryResources(service, query, identifier, names, title, description, usePrefixOnly, + exactMatchNames, defaultRes, followedOnly, excludeBlocked, includeMetadata, includeStatus, + before, after, limit, offset, reverse); if (resources == null) { return new ArrayList<>(); diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 590aa3b8..089ca199 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -39,7 +39,7 @@ public interface ArbitraryRepository { public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; // Arbitrary resources cache save/load diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 45706e11..d72d233b 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -640,7 +640,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List exactMatchNames, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, - Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException { + Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); @@ -724,6 +724,16 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { sql.append(")"); } + // Timestamp range + if (before != null) { + sql.append(" AND created_when < ?"); + bindParams.add(before); + } + if (after != null) { + sql.append(" AND created_when > ?"); + bindParams.add(after); + } + // Handle "followed only" if (followedOnly != null && followedOnly) { List followedNames = ListUtils.followedNames(); diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js index 6c72a410..ac0d6603 100644 --- a/src/main/resources/q-apps/q-apps.js +++ b/src/main/resources/q-apps/q-apps.js @@ -228,6 +228,8 @@ window.addEventListener("message", (event) => { if (data.nameListFilter != null) url = url.concat("&namefilter=" + data.nameListFilter); if (data.followedOnly != null) url = url.concat("&followedonly=" + new Boolean(data.followedOnly).toString()); if (data.excludeBlocked != null) url = url.concat("&excludeblocked=" + new Boolean(data.excludeBlocked).toString()); + if (data.before != null) url = url.concat("&before=" + data.before); + if (data.after != null) url = url.concat("&after=" + data.after); if (data.limit != null) url = url.concat("&limit=" + data.limit); if (data.offset != null) url = url.concat("&offset=" + data.offset); if (data.reverse != null) url = url.concat("&reverse=" + new Boolean(data.reverse).toString()); From c210d63c40f2ecc882281004407325558567359d Mon Sep 17 00:00:00 2001 From: CalDescent Date: Mon, 8 May 2023 13:41:23 +0100 Subject: [PATCH 13/74] Added "mode" parameter to `GET /arbitrary/resources/search`, with possible values of LATEST, ALL. By default, only the latest resource is returned for a name/service combination. All identifiers can be optionally returned by setting `mode` to "ALL". More search modes can be added in the future, for instance "RELEVANT" or "POPULAR" (these are just ideas, and are not currently supported). --- Q-Apps.md | 5 ++++ src/main/java/org/qortal/api/SearchMode.java | 6 +++++ .../api/resource/ArbitraryResource.java | 3 ++- .../repository/ArbitraryRepository.java | 3 ++- .../hsqldb/HSQLDBArbitraryRepository.java | 27 ++++++++++++++++--- src/main/resources/q-apps/q-apps.js | 1 + 6 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/qortal/api/SearchMode.java diff --git a/Q-Apps.md b/Q-Apps.md index 41d5d756..74b09791 100644 --- a/Q-Apps.md +++ b/Q-Apps.md @@ -362,6 +362,7 @@ let res = await qortalRequest({ prefix: false, // Optional - if true, only the beginning of fields are matched in all of the above filters exactMatchNames: true, // Optional - if true, partial name matches are excluded default: false, // Optional - if true, only resources without identifiers are returned + mode: "LATEST", // Optional - whether to return all resources or just the latest for a name/service combination. Possible values: ALL,LATEST. Default: LATEST includeStatus: false, // Optional - will take time to respond, so only request if necessary includeMetadata: false, // Optional - will take time to respond, so only request if necessary nameListFilter: "QApp1234Subscriptions", // Optional - will only return results if they are from a name included in supplied list @@ -384,12 +385,16 @@ let res = await qortalRequest({ identifier: "search query goes here", // Optional - searches only the "identifier" field names: ["QortalDemo", "crowetic", "AlphaX"], // Optional - searches only the "name" field for any of the supplied names prefix: false, // Optional - if true, only the beginning of fields are matched in all of the above filters + exactMatchNames: true, // Optional - if true, partial name matches are excluded default: false, // Optional - if true, only resources without identifiers are returned + mode: "LATEST", // Optional - whether to return all resources or just the latest for a name/service combination. Possible values: ALL,LATEST. Default: LATEST includeStatus: false, // Optional - will take time to respond, so only request if necessary includeMetadata: false, // Optional - will take time to respond, so only request if necessary nameListFilter: "QApp1234Subscriptions", // Optional - will only return results if they are from a name included in supplied list followedOnly: false, // Optional - include followed names only excludeBlocked: false, // Optional - exclude blocked content + // before: 1683546000000, // Optional - limit to resources created before timestamp + // after: 1683546000000, // Optional - limit to resources created after timestamp limit: 100, offset: 0, reverse: true diff --git a/src/main/java/org/qortal/api/SearchMode.java b/src/main/java/org/qortal/api/SearchMode.java new file mode 100644 index 00000000..85c1c61a --- /dev/null +++ b/src/main/java/org/qortal/api/SearchMode.java @@ -0,0 +1,6 @@ +package org.qortal.api; + +public enum SearchMode { + LATEST, + ALL; +} diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index b3fd6d6d..295fb7c5 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -170,6 +170,7 @@ public class ArbitraryResource { @Parameter(description = "Prefix only (if true, only the beginning of fields are matched)") @QueryParam("prefix") Boolean prefixOnly, @Parameter(description = "Exact match names only (if true, partial name matches are excluded)") @QueryParam("exactmatchnames") Boolean exactMatchNamesOnly, @Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource, + @Parameter(description = "Search mode") @QueryParam("mode") SearchMode mode, @Parameter(description = "Filter names by list (exact matches only)") @QueryParam("namefilter") String nameListFilter, @Parameter(description = "Include followed names only") @QueryParam("followedonly") Boolean followedOnly, @Parameter(description = "Exclude blocked content") @QueryParam("excludeblocked") Boolean excludeBlocked, @@ -206,7 +207,7 @@ public class ArbitraryResource { List resources = repository.getArbitraryRepository() .searchArbitraryResources(service, query, identifier, names, title, description, usePrefixOnly, - exactMatchNames, defaultRes, followedOnly, excludeBlocked, includeMetadata, includeStatus, + exactMatchNames, defaultRes, mode, followedOnly, excludeBlocked, includeMetadata, includeStatus, before, after, limit, offset, reverse); if (resources == null) { diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 089ca199..e773597d 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -1,5 +1,6 @@ package org.qortal.repository; +import org.qortal.api.SearchMode; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; @@ -39,7 +40,7 @@ public interface ArbitraryRepository { public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, SearchMode mode, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; // Arbitrary resources cache save/load diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index d72d233b..b1e878ac 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -2,6 +2,7 @@ package org.qortal.repository.hsqldb; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.qortal.api.SearchMode; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; @@ -639,16 +640,34 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, - List exactMatchNames, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, + List exactMatchNames, boolean defaultResource, SearchMode mode, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + - "FROM ArbitraryResourcesCache " + - "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + - "WHERE name IS NOT NULL"); + "FROM ArbitraryResourcesCache"); + + // Default to "latest" mode + if (mode == null) { + mode = SearchMode.LATEST; + } + + switch (mode) { + case LATEST: + // Include latest item only for a name/service combination + sql.append(" JOIN (SELECT name, service, MAX(created_when) AS latest " + + "FROM ArbitraryResourcesCache GROUP BY name, service) LatestResources " + + "ON name=LatestResources.name AND service=LatestResources.service " + + "AND created_when=LatestResources.latest"); + break; + + case ALL: + break; + } + + sql.append(" LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) WHERE name IS NOT NULL"); if (service != null) { sql.append(" AND service = "); diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js index ac0d6603..3069c160 100644 --- a/src/main/resources/q-apps/q-apps.js +++ b/src/main/resources/q-apps/q-apps.js @@ -223,6 +223,7 @@ window.addEventListener("message", (event) => { if (data.prefix != null) url = url.concat("&prefix=" + new Boolean(data.prefix).toString()); if (data.exactMatchNames != null) url = url.concat("&exactmatchnames=" + new Boolean(data.exactMatchNames).toString()); if (data.default != null) url = url.concat("&default=" + new Boolean(data.default).toString()); + if (data.mode != null) url = url.concat("&mode=" + data.mode); if (data.includeStatus != null) url = url.concat("&includestatus=" + new Boolean(data.includeStatus).toString()); if (data.includeMetadata != null) url = url.concat("&includemetadata=" + new Boolean(data.includeMetadata).toString()); if (data.nameListFilter != null) url = url.concat("&namefilter=" + data.nameListFilter); From 7725c5e21fe5fdad8175d468883cce00ca033528 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 12 May 2023 12:03:32 +0100 Subject: [PATCH 14/74] Always ignore unsupported services when building the cache. --- .../org/qortal/transaction/ArbitraryTransaction.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index b2954dd9..df4a92f7 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -369,6 +369,11 @@ public class ArbitraryTransaction extends Transaction { String name = arbitraryTransactionData.getName(); String identifier = arbitraryTransactionData.getIdentifier(); + if (service == null) { + // Unsupported service - ignore this resource + return; + } + // In the cache we store null identifiers as "default", as it is part of the primary key if (identifier == null) { identifier = "default"; @@ -427,6 +432,11 @@ public class ArbitraryTransaction extends Transaction { String name = latestTransactionData.getName(); String identifier = latestTransactionData.getIdentifier(); + if (service == null) { + // Unsupported service - ignore this resource + return; + } + // In the cache we store null identifiers as "default", as it is part of the primary key if (identifier == null) { identifier = "default"; From b661d39844a7d776cc7c6ce848a2e84ec9224fdc Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 12 May 2023 19:39:31 +0100 Subject: [PATCH 15/74] Cache updating moved to a dedicated thread. Hopeful fix for serialization failures which occurred when updating from various different network threads. --- .../api/resource/ArbitraryResource.java | 3 +- .../org/qortal/controller/Controller.java | 4 +- .../arbitrary/ArbitraryDataCacheManager.java | 167 ++++++++++++++++++ .../arbitrary/ArbitraryDataManager.java | 6 +- .../arbitrary/ArbitraryMetadataManager.java | 9 +- .../qortal/repository/RepositoryManager.java | 64 ------- .../transaction/ArbitraryTransaction.java | 11 +- 7 files changed, 181 insertions(+), 83 deletions(-) create mode 100644 src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 295fb7c5..7dae7483 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -45,6 +45,7 @@ import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.Controller; +import org.qortal.controller.arbitrary.ArbitraryDataCacheManager; import org.qortal.controller.arbitrary.ArbitraryDataRenderManager; import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; import org.qortal.controller.arbitrary.ArbitraryMetadataManager; @@ -1133,7 +1134,7 @@ public class ArbitraryResource { Security.checkApiCallAllowed(request); try (final Repository repository = RepositoryManager.getRepository()) { - RepositoryManager.buildArbitraryResourcesCache(repository, true); + ArbitraryDataCacheManager.getInstance().buildArbitraryResourcesCache(repository, true); return "true"; } catch (DataException e) { diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index 1de6f776..16373099 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -403,7 +403,7 @@ public class Controller extends Thread { RepositoryManager.setRequestedCheckpoint(Boolean.TRUE); try (final Repository repository = RepositoryManager.getRepository()) { - RepositoryManager.buildArbitraryResourcesCache(repository, false); + ArbitraryDataCacheManager.getInstance().buildArbitraryResourcesCache(repository, false); } } catch (DataException e) { @@ -485,6 +485,7 @@ public class Controller extends Thread { LOGGER.info("Starting arbitrary-transaction controllers"); ArbitraryDataManager.getInstance().start(); ArbitraryDataFileManager.getInstance().start(); + ArbitraryDataCacheManager.getInstance().start(); ArbitraryDataBuildManager.getInstance().start(); ArbitraryDataCleanupManager.getInstance().start(); ArbitraryDataStorageManager.getInstance().start(); @@ -939,6 +940,7 @@ public class Controller extends Thread { LOGGER.info("Shutting down arbitrary-transaction controllers"); ArbitraryDataManager.getInstance().shutdown(); ArbitraryDataFileManager.getInstance().shutdown(); + ArbitraryDataCacheManager.getInstance().shutdown(); ArbitraryDataBuildManager.getInstance().shutdown(); ArbitraryDataCleanupManager.getInstance().shutdown(); ArbitraryDataStorageManager.getInstance().shutdown(); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java new file mode 100644 index 00000000..df2c1f29 --- /dev/null +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -0,0 +1,167 @@ +package org.qortal.controller.arbitrary; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.api.resource.TransactionsResource; +import org.qortal.controller.Controller; +import org.qortal.data.arbitrary.ArbitraryResourceData; +import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.gui.SplashFrame; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; +import org.qortal.settings.Settings; +import org.qortal.transaction.ArbitraryTransaction; +import org.qortal.transaction.Transaction; +import org.qortal.utils.Base58; + +import java.util.*; + +public class ArbitraryDataCacheManager extends Thread { + + private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataCacheManager.class); + + private static ArbitraryDataCacheManager instance; + private volatile boolean isStopping = false; + + /** Queue of arbitrary transactions that require cache updates */ + private final List updateQueue = Collections.synchronizedList(new ArrayList<>()); + + + public static synchronized ArbitraryDataCacheManager getInstance() { + if (instance == null) { + instance = new ArbitraryDataCacheManager(); + } + + return instance; + } + + @Override + public void run() { + Thread.currentThread().setName("Arbitrary Data Cache Manager"); + + try { + while (!Controller.isStopping()) { + Thread.sleep(500L); + + // Process queue + processResourceQueue(); + } + } catch (InterruptedException e) { + // Fall through to exit thread + } + } + + public void shutdown() { + isStopping = true; + this.interrupt(); + } + + + private void processResourceQueue() { + if (this.updateQueue.isEmpty()) { + // Nothing to do + return; + } + + try (final Repository repository = RepositoryManager.getRepository()) { + // Take a snapshot of resourceQueue, so we don't need to lock it while processing + List resourceQueueCopy = List.copyOf(this.updateQueue); + + for (ArbitraryTransactionData transactionData : resourceQueueCopy) { + // Best not to return when controller is stopping, as ideally we need to finish processing + + LOGGER.debug(() -> String.format("Processing transaction %.8s in arbitrary resource queue...", Base58.encode(transactionData.getSignature()))); + + // Remove from the queue regardless of outcome + this.updateQueue.remove(transactionData); + + // Update arbitrary resource caches + try { + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); + arbitraryTransaction.updateArbitraryResourceCache(); + arbitraryTransaction.updateArbitraryMetadataCache(); + repository.saveChanges(); + + LOGGER.debug(() -> String.format("Finished processing transaction %.8s in arbitrary resource queue...", Base58.encode(transactionData.getSignature()))); + + } catch (DataException e) { + repository.discardChanges(); + LOGGER.error("Repository issue while updating arbitrary resource caches", e); + } + } + } catch (DataException e) { + LOGGER.error("Repository issue while processing arbitrary resource cache updates", e); + } + } + + public void addToUpdateQueue(ArbitraryTransactionData transactionData) { + this.updateQueue.add(transactionData); + LOGGER.debug(() -> String.format("Transaction %.8s added to queue", Base58.encode(transactionData.getSignature()))); + } + + public boolean buildArbitraryResourcesCache(Repository repository, boolean forceRebuild) throws DataException { + if (Settings.getInstance().isLite()) { + // Lite nodes have no blockchain + return false; + } + + try { + // Check if QDNResources table is empty + List resources = repository.getArbitraryRepository().getArbitraryResources(10, 0, false); + if (!resources.isEmpty() && !forceRebuild) { + // Resources exist in the cache, so assume complete. + // We avoid checkpointing and prevent the node from starting up in the case of a rebuild failure, so + // we shouldn't ever be left in a partially rebuilt state. + LOGGER.debug("Arbitrary resources cache already built"); + return false; + } + + LOGGER.info("Building arbitrary resources cache..."); + SplashFrame.getInstance().updateStatus("Building QDN cache - please wait..."); + + final int batchSize = 100; + int offset = 0; + + // Loop through all ARBITRARY transactions, and determine latest state + while (!Controller.isStopping()) { + LOGGER.info("Fetching arbitrary transactions {} - {}", offset, offset+batchSize-1); + + List signatures = repository.getTransactionRepository().getSignaturesMatchingCriteria(null, null, null, List.of(Transaction.TransactionType.ARBITRARY), null, null, null, TransactionsResource.ConfirmationStatus.BOTH, batchSize, offset, false); + if (signatures.isEmpty()) { + // Complete + break; + } + + // Expand signatures to transactions + for (byte[] signature : signatures) { + ArbitraryTransactionData transactionData = (ArbitraryTransactionData) repository + .getTransactionRepository().fromSignature(signature); + + if (transactionData.getService() == null) { + // Unsupported service - ignore this resource + continue; + } + + // Update arbitrary resource caches + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); + arbitraryTransaction.updateArbitraryResourceCache(); + arbitraryTransaction.updateArbitraryMetadataCache(); + } + offset += batchSize; + } + + repository.saveChanges(); + LOGGER.info("Completed build of arbitrary resources cache."); + return true; + } + catch (DataException e) { + LOGGER.info("Unable to build arbitrary resources cache: {}. The database may have been left in an inconsistent state.", e.getMessage()); + + // Throw an exception so that the node startup is halted, allowing for a retry next time. + repository.discardChanges(); + throw new DataException("Build of arbitrary resources cache failed."); + } + } + +} diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index 60bf63b3..f70354d6 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -564,10 +564,8 @@ public class ArbitraryDataManager extends Thread { repository.getArbitraryRepository().delete(arbitraryResourceData); } else { - // We found the next oldest transaction, so we can update the cache - ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, latestTransactionData); - arbitraryTransaction.updateArbitraryResourceCache(); - arbitraryTransaction.updateArbitraryMetadataCache(); + // We found the next oldest transaction, so add to queue for processing + ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); } ; repository.saveChanges(); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index 02cf12c9..1fee6753 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -15,7 +15,6 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.settings.Settings; -import org.qortal.transaction.ArbitraryTransaction; import org.qortal.utils.Base58; import org.qortal.utils.ListUtils; import org.qortal.utils.NTP; @@ -354,13 +353,9 @@ public class ArbitraryMetadataManager { } } - // Update arbitrary resource caches + // Add to resource queue to update arbitrary resource caches if (arbitraryTransactionData != null) { - repository.discardChanges(); - ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, arbitraryTransactionData); - arbitraryTransaction.updateArbitraryResourceCache(); - arbitraryTransaction.updateArbitraryMetadataCache(); - repository.saveChanges(); + ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); } } catch (DataException e) { diff --git a/src/main/java/org/qortal/repository/RepositoryManager.java b/src/main/java/org/qortal/repository/RepositoryManager.java index 26eb49e3..fcf9e398 100644 --- a/src/main/java/org/qortal/repository/RepositoryManager.java +++ b/src/main/java/org/qortal/repository/RepositoryManager.java @@ -65,70 +65,6 @@ public abstract class RepositoryManager { } } - public static boolean buildArbitraryResourcesCache(Repository repository, boolean forceRebuild) throws DataException { - if (Settings.getInstance().isLite()) { - // Lite nodes have no blockchain - return false; - } - - try { - // Check if QDNResources table is empty - List resources = repository.getArbitraryRepository().getArbitraryResources(10, 0, false); - if (!resources.isEmpty() && !forceRebuild) { - // Resources exist in the cache, so assume complete. - // We avoid checkpointing and prevent the node from starting up in the case of a rebuild failure, so - // we shouldn't ever be left in a partially rebuilt state. - LOGGER.debug("Arbitrary resources cache already built"); - return false; - } - - LOGGER.info("Building arbitrary resources cache..."); - SplashFrame.getInstance().updateStatus("Building QDN cache - please wait..."); - - final int batchSize = 100; - int offset = 0; - - // Loop through all ARBITRARY transactions, and determine latest state - while (!Controller.isStopping()) { - LOGGER.info("Fetching arbitrary transactions {} - {}", offset, offset+batchSize-1); - - List signatures = repository.getTransactionRepository().getSignaturesMatchingCriteria(null, null, null, List.of(Transaction.TransactionType.ARBITRARY), null, null, null, TransactionsResource.ConfirmationStatus.BOTH, batchSize, offset, false); - if (signatures.isEmpty()) { - // Complete - break; - } - - // Expand signatures to transactions - for (byte[] signature : signatures) { - ArbitraryTransactionData transactionData = (ArbitraryTransactionData) repository - .getTransactionRepository().fromSignature(signature); - - if (transactionData.getService() == null) { - // Unsupported service - ignore this resource - continue; - } - - // Update arbitrary resource caches - ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); - arbitraryTransaction.updateArbitraryResourceCache(); - arbitraryTransaction.updateArbitraryMetadataCache(); - } - offset += batchSize; - } - - repository.saveChanges(); - LOGGER.info("Completed build of arbitrary resources cache."); - return true; - } - catch (DataException e) { - LOGGER.info("Unable to build arbitrary resources cache: {}. The database may have been left in an inconsistent state.", e.getMessage()); - - // Throw an exception so that the node startup is halted, allowing for a retry next time. - repository.discardChanges(); - throw new DataException("Build of arbitrary resources cache failed."); - } - } - public static void setRequestedCheckpoint(Boolean quick) { quickCheckpointRequested = quick; } diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index df4a92f7..d931e231 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -12,6 +12,7 @@ import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.block.BlockChain; +import org.qortal.controller.arbitrary.ArbitraryDataCacheManager; import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; import org.qortal.crypto.Crypto; @@ -258,9 +259,8 @@ public class ArbitraryTransaction extends Transaction { } } - // Add to arbitrary resource caches - this.updateArbitraryResourceCache(); - this.updateArbitraryMetadataCache(); + // Add to queue for cache updates + ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); } @Override @@ -296,9 +296,8 @@ public class ArbitraryTransaction extends Transaction { } } - // Add/update arbitrary resource caches - this.updateArbitraryResourceCache(); - this.updateArbitraryMetadataCache(); + // Add to queue for cache updates + ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); } catch (Exception e) { // Log and ignore all exceptions. The cache is updated from other places too, and can be rebuilt if needed. From 36a731255ad311499fbfb3b2964a4a566639115e Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 12 May 2023 20:08:53 +0100 Subject: [PATCH 16/74] Automatically delete cached resources & metadata if there is no longer a latest transaction. --- .../arbitrary/ArbitraryDataManager.java | 27 ++----------------- .../transaction/ArbitraryTransaction.java | 23 ++++++++-------- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index f70354d6..1e24ae70 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -546,32 +546,9 @@ public class ArbitraryDataManager extends Thread { return; } - Service service = arbitraryTransactionData.getService(); - String name = arbitraryTransactionData.getName(); - String identifier = arbitraryTransactionData.getIdentifier(); + // Add to queue for update/deletion + ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); - ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); - arbitraryResourceData.service = service; - arbitraryResourceData.name = name; - arbitraryResourceData.identifier = identifier; - - try (final Repository repository = RepositoryManager.getRepository()) { - // Find next oldest transaction (which is now the latest transaction) - ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(name, service, null, identifier); - - if (latestTransactionData == null) { - // There are no transactions anymore, so we can delete from the cache entirely (this deletes metadata too) - repository.getArbitraryRepository().delete(arbitraryResourceData); - } - else { - // We found the next oldest transaction, so add to queue for processing - ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); - } -; - repository.saveChanges(); - } catch (DataException e) { - // Not much we can do, so ignore for now - } } public int getPowDifficulty() { diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index d931e231..46b26f6b 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -357,13 +357,6 @@ public class ArbitraryTransaction extends Transaction { return; } - // Get the latest transaction - ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(arbitraryTransactionData.getName(), arbitraryTransactionData.getService(), null, arbitraryTransactionData.getIdentifier()); - if (latestTransactionData == null) { - // We don't have a latest transaction, so give up - return; - } - Service service = arbitraryTransactionData.getService(); String name = arbitraryTransactionData.getName(); String identifier = arbitraryTransactionData.getIdentifier(); @@ -378,15 +371,23 @@ public class ArbitraryTransaction extends Transaction { identifier = "default"; } - // Get existing cached entry if it exists - ArbitraryResourceData existingArbitraryResourceData = repository.getArbitraryRepository() - .getArbitraryResource(service, name, identifier); - ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); arbitraryResourceData.service = service; arbitraryResourceData.name = name; arbitraryResourceData.identifier = identifier; + // Get the latest transaction + ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(arbitraryTransactionData.getName(), arbitraryTransactionData.getService(), null, arbitraryTransactionData.getIdentifier()); + if (latestTransactionData == null) { + // We don't have a latest transaction, so delete from cache + repository.getArbitraryRepository().delete(arbitraryResourceData); + return; + } + + // Get existing cached entry if it exists + ArbitraryResourceData existingArbitraryResourceData = repository.getArbitraryRepository() + .getArbitraryResource(service, name, identifier); + // Check for existing cached data if (existingArbitraryResourceData == null) { // Nothing exists yet, so set everything from the newest transaction From 23d211836fa9d0123f03b5ef26ed039f779dc31f Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 12 May 2023 20:10:51 +0100 Subject: [PATCH 17/74] Fixed case sensitivity issue when updating status in the cache. --- .../qortal/repository/hsqldb/HSQLDBArbitraryRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index b1e878ac..e336d140 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -886,10 +886,10 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { if (status == null) { return; } - String updateSql = "UPDATE ArbitraryResourcesCache SET status = ? WHERE service = ? AND name = ? AND identifier = ?"; + String updateSql = "UPDATE ArbitraryResourcesCache SET status = ? WHERE service = ? AND LCASE(name) = ? AND LCASE(identifier) = ?"; try { - this.repository.executeCheckedUpdate(updateSql, status.value, arbitraryResourceData.service.value, arbitraryResourceData.name, arbitraryResourceData.identifier); + this.repository.executeCheckedUpdate(updateSql, status.value, arbitraryResourceData.service.value, arbitraryResourceData.name.toLowerCase(), arbitraryResourceData.identifier.toLowerCase()); } catch (SQLException e) { throw new DataException("Unable to set status for arbitrary resource", e); } From 5c7d12f25e628e094feb5fcc90652ab702143573 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 13 May 2023 12:27:56 +0100 Subject: [PATCH 18/74] Fixed bug causing incorrect creation dates in the cache. --- .../java/org/qortal/transaction/ArbitraryTransaction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 46b26f6b..ab5adc76 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -390,8 +390,8 @@ public class ArbitraryTransaction extends Transaction { // Check for existing cached data if (existingArbitraryResourceData == null) { - // Nothing exists yet, so set everything from the newest transaction - arbitraryResourceData.created = latestTransactionData.getTimestamp(); + // Nothing exists yet, so set creation date from the current transaction (it will be reduced later if needed) + arbitraryResourceData.created = arbitraryTransactionData.getTimestamp(); arbitraryResourceData.updated = null; } else { From 5ed3237d2f73c4bdfd276a82dd755f3bfb0cd63e Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 13 May 2023 13:36:40 +0100 Subject: [PATCH 19/74] Clear queue before exiting cache manager thread. --- .../qortal/controller/arbitrary/ArbitraryDataCacheManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java index df2c1f29..f12767b9 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -50,6 +50,9 @@ public class ArbitraryDataCacheManager extends Thread { } catch (InterruptedException e) { // Fall through to exit thread } + + // Clear queue before terminating thread + processResourceQueue(); } public void shutdown() { From f451bccbf66315ad027cc50d6a8d6985ae9f7e65 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 13 May 2023 14:54:00 +0100 Subject: [PATCH 20/74] Fixed bug causing descriptions to be truncated in the cache. --- .../org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index e336d140..4be2e7b4 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -922,7 +922,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { // Trim metadata values if they are too long to fit in the db String title = ArbitraryDataTransactionMetadata.limitTitle(metadata.getTitle()); - String description = ArbitraryDataTransactionMetadata.limitTitle(metadata.getDescription()); + String description = ArbitraryDataTransactionMetadata.limitDescription(metadata.getDescription()); List tags = ArbitraryDataTransactionMetadata.limitTags(metadata.getTags()); String tag1 = null; From a49529ad9b52efe5ea6df9834eb143cfd0d0a9c5 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 13 May 2023 15:11:32 +0100 Subject: [PATCH 21/74] Cache updating moved back to existing threads when processing or importing a transaction, to remove chances of queued updates being lost. The dedicated cache manager thread is now used for metadata updates only. If metadata ever goes missing from the db, it would be straightforward to have a background thread that corrects any discrepancies between the filesystem and the db. Not adding that until it is needed. --- .../transaction/ArbitraryTransaction.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index ab5adc76..a189adf2 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -250,17 +250,8 @@ public class ArbitraryTransaction extends Transaction { // We may need to move files from the misc_ folder ArbitraryTransactionUtils.checkAndRelocateMiscFiles(arbitraryTransactionData); - // If the data is local, we need to perform a few actions - if (isDataLocal()) { - - // We have the data for this transaction, so invalidate the cache - if (arbitraryTransactionData.getName() != null) { - ArbitraryDataManager.getInstance().invalidateCache(arbitraryTransactionData); - } - } - - // Add to queue for cache updates - ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); + // Update caches + updateCaches(); } @Override @@ -296,8 +287,9 @@ public class ArbitraryTransaction extends Transaction { } } - // Add to queue for cache updates - ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); + // Add/update arbitrary resource caches + this.updateArbitraryResourceCache(); + this.updateArbitraryMetadataCache(); } catch (Exception e) { // Log and ignore all exceptions. The cache is updated from other places too, and can be rebuilt if needed. From 633f73aa86dd34321f9ea599208264552e11bf05 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 13 May 2023 16:32:33 +0100 Subject: [PATCH 22/74] Removed API key fields from documentation for methods that don't require an API key by default. --- .../api/resource/ArbitraryResource.java | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 7dae7483..b17e810c 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -233,14 +233,12 @@ public class ArbitraryResource { ) } ) - @SecurityRequirement(name = "apiKey") - public ArbitraryResourceStatus getDefaultResourceStatus(@HeaderParam(Security.API_KEY_HEADER) String apiKey, - @PathParam("service") Service service, + public ArbitraryResourceStatus getDefaultResourceStatus(@PathParam("service") Service service, @PathParam("name") String name, @QueryParam("build") Boolean build) { if (!Settings.getInstance().isQDNAuthBypassEnabled()) - Security.requirePriorAuthorizationOrApiKey(request, name, service, null, apiKey); + Security.requirePriorAuthorizationOrApiKey(request, name, service, null, null); return ArbitraryTransactionUtils.getStatus(service, name, null, build, true); } @@ -256,14 +254,12 @@ public class ArbitraryResource { ) } ) - @SecurityRequirement(name = "apiKey") - public FileProperties getResourceProperties(@HeaderParam(Security.API_KEY_HEADER) String apiKey, - @PathParam("service") Service service, - @PathParam("name") String name, - @PathParam("identifier") String identifier) { + public FileProperties getResourceProperties(@PathParam("service") Service service, + @PathParam("name") String name, + @PathParam("identifier") String identifier) { if (!Settings.getInstance().isQDNAuthBypassEnabled()) - Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier, apiKey); + Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier, null); return this.getFileProperties(service, name, identifier); } @@ -279,15 +275,13 @@ public class ArbitraryResource { ) } ) - @SecurityRequirement(name = "apiKey") - public ArbitraryResourceStatus getResourceStatus(@HeaderParam(Security.API_KEY_HEADER) String apiKey, - @PathParam("service") Service service, + public ArbitraryResourceStatus getResourceStatus(@PathParam("service") Service service, @PathParam("name") String name, @PathParam("identifier") String identifier, @QueryParam("build") Boolean build) { if (!Settings.getInstance().isQDNAuthBypassEnabled()) - Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier, apiKey); + Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier, null); return ArbitraryTransactionUtils.getStatus(service, name, identifier, build, true); } @@ -630,9 +624,7 @@ public class ArbitraryResource { ) } ) - @SecurityRequirement(name = "apiKey") - public HttpServletResponse get(@HeaderParam(Security.API_KEY_HEADER) String apiKey, - @PathParam("service") Service service, + public HttpServletResponse get(@PathParam("service") Service service, @PathParam("name") String name, @QueryParam("filepath") String filepath, @QueryParam("encoding") String encoding, @@ -665,9 +657,7 @@ public class ArbitraryResource { ) } ) - @SecurityRequirement(name = "apiKey") - public HttpServletResponse get(@HeaderParam(Security.API_KEY_HEADER) String apiKey, - @PathParam("service") Service service, + public HttpServletResponse get(@PathParam("service") Service service, @PathParam("name") String name, @PathParam("identifier") String identifier, @QueryParam("filepath") String filepath, @@ -678,7 +668,7 @@ public class ArbitraryResource { // Authentication can be bypassed in the settings, for those running public QDN nodes if (!Settings.getInstance().isQDNAuthBypassEnabled()) { - Security.checkApiCallAllowed(request, apiKey); + Security.checkApiCallAllowed(request, null); } return this.download(service, name, identifier, filepath, encoding, rebuild, async, attempts); @@ -703,7 +693,6 @@ public class ArbitraryResource { ) } ) - @SecurityRequirement(name = "apiKey") public ArbitraryResourceMetadata getMetadata(@PathParam("service") Service service, @PathParam("name") String name, @PathParam("identifier") String identifier) { From f5f82dc3f6e60c668fec3ce0ba6622aaec53cdf7 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 13 May 2023 19:20:18 +0100 Subject: [PATCH 23/74] Fixed issues relating to using a separate repository instance when determining the latest status of a resource. --- .../api/gateway/resource/GatewayResource.java | 38 +++------- .../api/resource/ArbitraryResource.java | 10 ++- .../arbitrary/ArbitraryDataResource.java | 75 +++++++++++-------- .../transaction/ArbitraryTransaction.java | 2 +- 4 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java index 7d76be3d..15bb398e 100644 --- a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java +++ b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java @@ -3,6 +3,8 @@ package org.qortal.api.gateway.resource; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.commons.lang3.StringUtils; +import org.qortal.api.ApiError; +import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; @@ -11,6 +13,9 @@ import org.qortal.arbitrary.ArbitraryDataRenderer; import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceStatus; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -31,30 +36,6 @@ public class GatewayResource { @Context HttpServletResponse response; @Context ServletContext context; - /** - * We need to allow resource status checking (and building) via the gateway, as the node's API port - * may not be forwarded and will almost certainly not be authenticated. Since gateways allow for - * all resources to be loaded except those that are blocked, there is no need for authentication. - */ - @GET - @Path("/arbitrary/resource/status/{service}/{name}") - public ArbitraryResourceStatus getDefaultResourceStatus(@PathParam("service") Service service, - @PathParam("name") String name, - @QueryParam("build") Boolean build) { - - return this.getStatus(service, name, null, build); - } - - @GET - @Path("/arbitrary/resource/status/{service}/{name}/{identifier}") - public ArbitraryResourceStatus getResourceStatus(@PathParam("service") Service service, - @PathParam("name") String name, - @PathParam("identifier") String identifier, - @QueryParam("build") Boolean build) { - - return this.getStatus(service, name, identifier, build); - } - private ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build) { // If "build=true" has been specified in the query string, build the resource before returning its status @@ -69,8 +50,13 @@ public class GatewayResource { } } - ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.getStatus(); + try (final Repository repository = RepositoryManager.getRepository()) { + ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); + return resource.getStatus(repository); + + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + } } diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index b17e810c..b7eb6cd4 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -531,8 +531,14 @@ public class ArbitraryResource { @PathParam("identifier") String identifier) { Security.checkApiCallAllowed(request); - ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.delete(false); + + try (final Repository repository = RepositoryManager.getRepository()) { + ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); + return resource.delete(repository, false); + + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + } } @POST diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java index 4aed21fc..96fc4e48 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java @@ -59,28 +59,34 @@ public class ArbitraryDataResource { } public ArbitraryResourceStatus getStatusAndUpdateCache(boolean updateCache) { - ArbitraryResourceStatus arbitraryResourceStatus = this.getStatus(); + ArbitraryResourceStatus arbitraryResourceStatus = null; - if (updateCache) { - // Update cache if possible - ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; - ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); + try (final Repository repository = RepositoryManager.getRepository()) { + arbitraryResourceStatus = this.getStatus(repository); - try (final Repository repository = RepositoryManager.getRepository()) { + if (updateCache) { + // Update cache if possible + ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); repository.saveChanges(); - - } catch (DataException e) { - LOGGER.info("Unable to update status cache for resource {}: {}", arbitraryResourceData, e.getMessage()); } + } catch (DataException e) { + LOGGER.info("Unable to update status cache for resource {}: {}", this.toString(), e.getMessage()); } return arbitraryResourceStatus; } - public ArbitraryResourceStatus getStatus() { + /** + * Get current status of resource + * + * @param repository + * @return the resource's status + */ + public ArbitraryResourceStatus getStatus(Repository repository) { // Calculate the chunk counts - this.calculateChunkCounts(); + this.calculateChunkCounts(repository); if (!this.exists) { return new ArbitraryResourceStatus(Status.NOT_PUBLISHED, this.localChunkCount, this.totalChunkCount); @@ -111,11 +117,11 @@ public class ArbitraryDataResource { } // Check if we have all data locally for this resource - if (!this.allFilesDownloaded()) { - if (this.isDownloading()) { + if (!this.allFilesDownloaded(repository)) { + if (this.isDownloading(repository)) { return new ArbitraryResourceStatus(Status.DOWNLOADING, this.localChunkCount, this.totalChunkCount); } - else if (this.isDataPotentiallyAvailable()) { + else if (this.isDataPotentiallyAvailable(repository)) { return new ArbitraryResourceStatus(Status.PUBLISHED, this.localChunkCount, this.totalChunkCount); } return new ArbitraryResourceStatus(Status.MISSING_DATA, this.localChunkCount, this.totalChunkCount); @@ -157,9 +163,9 @@ public class ArbitraryDataResource { return null; } - public boolean delete(boolean deleteMetadata) { + public boolean delete(Repository repository, boolean deleteMetadata) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -208,7 +214,7 @@ public class ArbitraryDataResource { } } - private boolean allFilesDownloaded() { + private boolean allFilesDownloaded(Repository repository) { // Use chunk counts to speed things up if we can if (this.localChunkCount != null && this.totalChunkCount != null && this.localChunkCount >= this.totalChunkCount) { @@ -216,7 +222,7 @@ public class ArbitraryDataResource { } try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -236,9 +242,14 @@ public class ArbitraryDataResource { } } - private void calculateChunkCounts() { + /** + * Calculate chunk counts of a resource + * + * @param repository optional - a new instance will be created if null + */ + private void calculateChunkCounts(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { this.exists = false; this.localChunkCount = 0; @@ -263,9 +274,9 @@ public class ArbitraryDataResource { } catch (DataException e) {} } - private boolean isRateLimited() { + private boolean isRateLimited(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return true; } @@ -289,9 +300,9 @@ public class ArbitraryDataResource { * This is only used to give an indication to the user of progress * @return - whether data might be available on the network */ - private boolean isDataPotentiallyAvailable() { + private boolean isDataPotentiallyAvailable(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -324,9 +335,9 @@ public class ArbitraryDataResource { * This is only used to give an indication to the user of progress * @return - whether we are trying to download the resource */ - private boolean isDownloading() { + private boolean isDownloading(Repository repository) { try { - this.fetchTransactions(); + this.fetchTransactions(repository); if (this.transactions == null) { return false; } @@ -357,15 +368,19 @@ public class ArbitraryDataResource { } - - private void fetchTransactions() throws DataException { + /** + * Fetch relevant arbitrary transactions for resource + * + * @param repository + * @throws DataException + */ + private void fetchTransactions(Repository repository) throws DataException { if (this.transactions != null && !this.transactions.isEmpty()) { // Already fetched return; } - try (final Repository repository = RepositoryManager.getRepository()) { - + try { // Get the most recent PUT ArbitraryTransactionData latestPut = repository.getArbitraryRepository() .getLatestTransaction(this.resourceId, this.service, ArbitraryTransactionData.Method.PUT, this.identifier); diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index a189adf2..c0d441e0 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -407,7 +407,7 @@ public class ArbitraryTransaction extends Transaction { // Update status ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); - ArbitraryResourceStatus arbitraryResourceStatus = resource.getStatus(); + ArbitraryResourceStatus arbitraryResourceStatus = resource.getStatus(repository); ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); } From 707176a202b88567f5ac294c7bffab90d4359e4c Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 27 May 2023 11:30:19 +0200 Subject: [PATCH 24/74] Improved detection of an existing arbitrary resources cache. --- .../org/qortal/controller/Controller.java | 7 ++ .../arbitrary/ArbitraryDataCacheManager.java | 30 +++++-- .../repository/ArbitraryRepository.java | 2 + .../hsqldb/HSQLDBArbitraryRepository.java | 79 +++++++++++++++++++ 4 files changed, 112 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index b9c3cde9..b6efd26f 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -450,6 +450,13 @@ public class Controller extends Thread { Gui.getInstance().fatalError("Database upgrade needed", "Please restart the core to complete the upgrade process."); return; } + if (ArbitraryDataCacheManager.getInstance().needsArbitraryResourcesCacheRebuild(repository)) { + // Don't allow the node to start if arbitrary resources cache hasn't been built yet + // This is needed to handle a case when bootstrapping + LOGGER.error("Database upgrade needed. Please restart the core to complete the upgrade process."); + Gui.getInstance().fatalError("Database upgrade needed", "Please restart the core to complete the upgrade process."); + return; + } } catch (DataException e) { LOGGER.error("Error checking transaction sequences in repository", e); return; diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java index f12767b9..75b00452 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -103,6 +103,28 @@ public class ArbitraryDataCacheManager extends Thread { LOGGER.debug(() -> String.format("Transaction %.8s added to queue", Base58.encode(transactionData.getSignature()))); } + public boolean needsArbitraryResourcesCacheRebuild(Repository repository) throws DataException { + // Check if we have an entry in the cache for the oldest ARBITRARY transaction with a name + List oldestCacheableTransactions = repository.getArbitraryRepository().getArbitraryTransactions(true, 1, 0, false); + if (oldestCacheableTransactions == null || oldestCacheableTransactions.isEmpty()) { + // No relevant arbitrary transactions yet on this chain + LOGGER.debug("No relevant arbitrary transactions exist to build cache from"); + return false; + } + // We have an arbitrary transaction, so check if it's in the cache + ArbitraryTransactionData txn = oldestCacheableTransactions.get(0); + ArbitraryResourceData cachedResource = repository.getArbitraryRepository().getArbitraryResource(txn.getService(), txn.getName(), txn.getIdentifier()); + if (cachedResource != null) { + // Earliest resource exists in the cache, so assume it has been built. + // We avoid checkpointing and prevent the node from starting up in the case of a rebuild failure, so + // we shouldn't ever be left in a partially rebuilt state. + LOGGER.debug("Arbitrary resources cache already built"); + return false; + } + + return true; + } + public boolean buildArbitraryResourcesCache(Repository repository, boolean forceRebuild) throws DataException { if (Settings.getInstance().isLite()) { // Lite nodes have no blockchain @@ -110,12 +132,8 @@ public class ArbitraryDataCacheManager extends Thread { } try { - // Check if QDNResources table is empty - List resources = repository.getArbitraryRepository().getArbitraryResources(10, 0, false); - if (!resources.isEmpty() && !forceRebuild) { - // Resources exist in the cache, so assume complete. - // We avoid checkpointing and prevent the node from starting up in the case of a rebuild failure, so - // we shouldn't ever be left in a partially rebuilt state. + // Skip if already built + if (!needsArbitraryResourcesCacheRebuild(repository) && !forceRebuild) { LOGGER.debug("Arbitrary resources cache already built"); return false; } diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index e773597d..8cff1231 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -31,6 +31,8 @@ public interface ArbitraryRepository { public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method, String identifier) throws DataException; + public List getArbitraryTransactions(boolean requireName, Integer limit, Integer offset, Boolean reverse) throws DataException; + // Resource related diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 4be2e7b4..a20036de 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -316,6 +316,85 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { return this.getSingleTransaction(name, service, method, identifier, false); } + public List getArbitraryTransactions(boolean requireName, Integer limit, Integer offset, Boolean reverse) throws DataException { + StringBuilder sql = new StringBuilder(512); + sql.append("SELECT type, reference, signature, creator, created_when, fee, " + + "tx_group_id, block_height, approval_status, approval_height, " + + "version, nonce, service, size, is_data_raw, data, metadata_hash, " + + "name, identifier, update_method, secret, compression FROM ArbitraryTransactions " + + "JOIN Transactions USING (signature)"); + + if (requireName) { + sql.append(" WHERE name IS NOT NULL"); + } + + sql.append(" ORDER BY created_when"); + + if (reverse != null && reverse) { + sql.append(" DESC"); + } + + HSQLDBRepository.limitOffsetSql(sql, limit, offset); + + List arbitraryTransactionData = new ArrayList<>(); + + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) { + if (resultSet == null) + return null; + + do { + //TransactionType type = TransactionType.valueOf(resultSet.getInt(1)); + + byte[] reference = resultSet.getBytes(2); + byte[] signature = resultSet.getBytes(3); + byte[] creatorPublicKey = resultSet.getBytes(4); + long timestamp = resultSet.getLong(5); + + Long fee = resultSet.getLong(6); + if (fee == 0 && resultSet.wasNull()) + fee = null; + + int txGroupId = resultSet.getInt(7); + + Integer blockHeight = resultSet.getInt(8); + if (blockHeight == 0 && resultSet.wasNull()) + blockHeight = null; + + ApprovalStatus approvalStatus = ApprovalStatus.valueOf(resultSet.getInt(9)); + Integer approvalHeight = resultSet.getInt(10); + if (approvalHeight == 0 && resultSet.wasNull()) + approvalHeight = null; + + BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, blockHeight, approvalHeight, signature); + + int version = resultSet.getInt(11); + int nonce = resultSet.getInt(12); + int serviceInt = resultSet.getInt(13); + int size = resultSet.getInt(14); + boolean isDataRaw = resultSet.getBoolean(15); // NOT NULL, so no null to false + DataType dataType = isDataRaw ? DataType.RAW_DATA : DataType.DATA_HASH; + byte[] data = resultSet.getBytes(16); + byte[] metadataHash = resultSet.getBytes(17); + String nameResult = resultSet.getString(18); + String identifierResult = resultSet.getString(19); + Method method = Method.valueOf(resultSet.getInt(20)); + byte[] secret = resultSet.getBytes(21); + Compression compression = Compression.valueOf(resultSet.getInt(22)); + // FUTURE: get payments from signature if needed. Avoiding for now to reduce database calls. + + ArbitraryTransactionData transactionData = new ArbitraryTransactionData(baseTransactionData, + version, serviceInt, nonce, size, nameResult, identifierResult, method, secret, + compression, data, dataType, metadataHash, null); + + arbitraryTransactionData.add(transactionData); + } while (resultSet.next()); + + return arbitraryTransactionData; + } catch (SQLException e) { + throw new DataException("Unable to fetch arbitrary transactions from repository", e); + } + } + // Resource related From 7e872f78005cc1bf91b976b9886af6e86fd4ed79 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 16 Jun 2023 14:58:33 +0100 Subject: [PATCH 25/74] Update QDN cache when receiving a metadata file as part of a resource download. --- .../arbitrary/ArbitraryDataFileManager.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java index 48c41496..69a1150a 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java @@ -146,7 +146,7 @@ public class ArbitraryDataFileManager extends Thread { if (!arbitraryDataFileRequests.containsKey(Base58.encode(hash))) { LOGGER.debug("Requesting data file {} from peer {}", hash58, peer); Long startTime = NTP.getTime(); - ArbitraryDataFile receivedArbitraryDataFile = fetchArbitraryDataFile(peer, null, signature, hash, null); + ArbitraryDataFile receivedArbitraryDataFile = fetchArbitraryDataFile(peer, null, arbitraryTransactionData, signature, hash, null); Long endTime = NTP.getTime(); if (receivedArbitraryDataFile != null) { LOGGER.debug("Received data file {} from peer {}. Time taken: {} ms", receivedArbitraryDataFile.getHash58(), peer, (endTime-startTime)); @@ -191,7 +191,7 @@ public class ArbitraryDataFileManager extends Thread { return receivedAtLeastOneFile; } - private ArbitraryDataFile fetchArbitraryDataFile(Peer peer, Peer requestingPeer, byte[] signature, byte[] hash, Message originalMessage) throws DataException { + private ArbitraryDataFile fetchArbitraryDataFile(Peer peer, Peer requestingPeer, ArbitraryTransactionData arbitraryTransactionData, byte[] signature, byte[] hash, Message originalMessage) throws DataException { ArbitraryDataFile existingFile = ArbitraryDataFile.fromHash(hash, signature); boolean fileAlreadyExists = existingFile.exists(); String hash58 = Base58.encode(hash); @@ -250,6 +250,13 @@ public class ArbitraryDataFileManager extends Thread { } } + // If this is a metadata file then we need to update the cache + if (arbitraryTransactionData != null && arbitraryTransactionData.getMetadataHash() != null) { + if (Arrays.equals(arbitraryTransactionData.getMetadataHash(), hash)) { + ArbitraryDataCacheManager.getInstance().addToUpdateQueue(arbitraryTransactionData); + } + } + return arbitraryDataFile; } @@ -585,7 +592,9 @@ public class ArbitraryDataFileManager extends Thread { // Forward the message to this peer LOGGER.debug("Asking peer {} for hash {}", peerToAsk, hash58); - this.fetchArbitraryDataFile(peerToAsk, peer, signature, hash, message); + // No need to pass arbitraryTransactionData below because this is only used for metadata caching, + // and metadata isn't retained when relaying. + this.fetchArbitraryDataFile(peerToAsk, peer, null, signature, hash, message); } else { LOGGER.debug("Peer {} not found in relay info", peer); From 4b04b99401abaff396790e358fb0d8dffd929167 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 16 Jun 2023 14:59:07 +0100 Subject: [PATCH 26/74] Discard changes before setting status. --- src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java index 96fc4e48..aa311786 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java @@ -68,6 +68,7 @@ public class ArbitraryDataResource { // Update cache if possible ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); + repository.discardChanges(); repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); repository.saveChanges(); } From badd6ad2b0dbf97bf963e632469fd120aa39ef4d Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 23 Jun 2023 11:55:49 +0100 Subject: [PATCH 27/74] Added optional minLevel filter to `GET /arbitrary/resources/search` and the `SEARCH_QDN_RESOURCES` action. --- Q-Apps.md | 1 + .../api/resource/ArbitraryResource.java | 3 ++- .../repository/ArbitraryRepository.java | 2 +- .../hsqldb/HSQLDBArbitraryRepository.java | 21 ++++++++++++++----- src/main/resources/q-apps/q-apps.js | 1 + 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Q-Apps.md b/Q-Apps.md index 1b4f33bb..bf44a981 100644 --- a/Q-Apps.md +++ b/Q-Apps.md @@ -376,6 +376,7 @@ let res = await qortalRequest({ exactMatchNames: true, // Optional - if true, partial name matches are excluded default: false, // Optional - if true, only resources without identifiers are returned mode: "LATEST", // Optional - whether to return all resources or just the latest for a name/service combination. Possible values: ALL,LATEST. Default: LATEST + minLevel: 1, // Optional - whether to filter results by minimum account level includeStatus: false, // Optional - will take time to respond, so only request if necessary includeMetadata: false, // Optional - will take time to respond, so only request if necessary nameListFilter: "QApp1234Subscriptions", // Optional - will only return results if they are from a name included in supplied list diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index b7eb6cd4..22a74f42 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -172,6 +172,7 @@ public class ArbitraryResource { @Parameter(description = "Exact match names only (if true, partial name matches are excluded)") @QueryParam("exactmatchnames") Boolean exactMatchNamesOnly, @Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource, @Parameter(description = "Search mode") @QueryParam("mode") SearchMode mode, + @Parameter(description = "Min level") @QueryParam("minlevel") Integer minLevel, @Parameter(description = "Filter names by list (exact matches only)") @QueryParam("namefilter") String nameListFilter, @Parameter(description = "Include followed names only") @QueryParam("followedonly") Boolean followedOnly, @Parameter(description = "Exclude blocked content") @QueryParam("excludeblocked") Boolean excludeBlocked, @@ -208,7 +209,7 @@ public class ArbitraryResource { List resources = repository.getArbitraryRepository() .searchArbitraryResources(service, query, identifier, names, title, description, usePrefixOnly, - exactMatchNames, defaultRes, mode, followedOnly, excludeBlocked, includeMetadata, includeStatus, + exactMatchNames, defaultRes, mode, minLevel, followedOnly, excludeBlocked, includeMetadata, includeStatus, before, after, limit, offset, reverse); if (resources == null) { diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 8cff1231..c586871f 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -42,7 +42,7 @@ public interface ArbitraryRepository { public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, SearchMode mode, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, SearchMode mode, Integer minLevel, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; // Arbitrary resources cache save/load diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index a20036de..85c60b4c 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -580,8 +580,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { "WHERE name IS NOT NULL"); if (service != null) { - sql.append(" AND service = "); - sql.append(service.value); + sql.append(" AND service = ?"); + bindParams.add(service.value); } if (defaultResource) { @@ -719,7 +719,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, - List exactMatchNames, boolean defaultResource, SearchMode mode, Boolean followedOnly, Boolean excludeBlocked, + List exactMatchNames, boolean defaultResource, SearchMode mode, Integer minLevel, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); @@ -746,11 +746,22 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { break; } + if (minLevel != null) { + // Join tables necessary for level filter + sql.append(" JOIN Names USING (name) JOIN Accounts ON Accounts.account=Names.owner"); + } + sql.append(" LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) WHERE name IS NOT NULL"); + if (minLevel != null) { + // Add level filter + sql.append(" AND Accounts.level >= ?"); + bindParams.add(minLevel); + } + if (service != null) { - sql.append(" AND service = "); - sql.append(service.value); + sql.append(" AND service = ?"); + bindParams.add(service.value); } // Handle general query matches diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js index 6cc1bf08..885a9ba6 100644 --- a/src/main/resources/q-apps/q-apps.js +++ b/src/main/resources/q-apps/q-apps.js @@ -233,6 +233,7 @@ window.addEventListener("message", (event) => { if (data.exactMatchNames != null) url = url.concat("&exactmatchnames=" + new Boolean(data.exactMatchNames).toString()); if (data.default != null) url = url.concat("&default=" + new Boolean(data.default).toString()); if (data.mode != null) url = url.concat("&mode=" + data.mode); + if (data.minLevel != null) url = url.concat("&minlevel=" + data.minLevel); if (data.includeStatus != null) url = url.concat("&includestatus=" + new Boolean(data.includeStatus).toString()); if (data.includeMetadata != null) url = url.concat("&includemetadata=" + new Boolean(data.includeMetadata).toString()); if (data.nameListFilter != null) url = url.concat("&namefilter=" + data.nameListFilter); From c0eeef546ab18b6d3ca2356c641087f6742881c3 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 23 Jun 2023 13:30:10 +0100 Subject: [PATCH 28/74] Added support for group encryption in service validation. --- .../org/qortal/arbitrary/misc/Service.java | 5 +++-- .../test/arbitrary/ArbitraryServiceTests.java | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/arbitrary/misc/Service.java b/src/main/java/org/qortal/arbitrary/misc/Service.java index 94ca9252..2b8f8d02 100644 --- a/src/main/java/org/qortal/arbitrary/misc/Service.java +++ b/src/main/java/org/qortal/arbitrary/misc/Service.java @@ -186,6 +186,7 @@ public enum Service { private static final ObjectMapper objectMapper = new ObjectMapper(); private static final String encryptedDataPrefix = "qortalEncryptedData"; + private static final String encryptedGroupDataPrefix = "qortalGroupEncryptedData"; Service(int value, boolean requiresValidation, Long maxSize, boolean single, boolean isPrivate, List requiredKeys) { this.value = value; @@ -221,10 +222,10 @@ public enum Service { // Validate private data for single file resources if (this.single) { String dataString = new String(data, StandardCharsets.UTF_8); - if (this.isPrivate && !dataString.startsWith(encryptedDataPrefix)) { + if (this.isPrivate && !dataString.startsWith(encryptedDataPrefix) && !dataString.startsWith(encryptedGroupDataPrefix)) { return ValidationResult.DATA_NOT_ENCRYPTED; } - if (!this.isPrivate && dataString.startsWith(encryptedDataPrefix)) { + if (!this.isPrivate && (dataString.startsWith(encryptedDataPrefix) || dataString.startsWith(encryptedGroupDataPrefix))) { return ValidationResult.DATA_ENCRYPTED; } } diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java index 33632b4a..b4c10fac 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java @@ -456,6 +456,25 @@ public class ArbitraryServiceTests extends Common { assertEquals(ValidationResult.OK, service.validate(filePath)); } + @Test + public void testValidPrivateGroupData() throws IOException { + String dataString = "qortalGroupEncryptedDatabMx4fELNTV+ifJxmv4+GcuOIJOTo+3qAvbWKNY2L1rfla5UBoEcoxbtjgZ9G7FLPb8V/Qfr0bfKWfvMmN06U/pgUdLuv2mGL2V0D3qYd1011MUzGdNG1qERjaCDz8GAi63+KnHHjfMtPgYt6bcqjs4CNV+ZZ4dIt3xxHYyVEBNc="; + + // Write the data a single file in a temp path + Path path = Files.createTempDirectory("testValidPrivateData"); + Path filePath = Paths.get(path.toString(), "test"); + filePath.toFile().deleteOnExit(); + + BufferedWriter writer = new BufferedWriter(new FileWriter(filePath.toFile())); + writer.write(dataString); + writer.close(); + + Service service = Service.FILE_PRIVATE; + assertTrue(service.isValidationRequired()); + + assertEquals(ValidationResult.OK, service.validate(filePath)); + } + @Test public void testEncryptedData() throws IOException { String dataString = "qortalEncryptedDatabMx4fELNTV+ifJxmv4+GcuOIJOTo+3qAvbWKNY2L1rfla5UBoEcoxbtjgZ9G7FLPb8V/Qfr0bfKWfvMmN06U/pgUdLuv2mGL2V0D3qYd1011MUzGdNG1qERjaCDz8GAi63+KnHHjfMtPgYt6bcqjs4CNV+ZZ4dIt3xxHYyVEBNc="; From 537779b1529cb761904be9e8cb3c6dd63d7ef14d Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 2 Jul 2023 17:49:49 +0100 Subject: [PATCH 29/74] Use a separate repository instance when updating caches. --- .../arbitrary/ArbitraryDataCacheManager.java | 8 ++++---- .../qortal/transaction/ArbitraryTransaction.java | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java index 75b00452..f49fbad2 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -82,8 +82,8 @@ public class ArbitraryDataCacheManager extends Thread { // Update arbitrary resource caches try { ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); - arbitraryTransaction.updateArbitraryResourceCache(); - arbitraryTransaction.updateArbitraryMetadataCache(); + arbitraryTransaction.updateArbitraryResourceCache(repository); + arbitraryTransaction.updateArbitraryMetadataCache(repository); repository.saveChanges(); LOGGER.debug(() -> String.format("Finished processing transaction %.8s in arbitrary resource queue...", Base58.encode(transactionData.getSignature()))); @@ -166,8 +166,8 @@ public class ArbitraryDataCacheManager extends Thread { // Update arbitrary resource caches ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); - arbitraryTransaction.updateArbitraryResourceCache(); - arbitraryTransaction.updateArbitraryMetadataCache(); + arbitraryTransaction.updateArbitraryResourceCache(repository); + arbitraryTransaction.updateArbitraryMetadataCache(repository); } offset += batchSize; } diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index c0d441e0..851bd7ef 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -28,6 +28,7 @@ import org.qortal.payment.Payment; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.arbitrary.ArbitraryDataFile; +import org.qortal.repository.RepositoryManager; import org.qortal.transform.TransformationException; import org.qortal.transform.Transformer; import org.qortal.transform.transaction.ArbitraryTransactionTransformer; @@ -277,7 +278,8 @@ public class ArbitraryTransaction extends Transaction { } private void updateCaches() { - try { + // Very important to use a separate repository instance from the one being used for validation/processing + try (final Repository repository = RepositoryManager.getRepository()) { // If the data is local, we need to perform a few actions if (isDataLocal()) { @@ -288,8 +290,10 @@ public class ArbitraryTransaction extends Transaction { } // Add/update arbitrary resource caches - this.updateArbitraryResourceCache(); - this.updateArbitraryMetadataCache(); + this.updateArbitraryResourceCache(repository); + this.updateArbitraryMetadataCache(repository); + + repository.saveChanges(); } catch (Exception e) { // Log and ignore all exceptions. The cache is updated from other places too, and can be rebuilt if needed. @@ -343,7 +347,7 @@ public class ArbitraryTransaction extends Transaction { * * @throws DataException */ - public void updateArbitraryResourceCache() throws DataException { + public void updateArbitraryResourceCache(Repository repository) throws DataException { // Don't cache resources without a name (such as auto updates) if (arbitraryTransactionData.getName() == null) { return; @@ -412,7 +416,7 @@ public class ArbitraryTransaction extends Transaction { repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); } - public void updateArbitraryMetadataCache() throws DataException { + public void updateArbitraryMetadataCache(Repository repository) throws DataException { // Get the latest transaction ArbitraryTransactionData latestTransactionData = repository.getArbitraryRepository().getLatestTransaction(arbitraryTransactionData.getName(), arbitraryTransactionData.getService(), null, arbitraryTransactionData.getIdentifier()); if (latestTransactionData == null) { From d8237abde5066c6827108e5030982f4b264e8eb3 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 8 Jul 2023 14:16:50 +0100 Subject: [PATCH 30/74] Don't update statuses when processing arbitrary transactions, to improve success rate and speed it up. --- .../arbitrary/ArbitraryDataCacheManager.java | 10 ++++++- .../transaction/ArbitraryTransaction.java | 30 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java index f49fbad2..07ae7d67 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -86,6 +86,10 @@ public class ArbitraryDataCacheManager extends Thread { arbitraryTransaction.updateArbitraryMetadataCache(repository); repository.saveChanges(); + // Update status as separate commit, as this is more prone to failure + arbitraryTransaction.updateArbitraryResourceStatus(repository); + repository.saveChanges(); + LOGGER.debug(() -> String.format("Finished processing transaction %.8s in arbitrary resource queue...", Base58.encode(transactionData.getSignature()))); } catch (DataException e) { @@ -168,11 +172,15 @@ public class ArbitraryDataCacheManager extends Thread { ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); arbitraryTransaction.updateArbitraryResourceCache(repository); arbitraryTransaction.updateArbitraryMetadataCache(repository); + repository.saveChanges(); + + // Update status as separate commit, as this is more prone to failure + arbitraryTransaction.updateArbitraryResourceStatus(repository); + repository.saveChanges(); } offset += batchSize; } - repository.saveChanges(); LOGGER.info("Completed build of arbitrary resources cache."); return true; } diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 851bd7ef..de1dfaad 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -289,7 +289,9 @@ public class ArbitraryTransaction extends Transaction { } } - // Add/update arbitrary resource caches + // Add/update arbitrary resource caches, but don't update the status as this involves time-consuming + // disk reads, and is more prone to failure. The status will be updated on metadata retrieval, or when + // accessing the resource. this.updateArbitraryResourceCache(repository); this.updateArbitraryMetadataCache(repository); @@ -408,6 +410,32 @@ public class ArbitraryTransaction extends Transaction { // Save repository.getArbitraryRepository().save(arbitraryResourceData); + } + + public void updateArbitraryResourceStatus(Repository repository) throws DataException { + // Don't cache resources without a name (such as auto updates) + if (arbitraryTransactionData.getName() == null) { + return; + } + + Service service = arbitraryTransactionData.getService(); + String name = arbitraryTransactionData.getName(); + String identifier = arbitraryTransactionData.getIdentifier(); + + if (service == null) { + // Unsupported service - ignore this resource + return; + } + + // In the cache we store null identifiers as "default", as it is part of the primary key + if (identifier == null) { + identifier = "default"; + } + + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(); + arbitraryResourceData.service = service; + arbitraryResourceData.name = name; + arbitraryResourceData.identifier = identifier; // Update status ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); From 9694094bbf2acae5f1ef5ccb5c5b28f80db085ff Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 8 Jul 2023 14:27:24 +0100 Subject: [PATCH 31/74] Sanitize inputs used for the working path when building arbitrary data, and throw/handle an exception if it still doesn't work. Should fix issue on Windows systems due to reserved characters in certain resource names. --- .../api/gateway/resource/GatewayResource.java | 2 +- .../org/qortal/api/resource/ArbitraryResource.java | 4 ++-- .../org/qortal/arbitrary/ArbitraryDataReader.java | 11 ++++++++--- .../org/qortal/arbitrary/ArbitraryDataRenderer.java | 6 ++++-- .../org/qortal/arbitrary/ArbitraryDataResource.java | 13 +++++++++---- .../arbitrary/ArbitraryDataTransactionBuilder.java | 3 ++- .../org/qortal/utils/ArbitraryTransactionUtils.java | 2 +- src/main/java/org/qortal/utils/StringUtils.java | 13 +++++++++++++ 8 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/qortal/utils/StringUtils.java diff --git a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java index d82fb98d..bf4e1ea6 100644 --- a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java +++ b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java @@ -40,8 +40,8 @@ public class GatewayResource { // If "build=true" has been specified in the query string, build the resource before returning its status if (build != null && build == true) { - ArbitraryDataReader reader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, null); try { + ArbitraryDataReader reader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, null); if (!reader.isBuilding()) { reader.loadSynchronously(false); } diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 22a74f42..9be74a2f 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -1287,8 +1287,8 @@ public class ArbitraryResource { private HttpServletResponse download(Service service, String name, String identifier, String filepath, String encoding, boolean rebuild, boolean async, Integer maxAttempts) { - ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); try { + ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); int attempts = 0; if (maxAttempts == null) { @@ -1394,8 +1394,8 @@ public class ArbitraryResource { } private FileProperties getFileProperties(Service service, String name, String identifier) { - ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); try { + ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); arbitraryDataReader.loadSynchronously(false); java.nio.file.Path outputPath = arbitraryDataReader.getFilePath(); if (outputPath == null) { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java index f281cec5..8896f44f 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java @@ -66,7 +66,7 @@ public class ArbitraryDataReader { // TODO: all builds could be handled by the build queue (even synchronous ones), to avoid the need for this private static Map inProgress = Collections.synchronizedMap(new HashMap<>()); - public ArbitraryDataReader(String resourceId, ResourceIdType resourceIdType, Service service, String identifier) { + public ArbitraryDataReader(String resourceId, ResourceIdType resourceIdType, Service service, String identifier) throws DataException { // Ensure names are always lowercase if (resourceIdType == ResourceIdType.NAME) { resourceId = resourceId.toLowerCase(); @@ -90,11 +90,16 @@ public class ArbitraryDataReader { this.canRequestMissingFiles = true; } - private Path buildWorkingPath() { + private Path buildWorkingPath() throws DataException { // Use the user-specified temp dir, as it is deterministic, and is more likely to be located on reusable storage hardware String baseDir = Settings.getInstance().getTempDataPath(); String identifier = this.identifier != null ? this.identifier : "default"; - return Paths.get(baseDir, "reader", this.resourceIdType.toString(), this.resourceId, this.service.toString(), identifier); + + try { + return Paths.get(baseDir, "reader", this.resourceIdType.toString(), StringUtils.sanitizeString(this.resourceId), this.service.toString(), StringUtils.sanitizeString(identifier)); + } catch (InvalidPathException e) { + throw new DataException(String.format("Invalid path: %s", e.getMessage())); + } } public boolean isCachedDataAvailable() { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java index 704533c8..0936b3ec 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java @@ -76,9 +76,11 @@ public class ArbitraryDataRenderer { return ArbitraryDataRenderer.getResponse(response, 500, "QDN is disabled in settings"); } - ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(resourceId, resourceIdType, service, identifier); - arbitraryDataReader.setSecret58(secret58); // Optional, used for loading encrypted file hashes only + ArbitraryDataReader arbitraryDataReader; try { + arbitraryDataReader = new ArbitraryDataReader(resourceId, resourceIdType, service, identifier); + arbitraryDataReader.setSecret58(secret58); // Optional, used for loading encrypted file hashes only + if (!arbitraryDataReader.isCachedDataAvailable()) { // If async is requested, show a loading screen whilst build is in progress if (async) { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java index aa311786..16faf838 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java @@ -111,10 +111,15 @@ public class ArbitraryDataResource { } // Firstly check the cache to see if it's already built - ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader( - resourceId, resourceIdType, service, identifier); - if (arbitraryDataReader.isCachedDataAvailable()) { - return new ArbitraryResourceStatus(Status.READY, this.localChunkCount, this.totalChunkCount); + try { + ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader( + resourceId, resourceIdType, service, identifier); + if (arbitraryDataReader.isCachedDataAvailable()) { + return new ArbitraryResourceStatus(Status.READY, this.localChunkCount, this.totalChunkCount); + } + } catch (DataException e) { + // Assume no usable data + return new ArbitraryResourceStatus(Status.PUBLISHED, this.localChunkCount, this.totalChunkCount); } // Check if we have all data locally for this resource diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java index a9dd4fcf..c32734dc 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java @@ -117,8 +117,9 @@ public class ArbitraryDataTransactionBuilder { } private Method determineMethodAutomatically() throws DataException { - ArbitraryDataReader reader = new ArbitraryDataReader(this.name, ResourceIdType.NAME, this.service, this.identifier); + ArbitraryDataReader reader; try { + reader = new ArbitraryDataReader(this.name, ResourceIdType.NAME, this.service, this.identifier); reader.loadSynchronously(true); } catch (Exception e) { // Catch all exceptions if the existing resource cannot be loaded first time diff --git a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java index bf7e2aa6..65f3436c 100644 --- a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java +++ b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java @@ -397,8 +397,8 @@ public class ArbitraryTransactionUtils { // If "build" has been specified, build the resource before returning its status if (build != null && build == true) { - ArbitraryDataReader reader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); try { + ArbitraryDataReader reader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); if (!reader.isBuilding()) { reader.loadSynchronously(false); } diff --git a/src/main/java/org/qortal/utils/StringUtils.java b/src/main/java/org/qortal/utils/StringUtils.java new file mode 100644 index 00000000..b3ffcfa6 --- /dev/null +++ b/src/main/java/org/qortal/utils/StringUtils.java @@ -0,0 +1,13 @@ +package org.qortal.utils; + +public class StringUtils { + + public static String sanitizeString(String input) { + String sanitized = input + .replaceAll("[<>:\"/\\\\|?*]", "") // Remove invalid characters + .replaceAll("^\\s+|\\s+$", "") // Trim leading and trailing whitespace + .replaceAll("\\s+", "_"); // Replace consecutive whitespace with underscores + + return sanitized; + } +} From eecd37d6bcb73a56db3342976156bb9a15666372 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 5 Aug 2023 13:10:03 +0100 Subject: [PATCH 32/74] Speed up finding arbitrary transactions. --- .../org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index cac02a9e..c73c80ac 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -1040,6 +1040,11 @@ public class HSQLDBDatabaseUpdates { + "REFERENCES ArbitraryResourcesCache (service, name, identifier) ON DELETE CASCADE)"); // For finding metadata by title. stmt.execute("CREATE INDEX ArbitraryMetadataTitleIndex ON ArbitraryMetadataCache (title)"); + + // For finding arbitrary transactions by service + stmt.execute("CREATE INDEX ArbitraryServiceIndex ON ArbitraryTransactions (service)"); + // For finding arbitrary transactions by identifier + stmt.execute("CREATE INDEX ArbitraryIdentifierIndex ON ArbitraryTransactions (identifier)"); break; default: From e44b38819e9b6989c225c91b4c10dfb4c80a6a9c Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 5 Aug 2023 13:17:30 +0100 Subject: [PATCH 33/74] Specify table name in query, to avoid potential ambiguity with indexes. --- .../org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 85c60b4c..66829d92 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -412,7 +412,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + - "WHERE service = ? AND name = ?"); + "WHERE ArbitraryResourcesCache.service = ? AND ArbitraryResourcesCache.name = ?"); bindParams.add(service.value); bindParams.add(name); From 133848ef50b7f2addff217d52bbbfb9fe669d9ba Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 5 Aug 2023 19:42:30 +0100 Subject: [PATCH 34/74] Speed up status rebuilding by excluding transactions that aren't hosted locally by the node. --- .../arbitrary/ArbitraryDataCacheManager.java | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java index 07ae7d67..0c56769f 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -173,14 +173,13 @@ public class ArbitraryDataCacheManager extends Thread { arbitraryTransaction.updateArbitraryResourceCache(repository); arbitraryTransaction.updateArbitraryMetadataCache(repository); repository.saveChanges(); - - // Update status as separate commit, as this is more prone to failure - arbitraryTransaction.updateArbitraryResourceStatus(repository); - repository.saveChanges(); } offset += batchSize; } + // Now refresh all statuses + refreshArbitraryStatuses(repository); + LOGGER.info("Completed build of arbitrary resources cache."); return true; } @@ -193,4 +192,45 @@ public class ArbitraryDataCacheManager extends Thread { } } + private boolean refreshArbitraryStatuses(Repository repository) throws DataException { + try { + LOGGER.info("Refreshing arbitrary resource statuses for locally hosted transactions..."); + SplashFrame.getInstance().updateStatus("Refreshing statuses - please wait..."); + + final int batchSize = 100; + int offset = 0; + + // Loop through all ARBITRARY transactions, and determine latest state + while (!Controller.isStopping()) { + LOGGER.info("Fetching hosted transactions {} - {}", offset, offset+batchSize-1); + + List hostedTransactions = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, batchSize, offset); + if (hostedTransactions.isEmpty()) { + // Complete + break; + } + + // Loop through hosted transactions + for (ArbitraryTransactionData transactionData : hostedTransactions) { + + // Determine status and update cache + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); + arbitraryTransaction.updateArbitraryResourceStatus(repository); + repository.saveChanges(); + } + offset += batchSize; + } + + LOGGER.info("Completed refresh of arbitrary resource statuses."); + return true; + } + catch (DataException e) { + LOGGER.info("Unable to refresh arbitrary resource statuses: {}. The database may have been left in an inconsistent state.", e.getMessage()); + + // Throw an exception so that the node startup is halted, allowing for a retry next time. + repository.discardChanges(); + throw new DataException("Refresh of arbitrary resource statuses failed."); + } + } + } From 053d56d01d567280172393bce63a6270323831d6 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:40:01 +0200 Subject: [PATCH 35/74] Update hsqldb to 2.7.2 , ciyam at to 1.4.1 --- lib/org/ciyam/AT/1.4.1/AT-1.4.1.jar | Bin 0 -> 161850 bytes lib/org/ciyam/AT/1.4.1/AT-1.4.1.pom | 124 ++++++++++++++++++ lib/org/ciyam/AT/maven-metadata-local.xml | 5 +- pom.xml | 24 ++-- .../hsqldb/HSQLDBDatabaseUpdates.java | 20 +-- 5 files changed, 149 insertions(+), 24 deletions(-) create mode 100644 lib/org/ciyam/AT/1.4.1/AT-1.4.1.jar create mode 100644 lib/org/ciyam/AT/1.4.1/AT-1.4.1.pom diff --git a/lib/org/ciyam/AT/1.4.1/AT-1.4.1.jar b/lib/org/ciyam/AT/1.4.1/AT-1.4.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..05c548c8b59e0ca4254cb43fe5f809fe80a0c83e GIT binary patch literal 161850 zcma&O1yo#Zwk=8^I0SchcXxMphZOGak_0Q9;O_1a+}&M+yA}=!ZkP1meeUi5ywm5^ zpla*^U$H-S%_VcrwNaLX_=pY$1_J}8pN6glr?=j%32l1$r5U8Mm@})k_6>xe2vP zS$b8NVH$<0aW&?jY~ZC%v=iepGdHp$KM@(F6`-uy_x5-8!NHW@cL4Xk1F(PW;Qgfk z^?-dp`mY`Q-(`C58~v{}?*|{>pAOCzO#kzW_h0{y6(&|*0K5ON4)NdC0bKu|rGKu@ z`%nMtf%Ja#Uwg9yxSQGkhs8MmeewH-8UMbWzn=sDKfO&v{U0a%>$CfFNq!AopLKzQ zfq6oLff2vI^Uo#u>kRLIh?1k2gQ=M^z!_ji&c$eA3vh8sR5wsU6G0c4OS0Faou{S7 zkSLIr^WUNRjN%`@QlK11J9E!&TYMIGW?z?ydQV5$c@O_vA}nms;%mayWI!PU#j!mr zk;l2f-6W64-C=e0<_G%E0zqHMpID;QVZMxiWG)9Nis_ymaIC>@GoD*DS8sm^{JLC& z(2}=JB1UYpcnqY$2RcsH2E}uD<&)qd$b~%m|CX@B%eP_O2V%WKIT2sta4> zv5s}x$QxVwY_5d3Q};dvDlOwc{Q^=nrZpIBx9_!4>g0Lp9Ugr0KxhzRc{E+f3CceV zWHK#L?a%=A3nlbSYhkKZvsPs2_p_eiE23Xp^tlqMxGYTSnTC;6kyD2%dUbi0>HPC22 zTf)dAw&7wZjjO}QP_9ppX3W9~Ka|E(ae<3KU#W4OvscbjASrhblU+kad9TQ2oZ@yNLv&Ut^WPybNV4N{YzpJZa7|NQvL#8c zIkcKZQvuvFBxkS!Wu=I6=lEkM3MDDh9uU)qx{aB*$sJw8O%~~SQfQTvVlO1~yTMYh z@Us!_W0y1VAB)uT>x{YuXI28KqrO~&ZET}P^_h|p=?}(4pb(E?h?1Hyi(0^ecqRmLP97f?K^#=L6tKfi~w}$ocixTfCKirY$17*bhWlk7>&4ru4_Z{KPi# z9FC!%vvVcDDfej!NtQA%#Pm9~>5LF|oA@)z(k)%29mRFGdkb%5Lx z!2{MDG;Kf7F8)x-=r9 zmo6-swpnzhKA3m%)NOvv@`JdYIeA?3#E?9yRN2XJ`?0#sJV+J>kMPQPw zdkt;JS1kt1;#Hy$bvG_!s2tYzw%gX^W*gBE*#)t+PlBQ>{I(S|@olLMc1V z@sf7uDD2>LoMaIe8-th@35-zAWiJ#A6Rdi%xYb>)AH2kB}6Q5Vo9XT zSi*K+SzkBO)-$w2`0n~hm<7V_NABB`2(=>O2_cO~vJV3eZaM~9N(;Ap0|sj3$5K2p z`qIWO^B>BskmnCOCePw1o=pWRGIbTAy!PiB{%l=WXt3O8ks*%BDlmtoWu9E^-9H&ih@BP=X{H z??VJI{mAw+tSicsk86GiE5-@t@@TQrR0c}WG82r!r8OK}CMn_LQh#N(%Sm&vp+>r* zU$er@i|Z#e)|lz}EOzg&qT1SCl0y&0o2`O~DNpJY;W&fR-S~slnY_|h+Q>rDVPG0) zDF`tz3m<7fFeyLca%gq<2f*S)gj~ty&(O~S$5{U!2Vqc?Kk?qNg>;Fk^%@ADJg$q$LWeHY!?E$8$MMv9Yj`;RJ$thg!ZT$W zoMp{|I#ruR1#_7H%2!DUBZZE`Xw(GsyKvJ@m-qLxeZ!0;epNkWq^@JZ$7_Wtt*5J; z{9cGLPIK*MQtr^J&h)eZ6KV}^XLYZxkz_2X#}Aw!gQ1&^VSloQI<%*%Tk!1E z)9SMC40e?bYJ+M-AH3Dc88%1(H)vXjJeaB4 z6kQnox#jNsg3YBfk8qn%GxL5;MB=V^KC*WKWd0+57$AdL2LP%Lnhhplj&Tn_+hR#r zBFA&aY0mA9i=l=+iBA9^n^pa4aaZE(uO4zV;KIp?(}+!IUri?VMk++(ZRHZl*tf;2FDbbFL%AEB64fTHV(wI9oLHeTN@r&a z7NTrBqa*1h0KM;HU{B1efOXOe@dgRQ1{swgF_WONq%SUxUH11zC&WcBj@kpqK22DP`3(my`xQ!D_J4zeCHFyk14{9a`t_(8BvWwEpTZ z$l3qOuzqTrN-N6P0$6YuN6!N(CZlUeO;>$7W^%XP#*sh?1X@@;!FyMlMO6p}D<(;! zdzkjyyy z)89l+(8L#L*8239D8jtxBY#K~ClZnYMXed|Cu++!3Bqt?L;XKfrhma}MLA>8QZ8sS<=^bQMb2XRt{}qH^|tz#q*G|bDu*KOs-PuJFZgNhfHpVLc{6PtXp^quHQB{@%%jP=4qTm z1c9(?L6YRMbspi$sE;}k*>ylUqx@!<$VLa0;Emu}T(9;<5Slbf;}x-6D_^5oA(fsd zWlO&JnT^`?o&W0Vr0&Q;OX=8#nfPcD?zG{|DmZe+k=r?{Lf4C@KRWLnoReneGz>LW0#Y`CEsCosS zDP1-TkDEMlkx=eUq?Q)4V(7^#kNs}KsxX&*Py^!cElP>I*(OP8BYmyIf{iD#UiN() zLchE1rYa@TgRGi3pa??nI4%%W9*q7y=qeu@UWLQ|3OP(!Ato*<21m}REUw4oHwntE z7+$VDl_NA-*FTu?|7~$^V)@8#-vi+fza#y7{{6So&cgi9G_1a=h%SOGfY|q`f{gyC zY*4j*C9T?LVFnzuFjj!vi1wr}I{pE-JP7$kI_Rhi4r>7VPEPS+aBFtcOW zYK;fmR0nr;8}XT1(RgBdV754vzxb=foAG^SmS4p9@^f2+*m70p@_C`&%;BnmJsAX= zZYVfwfot(`B<@pg>dB0WW{W53ob>BVx)IevjbSo9YU|nY|C&nj;~bJz5A)~hT2YOt z%)wA;JX6X}oJE;I-5RYLg~UkVFuI2S;ApHRu#qi?dPbPwnW+peF>U{shg3vCe*^*| zMKAMu+)@FlOL~&F)~hfy3o?^;u0xoW9>V9P*DsUdL z4(91dOoAzdNE6Ya0)P4L{6!{FcDKMjkiLbtzYQhsL(2AKf1nZtnJ2SI2loF2e z0ZPMEl+g;~n84FUZA#gs$J4DjaWTx|^;G47bacHI(wdAOc1(VjMF`g1W`jpr@KpCW zzi*T^S#1=+?(&8XYhmIE5|lDc?S7!G{A%2M7`tuSKim+8014m-bZ@6Phfks2Ne z>mhDPjaQAN8eR?NsTv5PD2~SphVC5gK`9g5J?^g`_3~>8G^b%R_k1#jphvICX79xz zUU1~@1Dck?Xz@z-?y6a#7aax4)_M@v$jJ-cb}=);Ta^D-#eD2|21kj|5-%*)Zgi$2>Rm=y38!5+w?$&J?2{IeC}emLk0cmi-S%NvbURbH@8KecaAta|Y2oQsr}cBM zm8uLEExlRsPE|XCpJm@>cSG_GAV83pnP7-K$exLlOS=u%cdmm{Zgm_IrC4CM)~$fH z%Sq`tCf+k>C!dy5>jXW=slQgJ^2X(Wcc)y>5~zcB$6~SLf1BN;(hDxOsfhNR+}LtU zrqK8}J$zs6t=nI#jON1rL`b!|rah}FH1~Fl9i0eihg~QzwJ+P;SkhLD?1b}+yq1p2 z@+^a(D522Y^?Ci#n0gGsyf);Hh|QJHqi(?5<@KxCPpsm~&a(9Mw2foi2PYcjyyFvT zV0@v$d3ZmYQPq*)#LVZDb!ncejWK&`*#M)2QKX_^qpE2n(p~nVeOZc8QqpULT=)iR zRMmAjQHL9@tR3a1TYD$KQ6clHs@u>i>iIyy({OY|OZ(*LPlh1rW7xs86#5{u?^?1s}ys^wl zDq|L}c({@3bIx85~4#!0K@t|A-4hEjWY@(r{YU1KnVoAp>z2Q_E>b3GKYho;7%_G6U!`gWQ7P}(j1nz6?_ zsh5!8&BDVbMy}h^@Y7p!oZrq$`&mbeqv1E&FlHzmm4@LwL5F&q0kc<+B@O>HEjh4c zp6F6Y4ZGQk5vhyarvb5xSp^8l{nZ7>Aa9(IYcUj@A!pzezG%(*I%~%5nkko6F(&7& zk@{ORp3ZQA0V;gT4PLFeC&qHkzRWlf0(efaQCicMaGu?+GL#t6AQDzE%TDVPA#S>p zi;lLips~%?Z*%5Ez*KiuwBye1$c9Zp@+(U(@3zR<>NwWW{U?D8Gh$X~8b-cqCA4di zGaCpvGB^cb641Ee*p9VEI!cV;KqNRWO)Gwic6GC^?luha;I*_X;_H?=E#?RdZ4KuB z6huw=DX;FFFQ{+&5?g9oA{OojYnkQI==?iEr_>xKsmY73pNGha4=h8KoyaCqAI=P# z_vx}rKicTtu`T=$sy!<&h+m3NSz0w4G!CL)Wl6|@D;^Y)4E6LhWw9~GPU2QC;--RV z158IfT9G?=_B(uV_x?WjIHM`RT+5flACdV-pUfEJ`%T0*`|U*4W_MD0U{|byk_wHO zFv`Fpg6>d9Wx~U9L0k&dbH>~fMUuiax^nUjsXu>fy71ls*C96DT>U*>~&dSebv{^TE*8cLf!*U)b zR|=E|QD7$?z3pl?8+n-_u?q&EW4s!kF5%;*3cLkJ{&T z0B%5(y!U?w&r{|8fBHYI8wu4N3Scy=Q;NM#g<9-`o1A*0z_bWjXma~>Q-5S-+LFQ7 zyYMswl>>vZEAX`U{tu&id|HqS{2|mEkb@`X%FoQ~FGHXP<($G9GlZaWHo4$hsEyL; zAL1!aw#oGsf)b9G5RcmUXE#0^R2KCWIwY_&kg_GY@dq>nV&lr?aPwT)i~ZsOYJ_Hx zDEYB_!_iC;t1Bnzymg4-D&JfhZeBZD(h9Z&hYsTtX-*}+JOOimK&gAaT9oZ^1G?Jw zb?qfiT*Fq?nVCCaG{-EA)dc;}5{)m=5YddGE-OI?dnI`<4b?<8Qc1t?f;YF*s(xCG z4C=?66(Nf^7@5GD2X86G>X&bR5$(~jk+E2ppJd{!EJu-soLF~QrUTV1qv{Q3t$zw; zNaBHBu!%omY$IhZZ1&51NBAl=MyY$FV7YqC($BfEF)i7dFHqVsqn+0w>g|gbf_e8@ z67AFxtwIgZhVfgB>VYui%D?tG6hUxC^y?sL=N3h$WMb6f^=j#O5AmdUA|H2zOMgNA zuV&$e+Z`N6$pu4Fb+T&okz8s++&+||M}AZi*o+*HjP_RaEAbtofA9ZbcO|W^-`SG! z2QVB~U4wms8%X~x%{~S%|JS+S|xq{mB zs@`CzmSUNq4X>x`poeJdJ1Q4Q1SPYtef#QQVrb}amG2w;9{4JF+s9nnx>*jiNyVa{ z3~+@;W@^LAFq#PP`_P2bYKg8wb%oef5mi%jeboiH5c$AU8k(@az-R*CYCP3nTUQbYY6O>gQP7 z(v?9pfr(c=IITm2n_Izk($JoI7}m8A_ZESgtSP7C9-+J1;?G#JT`)< zhkBy(Z`o#q?UPHyd$!?wH&_2BKZT9+pJiP2uQFb@?mpJ)D+c+&3ZtP=`T>=lBS=^{ zDdGD^H8d~WMzJ<+_w;odf301l%O0w?;IN*4=-s+Encd974>GiEBj;-_7nv^SsSh`Y zPe@>Lo&eG?ScvcPmY!?=RKsb*fY}0#jqU{hVuY~ds>4w;V2dp%CHq=5(`TW#6G6XP zxBe_Jjz}Fo+GkP;P9M`9&*qE7>D9MvbQd!ygJ6VpibXWOiFh%T_Ja^N(MQ?Nz7sRT zW?Fmy)`}LAKr^2#n4ib|2#~>IXVjDjSP=+UYK9J~WOXu@Vn0-0h8fbZy$4bq(^T7? z%$NG(SmQSdnS8Z<)gTc1QKryu6V!z z?nT4w7ZJ(A6EIsH+jy_W=h1@0LylvoG%$yFLBL~X0cP^_t};j#HXPIP6#@XyP_2Xy za<$dJ$deqexg38&2fQrpiY&ek$NBcb`KXC9xv`yHS=MCd= z335lyTlV7qH_k}=7ylsA2nkaf3bECI(nRK*v(MtI61uAq!&szYsdU!}=f=`u`3ubF zD5WyP(&U!kc)eL46&ZGaD@dW4UlR8w&>@kLhn-szvTFRO`2Bb8 zSHIAIVD=7T=XVhQXT^l`UnNt`>fIVd7x>NyVHN}^4Yy@1F^CC(r{;iCUDZ~dE>I9c z?&1eZ@vU@PnQsuk(hD^QiGTSfH0rsTARHl_KDp*GWw60>cRRJYiw0&hO!aw71RUNo zrJIajkvRA_GV3s|Hv44|$?HmNw09qKVwvww2>;?vZEQL1RBV)Qi~fefB2FHphY@q6 zCO(aOz-`v0wQsdV)>XL8FU?G!Xu)jW{4&rzg1L_DHpU+(kl>KEYH@gZQfp(?k*ZQLX?)oP^oXpbbSfGVAUpA)Cw-D5yJW&L_qCa zUCiiknM9X$5z^SQPEM&YkT|TxA@VDSDh=?Mrs}Fcbpq1EveV=R?=XynpLPxlq zm+#lB2h#kLDGdRcfCJujt8=YhgkOHzTGrrG-1_6^iQhEKN#+lr(+*5&*O@T9 zWJpf(zLPJ|*a_Um9X8q!CJQ26s3oP>i<-4W;i$wBqBnQt(D$EBcPR5x)u^m z8cB4vee7Fr;9KWCF}@yT-T8euoBiQ&mRfkXKrQOo$vZvubljFTE%N2#6Q(5M9Gjv_ zD1IL~UtmdeA7UiXOhngLOHF&?YvzKX;&*Z1Q zqD4zJuYYr{DV)7wz21w{+dEKc|6ZVE?A-yjR;D7Rrp{(AE)t$5W{!Uhyub2pRP2Oo zpD=pxRDJ18N#*U-V+b5+14ff{h=&79^J7HzbOUbf}q? z0N4y43+G7>wvm5SDm7cYls;U!D6>p6v7w@92LBcpjFM)Gm`b7zc+2G6T{v`ljApKv z^FX}y5$J69a7|0OH$%zrMNko@hq}^MHyqhi{X)cP8Y^dYp#Segmu>FY)su#h#wYZ0 zW^S~S`AR9Cm?9>KsrD!`3{MMwjf*%H?~xQCDF2nIB?BtBY%kxq@#Wghe0{Sru^bk& z9r+X|yj!x>4praAN}M6?gWssG<8^yFnmVK4Pj3$h;Cx-SXSp_a4?Rr~KEpFiJ92?r zG6nGUyt%X`2e@RRTGp)0(uid_-z0xZ948G@mW`?7#3+4WaHialbO{xze`me_Im@vAOP5vsOJOQncem2X&C!SjH&pf!Y0Mey#}!kR zqo!$3UzovfH zwrx?xmkO+cQS@9SGi}-DTRXYzUbthiEa}8!)mEU9P`>lThHI^Add{)nJBJpmX{o&< z15qy~r+K+F>6%Dqx-jJ(R*b|DTz^A4{z8s{0x2rtkHBa0LL+8>6jHW8>_{qc z`D^EmpnWHNu}DK|4WveCH;`D;;1=*R9o7c8AXh>?tt|9BWF4Luj&XSxFQd9;CtKmP z9hy5RiiXkJ^g`{}-&qdd#BSA9*(Sn{2=e?Qz0QqVcJXe&5JV^wD8FLLkEbrxUc#(W z+QMs`rYtpFVk=?8B`>5u3aCxguoU7YrX+NkWZ!tJcet(%6CBU>i#PbDQ2~Rkf=G5} zSk7&0wRxY@y=%)5!Wd_2`#NY<+2fiTAe|Mhm&UOtUp!*W5=#HHvvg*!>r}i zk{5J)PZ59A|Nqv*s<{G8Y(yR0>`nikAA)1$lzRW<2jN^@^n~OsGTAj^Y@KFDe?aa` ze^9f3Gm#ub{&bok`qv~nRIFF9_qnc(S!9V&JLmIE5YOgWeYVjB5!hsn1#uWd5~^IP znch%zw1NL#OKsvNYN*!t^N;m%#TKxpE2E9}fioTZ?)xt>?zMJ934MGZT0^PyG$G}z zZosP36QWwjsEXKQR5a7X5Ij|l&&I-1eU|V3l7hcz!wYe?nF;lopqIYcT{^!ikxmxX z({|*0c9@;g_SoWO;^&j6l*jQ*prdz%na7mZhhyVa+)De|uoIYwmAM_1Z!`U)H_m+7 zbOc`g^#u(4sf%CBWDMcHXWSnS^|!_SEU_m7h_+I(6s|06<>O9N8a9GzAT4!HEQiGU z%DlK+CN0D)N{+J<$nSZ9|39c zqyM2hV+)8i8E9j+e@0R7Zrjh3P*+y&CzVxDK|>I{XJ7wxX1#3ZUMy)8CDeoU75G;V zJ=K|N8L9FX>}^g$DpRP?w3+e1c<8%%>U)24OYn_m&3S95K8o$rN=y^Wd3Uc4bY{v? zH*AKBBOz8KhgAg)9+sUx>ahMTgwYh7{GKe*zDa8JSWcSJ&sZXLi|_&HLgumqfwxlq zF}cjHxfCS2=oa;Z+}Sg$9%(du0%zC*4V zBbQiqGVW?SEiab!Uxh`mfrEx>H%xP=<1G8s3*UMOxM5FKloA%_k2|YvJh;dv4;rQD zWvV56$8@bZer*vgdyFC_7NePgmQHI|KIN*D=hMRfu9qhLJSIz_%5ulHeQaI99*j=i zg+J0=zHVX(zK(iiEO;>!XGRopfG`Ns7C@f)1q z2g3xfCLGLIj+7c>pl^V>N&0tH25#{wOd;u(f_%kZaOoKKP-2J2e%PTe%7|_5jOKQW6RAx1IyB zA%$Su!}v7x4%+RsU}VBoui>d&E%$Jq2iod)K|_eCnePyh>^efu>yvMwAM^b_^_65C zeC9K?KV!4%B_-?FS>r)7i#5L6Rz!^VT|Ae%fERuo`4dx02Y{Zdci&vqZkY$ zFUu|xs!lSdFPHWYsWp1+f+??K_PEea!!^Ym-3WH3Jkhy9PDzV%0DO`@kw<)rB+2Ml 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

bXX6 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

$rbbE!fST0(P@kqlpTk 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 + 4.0.0 + org.ciyam + AT + 1.4.1 + jar + + + UTF-8 + false + + 3.8.1 + 3.2.0 + 3.3.1 + 3.0.0-M4 + 3.2.0 + + 1.64 + + + + src/main/java + src/test/java + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 11 + 11 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + ${skipTests} + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + attach-javadoc + + jar + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + test-jar + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + test + + + junit + junit + 4.13 + test + + + diff --git a/lib/org/ciyam/AT/maven-metadata-local.xml b/lib/org/ciyam/AT/maven-metadata-local.xml index 063c735d..d8f3dd34 100644 --- a/lib/org/ciyam/AT/maven-metadata-local.xml +++ b/lib/org/ciyam/AT/maven-metadata-local.xml @@ -3,7 +3,7 @@ org.ciyam AT - 1.4.0 + 1.4.1 1.3.4 1.3.5 @@ -11,7 +11,8 @@ 1.3.7 1.3.8 1.4.0 + 1.4.1 - 20221105114346 + 20230821074325 diff --git a/pom.xml b/pom.xml index fbcd40a5..0d286d8d 100644 --- a/pom.xml +++ b/pom.xml @@ -11,18 +11,18 @@ 0.15.10 1.69 ${maven.build.timestamp} - 1.4.0 - 3.6 - 1.8 - 2.6 - 1.21 - 3.12.0 + 1.4.1 + 3.9.0 + 1.10.0 + 2.13.0 + 1.23.0 + 3.13.0 1.9 1.2.2 - 28.1-jre - 2.5.1 + 32.1.2-jre + 2.7.2 1.2.1 - 70.1 + 73.2 1.1 2.29.1 9.4.29.v20200521 @@ -33,9 +33,9 @@ 3.23.8 1.1.0 1.13.1 - 4.10 - 1.45.1 - 3.19.4 + 4.12 + 1.57.2 + 3.24.2 1.17 diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index cd2b30fa..c2e9cd62 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -454,40 +454,40 @@ public class HSQLDBDatabaseUpdates { case 12: // Groups - stmt.execute("CREATE TABLE Groups (group_id GroupID, owner QortalAddress NOT NULL, group_name GroupName NOT NULL, " + stmt.execute("CREATE TABLE `Groups` (group_id GroupID, owner QortalAddress NOT NULL, group_name GroupName NOT NULL, " + "created_when EpochMillis NOT NULL, updated_when EpochMillis, is_open BOOLEAN NOT NULL, " + "approval_threshold TINYINT NOT NULL, min_block_delay INTEGER NOT NULL, max_block_delay INTEGER NOT NULL, " + "reference Signature, creation_group_id GroupID, reduced_group_name GroupName NOT NULL, " + "description GenericDescription NOT NULL, PRIMARY KEY (group_id))"); // For finding groups by name - stmt.execute("CREATE INDEX GroupNameIndex on Groups (group_name)"); + stmt.execute("CREATE INDEX GroupNameIndex on `Groups` (group_name)"); // For finding groups by reduced name - stmt.execute("CREATE INDEX GroupReducedNameIndex on Groups (reduced_group_name)"); + stmt.execute("CREATE INDEX GroupReducedNameIndex on `Groups` (reduced_group_name)"); // For finding groups by owner - stmt.execute("CREATE INDEX GroupOwnerIndex ON Groups (owner)"); + stmt.execute("CREATE INDEX GroupOwnerIndex ON `Groups` (owner)"); // We need a corresponding trigger to make sure new group_id values are assigned sequentially starting from 1 - stmt.execute("CREATE TRIGGER Group_ID_Trigger BEFORE INSERT ON Groups " + stmt.execute("CREATE TRIGGER Group_ID_Trigger BEFORE INSERT ON `Groups` " + "REFERENCING NEW ROW AS new_row FOR EACH ROW WHEN (new_row.group_id IS NULL) " - + "SET new_row.group_id = (SELECT IFNULL(MAX(group_id) + 1, 1) FROM Groups)"); + + "SET new_row.group_id = (SELECT IFNULL(MAX(group_id) + 1, 1) FROM `Groups`)"); // Admins stmt.execute("CREATE TABLE GroupAdmins (group_id GroupID, admin QortalAddress, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, admin), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, admin), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For finding groups by admin address stmt.execute("CREATE INDEX GroupAdminIndex ON GroupAdmins (admin)"); // Members stmt.execute("CREATE TABLE GroupMembers (group_id GroupID, address QortalAddress, " + "joined_when EpochMillis NOT NULL, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, address), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, address), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For finding groups by member address stmt.execute("CREATE INDEX GroupMemberIndex ON GroupMembers (address)"); // Invites stmt.execute("CREATE TABLE GroupInvites (group_id GroupID, inviter QortalAddress, invitee QortalAddress, " + "expires_when EpochMillis, reference Signature, " - + "PRIMARY KEY (group_id, invitee), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, invitee), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For finding invites sent by inviter stmt.execute("CREATE INDEX GroupInviteInviterIndex ON GroupInvites (inviter)"); // For finding invites by group @@ -503,7 +503,7 @@ public class HSQLDBDatabaseUpdates { // NULL expires_when means does not expire! stmt.execute("CREATE TABLE GroupBans (group_id GroupID, offender QortalAddress, admin QortalAddress NOT NULL, " + "banned_when EpochMillis NOT NULL, reason GenericDescription NOT NULL, expires_when EpochMillis, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, offender), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, offender), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For expiry maintenance stmt.execute("CREATE INDEX GroupBanExpiryIndex ON GroupBans (expires_when)"); break; From b92c7cc86651faaec21f020e712383facc05870f Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:35:53 +0200 Subject: [PATCH 36/74] Update dependencies and ntp servers --- pom.xml | 18 ++--- .../java/org/qortal/settings/Settings.java | 73 +++++++++++-------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index 0d286d8d..32e9343e 100644 --- a/pom.xml +++ b/pom.xml @@ -51,14 +51,14 @@ org.codehaus.mojo versions-maven-plugin - 2.5 + 2.16.0 false maven-compiler-plugin - 3.8.0 + 3.11.0 11 @@ -232,7 +232,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.4.0 generate-sources @@ -250,7 +250,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.2.0 + 3.3.0 @@ -268,7 +268,7 @@ org.apache.maven.plugins maven-shade-plugin - 2.4.3 + 3.5.0 false @@ -318,7 +318,7 @@ io.github.zlika reproducible-build-maven-plugin - 0.11 + 0.16 package @@ -335,7 +335,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + 3.1.2 ${skipTests} @@ -360,7 +360,7 @@ maven-dependency-plugin - [2.8,) + [3.6.0,) unpack @@ -413,7 +413,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.4.0 provided diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index bdff9506..f9f4eb0b 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -47,8 +47,8 @@ public class Settings { private static final int MAINNET_GATEWAY_PORT = 80; private static final int TESTNET_GATEWAY_PORT = 8080; - private static final int MAINNET_DEV_PROXY_PORT = 12393; - private static final int TESTNET_DEV_PROXY_PORT = 62393; + private static final int MAINNET_DEV_PROXY_PORT = 12393; + private static final int TESTNET_DEV_PROXY_PORT = 62393; private static final Logger LOGGER = LogManager.getLogger(Settings.class); private static final String SETTINGS_FILENAME = "settings.json"; @@ -110,10 +110,9 @@ public class Settings { private boolean gatewayLoggingEnabled = false; private boolean gatewayLoopbackEnabled = false; - // Developer Proxy + // Developer Proxy private Integer devProxyPort; - private boolean devProxyLoggingEnabled = false; - + private boolean devProxyLoggingEnabled = false; // Specific to this node private boolean wipeUnconfirmedOnStart = false; @@ -186,7 +185,6 @@ public class Settings { * This has a significant effect on execution time. */ private int blockPruneBatchSize = 10000; // blocks - /** Whether we should archive old data to reduce the database size */ private boolean archiveEnabled = true; /** How often to attempt archiving (ms). */ @@ -194,15 +192,12 @@ public class Settings { /** Serialization version to use when building an archive */ private int defaultArchiveVersion = 2; - /** Whether to automatically bootstrap instead of syncing from genesis */ private boolean bootstrap = true; - /** Registered names integrity check */ private boolean namesIntegrityCheckEnabled = false; - // Peer-to-peer related private boolean isTestNet = false; /** Single node testnet mode */ @@ -289,10 +284,10 @@ public class Settings { // Bootstrap sources private String[] bootstrapHosts = new String[] { - "http://bootstrap.qortal.org", - "http://bootstrap2.qortal.org", - "http://bootstrap3.qortal.org", - "http://bootstrap.qortal.online" + "http://bootstrap.qortal.org", + "http://bootstrap2.qortal.org", + "http://bootstrap3.qortal.org", + "http://bootstrap.qortal.online" }; // Auto-update sources @@ -311,17 +306,35 @@ public class Settings { "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org", - "cn.pool.ntp.org", - "0.cn.pool.ntp.org", - "1.cn.pool.ntp.org", - "2.cn.pool.ntp.org", - "3.cn.pool.ntp.org" + "asia.pool.ntp.org", + "0.asia.pool.ntp.org", + "1.asia.pool.ntp.org", + "2.asia.pool.ntp.org", + "3.asia.pool.ntp.org", + "europe.pool.ntp.org", + "0.europe.pool.ntp.org", + "1.europe.pool.ntp.org", + "2.europe.pool.ntp.org", + "3.europe.pool.ntp.org", + "north-america.pool.ntp.org", + "0.north-america.pool.ntp.org", + "1.north-america.pool.ntp.org", + "2.north-america.pool.ntp.org", + "3.north-america.pool.ntp.org", + "oceania.pool.ntp.org", + "0.oceania.pool.ntp.org", + "1.oceania.pool.ntp.org", + "2.oceania.pool.ntp.org", + "3.oceania.pool.ntp.org", + "south-america.pool.ntp.org", + "0.south-america.pool.ntp.org", + "1.south-america.pool.ntp.org", + "2.south-america.pool.ntp.org", + "3.south-america.pool.ntp.org" }; /** Additional offset added to values returned by NTP.getTime() */ private Long testNtpOffset = null; - - /* Foreign chains */ /** The number of consecutive empty addresses required before treating a wallet's transaction set as complete */ @@ -330,8 +343,6 @@ public class Settings { /** How many wallet keys to generate when using bitcoinj as the blockchain interface (e.g. when sending coins) */ private int bitcoinjLookaheadSize = 50; - - // Data storage (QDN) /** Data storage enabled/disabled*/ @@ -396,7 +407,6 @@ public class Settings { } } - // Constructors private Settings() { @@ -660,17 +670,16 @@ public class Settings { } - public int getDevProxyPort() { - if (this.devProxyPort != null) - return this.devProxyPort; + public int getDevProxyPort() { + if (this.devProxyPort != null) + return this.devProxyPort; - return this.isTestNet ? TESTNET_DEV_PROXY_PORT : MAINNET_DEV_PROXY_PORT; - } - - public boolean isDevProxyLoggingEnabled() { - return this.devProxyLoggingEnabled; - } + return this.isTestNet ? TESTNET_DEV_PROXY_PORT : MAINNET_DEV_PROXY_PORT; + } + public boolean isDevProxyLoggingEnabled() { + return this.devProxyLoggingEnabled; + } public boolean getWipeUnconfirmedOnStart() { return this.wipeUnconfirmedOnStart; From 43921e6ab869d7d04cb69efa0a6a3d051b2bb870 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 13:44:54 +0200 Subject: [PATCH 37/74] Update jetty server --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32e9343e..0cbb83cf 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 73.2 1.1 2.29.1 - 9.4.29.v20200521 + 9.4.52.v20230823 2.17.1 UTF-8 1.7.12 From 6be3897fdb5444847db2750c8d2f2685007da4a9 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 15:06:46 +0200 Subject: [PATCH 38/74] Update logging --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0cbb83cf..5205c1b3 100644 --- a/pom.xml +++ b/pom.xml @@ -26,9 +26,9 @@ 1.1 2.29.1 9.4.52.v20230823 - 2.17.1 + 2.20.0 UTF-8 - 1.7.12 + 2.0.9 2.0.9 3.23.8 1.1.0 From 12dbff79c9fff49aba5e4dd0717b79fc7546eda2 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 15:20:21 +0200 Subject: [PATCH 39/74] Update logging properties --- log4j2.properties | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/log4j2.properties b/log4j2.properties index 44e1b1e3..54f295c1 100644 --- a/log4j2.properties +++ b/log4j2.properties @@ -1,7 +1,7 @@ rootLogger.level = info # On Windows, uncomment next line to set dirname: # property.dirname = ${sys:user.home}\\AppData\\Local\\qortal\\ -property.filename = ${sys:log4j2.filenameTemplate:-log.txt} +# property.filename = ${sys:log4j2.filenameTemplate:-log.txt} rootLogger.appenderRef.console.ref = stdout rootLogger.appenderRef.rolling.ref = FILE @@ -59,11 +59,14 @@ appender.console.filter.threshold.level = error appender.rolling.type = RollingFile appender.rolling.name = FILE +appender.rolling.fileName = qortal.log +appender.rolling.filePattern = qortal.%d{dd-MMM}.log.gz appender.rolling.layout.type = PatternLayout appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -appender.rolling.filePattern = ./${filename}.%i appender.rolling.policy.type = SizeBasedTriggeringPolicy -appender.rolling.policy.size = 4MB +appender.rolling.policy.size = 10MB +appender.rolling.strategy.type = DefaultRolloverStrategy +appender.rolling.strategy.max = 7 # Set the immediate flush to true (default) # appender.rolling.immediateFlush = true # Set the append to true (default), should not overwrite From c0ed4022a5256b9d47eb879c8f73ed6e7d49418a Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 15:27:33 +0200 Subject: [PATCH 40/74] Update log4j2.properties --- WindowsInstaller/Install Files/log4j2.properties | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/WindowsInstaller/Install Files/log4j2.properties b/WindowsInstaller/Install Files/log4j2.properties index 44e1b1e3..54f295c1 100755 --- a/WindowsInstaller/Install Files/log4j2.properties +++ b/WindowsInstaller/Install Files/log4j2.properties @@ -1,7 +1,7 @@ rootLogger.level = info # On Windows, uncomment next line to set dirname: # property.dirname = ${sys:user.home}\\AppData\\Local\\qortal\\ -property.filename = ${sys:log4j2.filenameTemplate:-log.txt} +# property.filename = ${sys:log4j2.filenameTemplate:-log.txt} rootLogger.appenderRef.console.ref = stdout rootLogger.appenderRef.rolling.ref = FILE @@ -59,11 +59,14 @@ appender.console.filter.threshold.level = error appender.rolling.type = RollingFile appender.rolling.name = FILE +appender.rolling.fileName = qortal.log +appender.rolling.filePattern = qortal.%d{dd-MMM}.log.gz appender.rolling.layout.type = PatternLayout appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -appender.rolling.filePattern = ./${filename}.%i appender.rolling.policy.type = SizeBasedTriggeringPolicy -appender.rolling.policy.size = 4MB +appender.rolling.policy.size = 10MB +appender.rolling.strategy.type = DefaultRolloverStrategy +appender.rolling.strategy.max = 7 # Set the immediate flush to true (default) # appender.rolling.immediateFlush = true # Set the append to true (default), should not overwrite From bd055780358a347601f7b76f06a512f60fa0c755 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 5 Sep 2023 18:31:32 +0200 Subject: [PATCH 41/74] Reverse need latest 1.7.x --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5205c1b3..bdc4f1c6 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 9.4.52.v20230823 2.20.0 UTF-8 - 2.0.9 + 1.7.36 2.0.9 3.23.8 1.1.0 From 94e9f86245157310f868d3ed7368a50535cc8796 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 6 Sep 2023 09:11:41 +0200 Subject: [PATCH 42/74] Version 3.8.0 get faster the NTP offset --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bdc4f1c6..30448cab 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 1.69 ${maven.build.timestamp} 1.4.1 - 3.9.0 + 3.8.0 1.10.0 2.13.0 1.23.0 From 1a9087984a8425d63bf7db320470a592909bce3c Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 6 Sep 2023 17:22:13 +0200 Subject: [PATCH 43/74] Swagger updates --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 30448cab..8cbb7b58 100644 --- a/pom.xml +++ b/pom.xml @@ -29,8 +29,8 @@ 2.20.0 UTF-8 1.7.36 - 2.0.9 - 3.23.8 + 2.0.10 + 3.23.11 1.1.0 1.13.1 4.12 @@ -89,7 +89,7 @@ pl.project13.maven git-commit-id-plugin - 4.0.0 + 4.9.10 get-the-git-infos From a7ca306d1b7a9d36690fa897c0251a249790b41d Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:54:09 +0200 Subject: [PATCH 44/74] Update json dependency --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8cbb7b58..85e086ae 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ 2.0.10 3.23.11 1.1.0 - 1.13.1 + 1.16.1 4.12 1.57.2 3.24.2 @@ -462,7 +462,7 @@ org.json json - 20210307 + 20230618 org.apache.commons From 9959985a13aa0c9cbdc8d7bae5fa5cd2a0b5c1bc Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 9 Sep 2023 10:56:17 +0200 Subject: [PATCH 45/74] Update grpc --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 85e086ae..bea65026 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 1.1.0 1.16.1 4.12 - 1.57.2 + 1.58.0 3.24.2 1.17 @@ -168,7 +168,7 @@ ^(#.*$[\n\r]*) - + @@ -367,7 +367,7 @@ - + @@ -386,7 +386,7 @@ - + From 1fbb1659a33b56c6134b239b1cd3582c356e69bf Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:43:05 +0200 Subject: [PATCH 46/74] Update dependencies --- pom.xml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index bea65026..29b7ac58 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ 3.8.0 1.10.0 2.13.0 - 1.23.0 + 1.24.0 3.13.0 1.9 1.2.2 @@ -35,7 +35,7 @@ 1.16.1 4.12 1.58.0 - 3.24.2 + 3.24.3 1.17 @@ -164,7 +164,9 @@ ${project.build.outputDirectory}/git.properties true - MULTILINE + + MULTILINE + ^(#.*$[\n\r]*) @@ -414,14 +416,16 @@ org.codehaus.mojo build-helper-maven-plugin 3.4.0 - provided + provided + com.github.bohnman package-info-maven-plugin ${package-info-maven-plugin.version} - provided + provided + @@ -638,7 +642,8 @@ jersey-hk2 ${jersey.version} - + + javax.inject javax.inject @@ -665,7 +670,8 @@ swagger-jaxrs2-servlet-initializer ${swagger-api.version} - + + io.swagger.core.v3 swagger-integration From cae3fdcb064ef06aa8db80b822300a5feed0c398 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Fri, 22 Sep 2023 11:12:50 +0200 Subject: [PATCH 47/74] Update ElectrumX Servers --- .../java/org/qortal/crosschain/Bitcoin.java | 173 +++++++++--------- .../java/org/qortal/crosschain/Digibyte.java | 24 ++- .../java/org/qortal/crosschain/Dogecoin.java | 25 +-- .../java/org/qortal/crosschain/Litecoin.java | 45 ++--- .../org/qortal/crosschain/PirateChain.java | 18 +- .../java/org/qortal/crosschain/Ravencoin.java | 31 ++-- 6 files changed, 160 insertions(+), 156 deletions(-) diff --git a/src/main/java/org/qortal/crosschain/Bitcoin.java b/src/main/java/org/qortal/crosschain/Bitcoin.java index b65bac8e..7925dd4e 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoin.java +++ b/src/main/java/org/qortal/crosschain/Bitcoin.java @@ -44,89 +44,78 @@ public class Bitcoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - // Servers chosen on NO BASIS WHATSOEVER from various sources! - // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=btc - //CLOSED new Server("bitcoin.grey.pw", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("btc.litepay.ch", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("electrum.pabu.io", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("electrumx.dev", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("electrumx.hodlwallet.com", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("gd42.org", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("korea.electrum-server.com", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("prospero.bitsrc.net", Server.ConnectionType.SSL, 50002), - //1.15.0 new Server("alviss.coinjoined.com", Server.ConnectionType.SSL, 50002), - //1.15.0 new Server("electrum.acinq.co", Server.ConnectionType.SSL, 50002), - //1.14.0 new Server("electrum.coinext.com.br", Server.ConnectionType.SSL, 50002), - //F1.7.0 new Server("btc.lastingcoin.net", Server.ConnectionType.SSL, 50002), - new Server("104.248.139.211", Server.ConnectionType.SSL, 50002), - new Server("128.0.190.26", Server.ConnectionType.SSL, 50002), - new Server("142.93.6.38", Server.ConnectionType.SSL, 50002), - new Server("157.245.172.236", Server.ConnectionType.SSL, 50002), - new Server("167.172.226.175", Server.ConnectionType.SSL, 50002), - new Server("167.172.42.31", Server.ConnectionType.SSL, 50002), - new Server("178.62.80.20", Server.ConnectionType.SSL, 50002), - new Server("185.64.116.15", Server.ConnectionType.SSL, 50002), - new Server("188.165.206.215", Server.ConnectionType.SSL, 50002), - new Server("188.165.211.112", Server.ConnectionType.SSL, 50002), - new Server("2azzarita.hopto.org", Server.ConnectionType.SSL, 50002), - new Server("2electrumx.hopto.me", Server.ConnectionType.SSL, 56022), - new Server("2ex.digitaleveryware.com", Server.ConnectionType.SSL, 50002), - new Server("65.39.140.37", Server.ConnectionType.SSL, 50002), - new Server("68.183.188.105", Server.ConnectionType.SSL, 50002), - new Server("71.73.14.254", Server.ConnectionType.SSL, 50002), - new Server("94.23.247.135", Server.ConnectionType.SSL, 50002), - new Server("assuredly.not.fyi", Server.ConnectionType.SSL, 50002), - new Server("ax101.blockeng.ch", Server.ConnectionType.SSL, 50002), - new Server("ax102.blockeng.ch", Server.ConnectionType.SSL, 50002), - new Server("b.1209k.com", Server.ConnectionType.SSL, 50002), - new Server("b6.1209k.com", Server.ConnectionType.SSL, 50002), - new Server("bitcoin.dermichi.com", Server.ConnectionType.SSL, 50002), - new Server("bitcoin.lu.ke", Server.ConnectionType.SSL, 50002), - new Server("bitcoin.lukechilds.co", Server.ConnectionType.SSL, 50002), - new Server("blkhub.net", Server.ConnectionType.SSL, 50002), - new Server("btc.electroncash.dk", Server.ConnectionType.SSL, 60002), - new Server("btc.ocf.sh", Server.ConnectionType.SSL, 50002), - new Server("btce.iiiiiii.biz", Server.ConnectionType.SSL, 50002), - new Server("caleb.vegas", Server.ConnectionType.SSL, 50002), - new Server("eai.coincited.net", Server.ConnectionType.SSL, 50002), - new Server("electrum.bhoovd.com", Server.ConnectionType.SSL, 50002), - new Server("electrum.bitaroo.net", Server.ConnectionType.SSL, 50002), - new Server("electrum.bitcoinlizard.net", Server.ConnectionType.SSL, 50002), - new Server("electrum.blockstream.info", Server.ConnectionType.SSL, 50002), - new Server("electrum.emzy.de", Server.ConnectionType.SSL, 50002), - new Server("electrum.exan.tech", Server.ConnectionType.SSL, 50002), - new Server("electrum.kendigisland.xyz", Server.ConnectionType.SSL, 50002), - new Server("electrum.mmitech.info", Server.ConnectionType.SSL, 50002), - new Server("electrum.petrkr.net", Server.ConnectionType.SSL, 50002), - new Server("electrum.stippy.com", Server.ConnectionType.SSL, 50002), - new Server("electrum.thomasfischbach.de", Server.ConnectionType.SSL, 50002), - new Server("electrum0.snel.it", Server.ConnectionType.SSL, 50002), - new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 50002), - new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 50002), - new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 50002), - new Server("electrumx.alexridevski.net", Server.ConnectionType.SSL, 50002), - new Server("electrumx-core.1209k.com", Server.ConnectionType.SSL, 50002), - new Server("elx.bitske.com", Server.ConnectionType.SSL, 50002), - new Server("ex03.axalgo.com", Server.ConnectionType.SSL, 50002), - new Server("ex05.axalgo.com", Server.ConnectionType.SSL, 50002), - new Server("ex07.axalgo.com", Server.ConnectionType.SSL, 50002), - new Server("fortress.qtornado.com", Server.ConnectionType.SSL, 50002), - new Server("fulcrum.grey.pw", Server.ConnectionType.SSL, 50002), - new Server("fulcrum.sethforprivacy.com", Server.ConnectionType.SSL, 51002), - new Server("guichet.centure.cc", Server.ConnectionType.SSL, 50002), - new Server("hodlers.beer", Server.ConnectionType.SSL, 50002), - new Server("kareoke.qoppa.org", Server.ConnectionType.SSL, 50002), - new Server("kirsche.emzy.de", Server.ConnectionType.SSL, 50002), - new Server("node1.btccuracao.com", Server.ConnectionType.SSL, 50002), - new Server("osr1ex1.compumundohipermegared.one", Server.ConnectionType.SSL, 50002), - new Server("smmalis37.ddns.net", Server.ConnectionType.SSL, 50002), - new Server("ulrichard.ch", Server.ConnectionType.SSL, 50002), - new Server("vmd104012.contaboserver.net", Server.ConnectionType.SSL, 50002), - new Server("vmd104014.contaboserver.net", Server.ConnectionType.SSL, 50002), - new Server("vmd63185.contaboserver.net", Server.ConnectionType.SSL, 50002), - new Server("vmd71287.contaboserver.net", Server.ConnectionType.SSL, 50002), - new Server("vmd84592.contaboserver.net", Server.ConnectionType.SSL, 50002), - new Server("xtrum.com", Server.ConnectionType.SSL, 50002)); + // Servers chosen on NO BASIS WHATSOEVER from various sources! + // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=btc + new Server("104.248.139.211", Server.ConnectionType.SSL, 50002), + new Server("128.0.190.26", Server.ConnectionType.SSL, 50002), + new Server("142.93.6.38", Server.ConnectionType.SSL, 50002), + new Server("157.245.172.236", Server.ConnectionType.SSL, 50002), + new Server("167.172.226.175", Server.ConnectionType.SSL, 50002), + new Server("167.172.42.31", Server.ConnectionType.SSL, 50002), + new Server("178.62.80.20", Server.ConnectionType.SSL, 50002), + new Server("185.64.116.15", Server.ConnectionType.SSL, 50002), + new Server("188.165.206.215", Server.ConnectionType.SSL, 50002), + new Server("188.165.211.112", Server.ConnectionType.SSL, 50002), + new Server("2azzarita.hopto.org", Server.ConnectionType.SSL, 50002), + new Server("2electrumx.hopto.me", Server.ConnectionType.SSL, 56022), + new Server("2ex.digitaleveryware.com", Server.ConnectionType.SSL, 50002), + new Server("65.39.140.37", Server.ConnectionType.SSL, 50002), + new Server("68.183.188.105", Server.ConnectionType.SSL, 50002), + new Server("71.73.14.254", Server.ConnectionType.SSL, 50002), + new Server("94.23.247.135", Server.ConnectionType.SSL, 50002), + new Server("assuredly.not.fyi", Server.ConnectionType.SSL, 50002), + new Server("ax101.blockeng.ch", Server.ConnectionType.SSL, 50002), + new Server("ax102.blockeng.ch", Server.ConnectionType.SSL, 50002), + new Server("b.1209k.com", Server.ConnectionType.SSL, 50002), + new Server("b6.1209k.com", Server.ConnectionType.SSL, 50002), + new Server("bitcoin.dermichi.com", Server.ConnectionType.SSL, 50002), + new Server("bitcoin.lu.ke", Server.ConnectionType.SSL, 50002), + new Server("bitcoin.lukechilds.co", Server.ConnectionType.SSL, 50002), + new Server("blkhub.net", Server.ConnectionType.SSL, 50002), + new Server("btc.electroncash.dk", Server.ConnectionType.SSL, 60002), + new Server("btc.ocf.sh", Server.ConnectionType.SSL, 50002), + new Server("btce.iiiiiii.biz", Server.ConnectionType.SSL, 50002), + new Server("caleb.vegas", Server.ConnectionType.SSL, 50002), + new Server("eai.coincited.net", Server.ConnectionType.SSL, 50002), + new Server("electrum.bhoovd.com", Server.ConnectionType.SSL, 50002), + new Server("electrum.bitaroo.net", Server.ConnectionType.SSL, 50002), + new Server("electrum.bitcoinlizard.net", Server.ConnectionType.SSL, 50002), + new Server("electrum.blockstream.info", Server.ConnectionType.SSL, 50002), + new Server("electrum.emzy.de", Server.ConnectionType.SSL, 50002), + new Server("electrum.exan.tech", Server.ConnectionType.SSL, 50002), + new Server("electrum.kendigisland.xyz", Server.ConnectionType.SSL, 50002), + new Server("electrum.mmitech.info", Server.ConnectionType.SSL, 50002), + new Server("electrum.petrkr.net", Server.ConnectionType.SSL, 50002), + new Server("electrum.stippy.com", Server.ConnectionType.SSL, 50002), + new Server("electrum.thomasfischbach.de", Server.ConnectionType.SSL, 50002), + new Server("electrum0.snel.it", Server.ConnectionType.SSL, 50002), + new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 50002), + new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 50002), + new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 50002), + new Server("electrumx.alexridevski.net", Server.ConnectionType.SSL, 50002), + new Server("electrumx-core.1209k.com", Server.ConnectionType.SSL, 50002), + new Server("elx.bitske.com", Server.ConnectionType.SSL, 50002), + new Server("ex03.axalgo.com", Server.ConnectionType.SSL, 50002), + new Server("ex05.axalgo.com", Server.ConnectionType.SSL, 50002), + new Server("ex07.axalgo.com", Server.ConnectionType.SSL, 50002), + new Server("fortress.qtornado.com", Server.ConnectionType.SSL, 50002), + new Server("fulcrum.grey.pw", Server.ConnectionType.SSL, 50002), + new Server("fulcrum.sethforprivacy.com", Server.ConnectionType.SSL, 51002), + new Server("guichet.centure.cc", Server.ConnectionType.SSL, 50002), + new Server("hodlers.beer", Server.ConnectionType.SSL, 50002), + new Server("kareoke.qoppa.org", Server.ConnectionType.SSL, 50002), + new Server("kirsche.emzy.de", Server.ConnectionType.SSL, 50002), + new Server("node1.btccuracao.com", Server.ConnectionType.SSL, 50002), + new Server("osr1ex1.compumundohipermegared.one", Server.ConnectionType.SSL, 50002), + new Server("smmalis37.ddns.net", Server.ConnectionType.SSL, 50002), + new Server("ulrichard.ch", Server.ConnectionType.SSL, 50002), + new Server("vmd104012.contaboserver.net", Server.ConnectionType.SSL, 50002), + new Server("vmd104014.contaboserver.net", Server.ConnectionType.SSL, 50002), + new Server("vmd63185.contaboserver.net", Server.ConnectionType.SSL, 50002), + new Server("vmd71287.contaboserver.net", Server.ConnectionType.SSL, 50002), + new Server("vmd84592.contaboserver.net", Server.ConnectionType.SSL, 50002), + new Server("xtrum.com", Server.ConnectionType.SSL, 50002) + ); } @Override @@ -152,12 +141,13 @@ public class Bitcoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("tn.not.fyi", Server.ConnectionType.SSL, 55002), - new Server("electrumx-test.1209k.com", Server.ConnectionType.SSL, 50002), - new Server("testnet.qtornado.com", Server.ConnectionType.SSL, 51002), - new Server("testnet.aranguren.org", Server.ConnectionType.TCP, 51001), - new Server("testnet.aranguren.org", Server.ConnectionType.SSL, 51002), - new Server("testnet.hsmiths.com", Server.ConnectionType.SSL, 53012)); + new Server("tn.not.fyi", Server.ConnectionType.SSL, 55002), + new Server("electrumx-test.1209k.com", Server.ConnectionType.SSL, 50002), + new Server("testnet.qtornado.com", Server.ConnectionType.SSL, 51002), + new Server("testnet.aranguren.org", Server.ConnectionType.TCP, 51001), + new Server("testnet.aranguren.org", Server.ConnectionType.SSL, 51002), + new Server("testnet.hsmiths.com", Server.ConnectionType.SSL, 53012) + ); } @Override @@ -179,8 +169,9 @@ public class Bitcoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("localhost", Server.ConnectionType.TCP, 50001), - new Server("localhost", Server.ConnectionType.SSL, 50002)); + new Server("localhost", Server.ConnectionType.TCP, 50001), + new Server("localhost", Server.ConnectionType.SSL, 50002) + ); } @Override diff --git a/src/main/java/org/qortal/crosschain/Digibyte.java b/src/main/java/org/qortal/crosschain/Digibyte.java index c5d96383..8e316173 100644 --- a/src/main/java/org/qortal/crosschain/Digibyte.java +++ b/src/main/java/org/qortal/crosschain/Digibyte.java @@ -43,14 +43,17 @@ public class Digibyte extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - // Servers chosen on NO BASIS WHATSOEVER from various sources! - // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=dgb - new Server("electrum.qortal.link", Server.ConnectionType.SSL, 55002), - new Server("electrum-dgb.qortal.online", ConnectionType.SSL, 50002), - new Server("electrum1-dgb.qortal.online", ConnectionType.SSL, 50002), - new Server("electrum1.cipig.net", ConnectionType.SSL, 20059), - new Server("electrum2.cipig.net", ConnectionType.SSL, 20059), - new Server("electrum3.cipig.net", ConnectionType.SSL, 20059)); + // Servers chosen on NO BASIS WHATSOEVER from various sources! + // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=dgb + new Server("electrum.qortal.link", Server.ConnectionType.SSL, 55002), + new Server("electrum1-dgb.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum2-dgb.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum3-dgb.qortal.online", Server.ConnectionType.SSL, 40002), + new Server("electrum4-dgb.qortal.online", Server.ConnectionType.SSL, 40002), + new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 20059), + new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 20059), + new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 20059) + ); } @Override @@ -94,8 +97,9 @@ public class Digibyte extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("localhost", ConnectionType.TCP, 50001), - new Server("localhost", ConnectionType.SSL, 50002)); + new Server("localhost", Server.ConnectionType.TCP, 50001), + new Server("localhost", Server.ConnectionType.SSL, 50002) + ); } @Override diff --git a/src/main/java/org/qortal/crosschain/Dogecoin.java b/src/main/java/org/qortal/crosschain/Dogecoin.java index 99f557a5..93941c41 100644 --- a/src/main/java/org/qortal/crosschain/Dogecoin.java +++ b/src/main/java/org/qortal/crosschain/Dogecoin.java @@ -4,7 +4,6 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.core.Context; import org.bitcoinj.core.NetworkParameters; import org.libdohj.params.DogecoinMainNetParams; -//import org.libdohj.params.DogecoinRegTestParams; import org.libdohj.params.DogecoinTestNet3Params; import org.qortal.crosschain.ElectrumX.Server; import org.qortal.crosschain.ElectrumX.Server.ConnectionType; @@ -44,14 +43,17 @@ public class Dogecoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - // Servers chosen on NO BASIS WHATSOEVER from various sources! - // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=doge - new Server("electrum.qortal.link", Server.ConnectionType.SSL, 54002), - new Server("electrum-doge.qortal.online", ConnectionType.SSL, 50002), - new Server("electrum1-doge.qortal.online", ConnectionType.SSL, 50002), - new Server("electrum1.cipig.net", ConnectionType.SSL, 20060), - new Server("electrum2.cipig.net", ConnectionType.SSL, 20060), - new Server("electrum3.cipig.net", ConnectionType.SSL, 20060)); + // Servers chosen on NO BASIS WHATSOEVER from various sources! + // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=doge + new Server("electrum.qortal.link", Server.ConnectionType.SSL, 54002), + new Server("electrum1-doge.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum2-doge.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum3-doge.qortal.online", Server.ConnectionType.SSL, 30002), + new Server("electrum4-doge.qortal.online", Server.ConnectionType.SSL, 30002), + new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 20060), + new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 20060), + new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 20060) + ); } @Override @@ -95,8 +97,9 @@ public class Dogecoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("localhost", ConnectionType.TCP, 50001), - new Server("localhost", ConnectionType.SSL, 50002)); + new Server("localhost", Server.ConnectionType.TCP, 50001), + new Server("localhost", Server.ConnectionType.SSL, 50002) + ); } @Override diff --git a/src/main/java/org/qortal/crosschain/Litecoin.java b/src/main/java/org/qortal/crosschain/Litecoin.java index 1dd9037a..22825c74 100644 --- a/src/main/java/org/qortal/crosschain/Litecoin.java +++ b/src/main/java/org/qortal/crosschain/Litecoin.java @@ -43,22 +43,21 @@ public class Litecoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - // Servers chosen on NO BASIS WHATSOEVER from various sources! - // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=ltc - //CLOSED new Server("electrum-ltc.someguy123.net", Server.ConnectionType.SSL, 50002), - //CLOSED new Server("ltc.litepay.ch", Server.ConnectionType.SSL, 50022), - //BEHIND new Server("62.171.169.176", Server.ConnectionType.SSL, 50002), - //PHISHY new Server("electrum-ltc.bysh.me", Server.ConnectionType.SSL, 50002), - new Server("backup.electrum-ltc.org", Server.ConnectionType.SSL, 443), - new Server("electrum.qortal.link", Server.ConnectionType.SSL, 50002), - new Server("electrum.ltc.xurious.com", Server.ConnectionType.SSL, 50002), - new Server("electrum-ltc.petrkr.net", Server.ConnectionType.SSL, 60002), - new Server("electrum-ltc.qortal.online", Server.ConnectionType.SSL, 50002), - new Server("electrum1-ltc.qortal.online", Server.ConnectionType.SSL, 50002), - new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 20063), - new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 20063), - new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 20063), - new Server("ltc.rentonrisk.com", Server.ConnectionType.SSL, 50002)); + // Servers chosen on NO BASIS WHATSOEVER from various sources! + // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=ltc + new Server("electrum.qortal.link", Server.ConnectionType.SSL, 50002), + new Server("electrum1-ltc.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum2-ltc.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum3-ltc.qortal.online", Server.ConnectionType.SSL, 20002), + new Server("electrum4-ltc.qortal.online", Server.ConnectionType.SSL, 20002), + new Server("backup.electrum-ltc.org", Server.ConnectionType.SSL, 443), + new Server("electrum.ltc.xurious.com", Server.ConnectionType.SSL, 50002), + new Server("electrum-ltc.petrkr.net", Server.ConnectionType.SSL, 60002), + new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 20063), + new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 20063), + new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 20063), + new Server("ltc.rentonrisk.com", Server.ConnectionType.SSL, 50002) + ); } @Override @@ -81,10 +80,11 @@ public class Litecoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("electrum-ltc.bysh.me", Server.ConnectionType.TCP, 51001), - new Server("electrum-ltc.bysh.me", Server.ConnectionType.SSL, 51002), - new Server("electrum.ltc.xurious.com", Server.ConnectionType.TCP, 51001), - new Server("electrum.ltc.xurious.com", Server.ConnectionType.SSL, 51002)); + new Server("electrum-ltc.bysh.me", Server.ConnectionType.TCP, 51001), + new Server("electrum-ltc.bysh.me", Server.ConnectionType.SSL, 51002), + new Server("electrum.ltc.xurious.com", Server.ConnectionType.TCP, 51001), + new Server("electrum.ltc.xurious.com", Server.ConnectionType.SSL, 51002) + ); } @Override @@ -106,8 +106,9 @@ public class Litecoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("localhost", Server.ConnectionType.TCP, 50001), - new Server("localhost", Server.ConnectionType.SSL, 50002)); + new Server("localhost", Server.ConnectionType.TCP, 50001), + new Server("localhost", Server.ConnectionType.SSL, 50002) + ); } @Override diff --git a/src/main/java/org/qortal/crosschain/PirateChain.java b/src/main/java/org/qortal/crosschain/PirateChain.java index a1d31a4e..4881c8bb 100644 --- a/src/main/java/org/qortal/crosschain/PirateChain.java +++ b/src/main/java/org/qortal/crosschain/PirateChain.java @@ -56,11 +56,14 @@ public class PirateChain extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - // Servers chosen on NO BASIS WHATSOEVER from various sources! - new Server("wallet-arrr1.qortal.online", ConnectionType.SSL, 443), - new Server("wallet-arrr2.qortal.online", ConnectionType.SSL, 443), - new Server("wallet-arrr3.qortal.online", ConnectionType.SSL, 443), - new Server("lightd.pirate.black", ConnectionType.SSL, 443)); + // Servers chosen on NO BASIS WHATSOEVER from various sources! + new Server("wallet-arrr1.qortal.online", Server.ConnectionType.SSL, 443), + new Server("wallet-arrr2.qortal.online", Server.ConnectionType.SSL, 443), + new Server("wallet-arrr3.qortal.online", Server.ConnectionType.SSL, 443), + new Server("wallet-arrr4.qortal.online", Server.ConnectionType.SSL, 443), + new Server("wallet-arrr5.qortal.online", Server.ConnectionType.SSL, 443), + new Server("lightd.pirate.black", Server.ConnectionType.SSL, 443) + ); } @Override @@ -104,8 +107,9 @@ public class PirateChain extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("localhost", ConnectionType.TCP, 9067), - new Server("localhost", ConnectionType.SSL, 443)); + new Server("localhost", Server.ConnectionType.TCP, 9067), + new Server("localhost", Server.ConnectionType.SSL, 443) + ); } @Override diff --git a/src/main/java/org/qortal/crosschain/Ravencoin.java b/src/main/java/org/qortal/crosschain/Ravencoin.java index 6030fa50..51b65f68 100644 --- a/src/main/java/org/qortal/crosschain/Ravencoin.java +++ b/src/main/java/org/qortal/crosschain/Ravencoin.java @@ -43,19 +43,19 @@ public class Ravencoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - // Servers chosen on NO BASIS WHATSOEVER from various sources! - // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=rvn - //CLOSED new Server("aethyn.com", ConnectionType.SSL, 50002), - //CLOSED new Server("electrum2.rvn.rocks", ConnectionType.SSL, 50002), - //BEHIND new Server("electrum3.rvn.rocks", ConnectionType.SSL, 50002), - new Server("electrum.qortal.link", Server.ConnectionType.SSL, 56002), - new Server("electrum-rvn.qortal.online", ConnectionType.SSL, 50002), - new Server("electrum1-rvn.qortal.online", ConnectionType.SSL, 50002), - new Server("electrum1.cipig.net", ConnectionType.SSL, 20051), - new Server("electrum2.cipig.net", ConnectionType.SSL, 20051), - new Server("electrum3.cipig.net", ConnectionType.SSL, 20051), - new Server("rvn-dashboard.com", ConnectionType.SSL, 50002), - new Server("rvn4lyfe.com", ConnectionType.SSL, 50002)); + // Servers chosen on NO BASIS WHATSOEVER from various sources! + // Status verified at https://1209k.com/bitcoin-eye/ele.php?chain=rvn + new Server("electrum.qortal.link", Server.ConnectionType.SSL, 56002), + new Server("electrum1-rvn.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum2-rvn.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum3-rvn.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum4-rvn.qortal.online", Server.ConnectionType.SSL, 50002), + new Server("electrum1.cipig.net", Server.ConnectionType.SSL, 20051), + new Server("electrum2.cipig.net", Server.ConnectionType.SSL, 20051), + new Server("electrum3.cipig.net", Server.ConnectionType.SSL, 20051), + new Server("rvn-dashboard.com", Server.ConnectionType.SSL, 50002), + new Server("rvn4lyfe.com", Server.ConnectionType.SSL, 50002) + ); } @Override @@ -99,8 +99,9 @@ public class Ravencoin extends Bitcoiny { @Override public Collection getServers() { return Arrays.asList( - new Server("localhost", ConnectionType.TCP, 50001), - new Server("localhost", ConnectionType.SSL, 50002)); + new Server("localhost", Server.ConnectionType.TCP, 50001), + new Server("localhost", Server.ConnectionType.SSL, 50002) + ); } @Override From 9454031b488fbe451f0aa2dfbc80ce1ce08716c1 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 22 Sep 2023 13:06:03 +0100 Subject: [PATCH 48/74] Added support for thread limits. Default thread limits per message type can be specified in Settings.setAdditionalDefaults(), e.g maxThreadsPerMessageType.add(new ThreadLimit("GET_ARBITRARY_DATA_FILE", 5)); These can also be overridden on a per-node basis in settings.json, e.g "maxThreadsPerMessageType": [ { "messageType": "GET_ARBITRARY_DATA_FILE", "limit": 3 }, { "messageType": "GET_ARBITRARY_DATA_FILE_LIST", "limit": 3 } ] settings.json values take priority, but any message types that aren't specified in settings.json will still be included from the Settings.java defaults. This allows single message types to be overridden in settings.json without removing the limits for all of the other message types. Any messages that arrive are discarded if the node is already at the thread limit for that message type. Warnings are now shown in the logs if the total number of active threads reaches 90% of the allocated thread pool size. Additionally, it can warn per message type by specifying a per-message-type warning threshold in settings.json, e.g "threadCountPerMessageTypeWarningThreshold": 20 The above setting would warn in the logs if a single message type was consuming more than 20 threads at once, therefore making it a candidate to be limited in maxThreadsPerMessageType. Initial values of maxThreadsPerMessageType are guesses and may need modifying based on real world results. Limiting threads may impact functionality, so this should be carefully tested. Also be aware that the thread tracking may reduce network performance slightly, so be sure to test thoroughly on slower hardware. --- src/main/java/org/qortal/network/Network.java | 67 +++++++++++++- .../java/org/qortal/settings/Settings.java | 88 +++++++++++++++++++ 2 files changed, 154 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/network/Network.java b/src/main/java/org/qortal/network/Network.java index a3528a66..b42ab450 100644 --- a/src/main/java/org/qortal/network/Network.java +++ b/src/main/java/org/qortal/network/Network.java @@ -8,7 +8,6 @@ import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.qortal.block.BlockChain; import org.qortal.controller.Controller; import org.qortal.controller.arbitrary.ArbitraryDataFileListManager; -import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.crypto.Crypto; import org.qortal.data.block.BlockData; import org.qortal.data.block.BlockSummaryData; @@ -122,6 +121,22 @@ public class Network { private List immutableOutboundHandshakedPeers = Collections.emptyList(); // always rebuilt from mutable, synced list above + /** + * Count threads per message type in order to enforce limits + */ + private final Map threadsPerMessageType = Collections.synchronizedMap(new HashMap<>()); + + /** + * Keep track of total thread count, to warn when the thread pool is getting low + */ + private int totalThreadCount = 0; + + /** + * Thresholds at which to warn about the number of active threads + */ + private final int threadCountWarningThreshold = (int) (Settings.getInstance().getMaxNetworkThreadPoolSize() * 0.9f); + private final Integer threadCountPerMessageTypeWarningThreshold = Settings.getInstance().getThreadCountPerMessageTypeWarningThreshold(); + private final List selfPeers = new ArrayList<>(); private String bindAddress = null; @@ -240,6 +255,16 @@ public class Network { private static final Network INSTANCE = new Network(); } + public Map getThreadsPerMessageType() { + return this.threadsPerMessageType; + } + + public int getTotalThreadCount() { + synchronized (this) { + return this.totalThreadCount; + } + } + public static Network getInstance() { return SingletonContainer.INSTANCE; } @@ -952,6 +977,37 @@ public class Network { // Should be non-handshaking messages from now on + // Limit threads per message type and discard if there are already too many + Integer maxThreadsForMessageType = Settings.getInstance().getMaxThreadsForMessageType(message.getType()); + if (maxThreadsForMessageType != null) { + Integer threadCount = threadsPerMessageType.get(message.getType()); + if (threadCount != null && threadCount >= maxThreadsForMessageType) { + LOGGER.trace("Discarding {} message as there are already {} active threads", message.getType().name(), threadCount); + return; + } + } + + // Warn if necessary + if (threadCountPerMessageTypeWarningThreshold != null) { + Integer threadCount = threadsPerMessageType.get(message.getType()); + if (threadCount != null && threadCount > threadCountPerMessageTypeWarningThreshold) { + LOGGER.info("Warning: high thread count for {} message type: {}", message.getType().name(), threadCount); + } + } + + // Add to per-message thread count (first initializing to 0 if not already present) + threadsPerMessageType.computeIfAbsent(message.getType(), key -> 0); + threadsPerMessageType.computeIfPresent(message.getType(), (key, value) -> value + 1); + + // Add to total thread count + synchronized (this) { + totalThreadCount++; + + if (totalThreadCount >= threadCountWarningThreshold) { + LOGGER.info("Warning: high total thread count: {} / {}", totalThreadCount, Settings.getInstance().getMaxNetworkThreadPoolSize()); + } + } + // Ordered by message type value switch (message.getType()) { case GET_PEERS: @@ -979,6 +1035,15 @@ public class Network { Controller.getInstance().onNetworkMessage(peer, message); break; } + + // Remove from per-message thread count (first initializing to 0 if not already present) + threadsPerMessageType.computeIfAbsent(message.getType(), key -> 0); + threadsPerMessageType.computeIfPresent(message.getType(), (key, value) -> value - 1); + + // Remove from total thread count + synchronized (this) { + totalThreadCount--; + } } private void onHandshakingMessage(Peer peer, Message message, Handshake handshakeStatus) { diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index bdff9506..9d25e846 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -29,6 +29,7 @@ import org.qortal.crosschain.Dogecoin.DogecoinNet; import org.qortal.crosschain.Digibyte.DigibyteNet; import org.qortal.crosschain.Ravencoin.RavencoinNet; import org.qortal.crosschain.PirateChain.PirateChainNet; +import org.qortal.network.message.MessageType; import org.qortal.utils.EnumUtils; // All properties to be converted to JSON via JAXB @@ -371,6 +372,58 @@ public class Settings { /** Whether to serve QDN data without authentication */ private boolean qdnAuthBypassEnabled = true; + /** Limit threads per message type */ + private Set maxThreadsPerMessageType = new HashSet<>(); + + /** The number of threads per message type at which a warning should be logged. + * Exclude from settings.json to disable this warning. */ + private Integer threadCountPerMessageTypeWarningThreshold = null; + + + // Domain mapping + public static class ThreadLimit { + private String messageType; + private Integer limit; + + private ThreadLimit() { // makes JAXB happy; will never be invoked + } + + private ThreadLimit(String messageType, Integer limit) { + this.messageType = messageType; + this.limit = limit; + } + + public String getMessageType() { + return messageType; + } + + public void setMessageType(String messageType) { + this.messageType = messageType; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ThreadLimit)) + return false; + + return this.messageType.equals(((ThreadLimit) other).getMessageType()); + } + + @Override + public int hashCode() { + return Objects.hash(messageType); + } + } + + // Domain mapping public static class DomainMap { private String domain; @@ -497,6 +550,9 @@ public class Settings { } } while (settings.userPath != null); + // Set some additional defaults if needed + settings.setAdditionalDefaults(); + // Validate settings settings.validate(); @@ -533,6 +589,22 @@ public class Settings { } } + private void setAdditionalDefaults() { + // Populate defaults for maxThreadsPerMessageType. If any are specified in settings.json, they will take priority. + maxThreadsPerMessageType.add(new ThreadLimit("ARBITRARY_DATA_FILE", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("GET_ARBITRARY_DATA_FILE", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("ARBITRARY_DATA", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("GET_ARBITRARY_DATA", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("ARBITRARY_DATA_FILE_LIST", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("GET_ARBITRARY_DATA_FILE_LIST", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("ARBITRARY_SIGNATURES", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("ARBITRARY_METADATA", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("GET_ARBITRARY_METADATA", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("GET_TRANSACTION", 10)); + maxThreadsPerMessageType.add(new ThreadLimit("TRANSACTION_SIGNATURES", 5)); + maxThreadsPerMessageType.add(new ThreadLimit("TRADE_PRESENCES", 5)); + } + // Getters / setters public String getUserPath() { @@ -1054,4 +1126,20 @@ public class Settings { } return this.qdnAuthBypassEnabled; } + + public Integer getMaxThreadsForMessageType(MessageType messageType) { + if (maxThreadsPerMessageType != null) { + for (ThreadLimit threadLimit : maxThreadsPerMessageType) { + if (threadLimit.getMessageType().equals(messageType.name())) { + return threadLimit.getLimit(); + } + } + } + // No entry, so assume unlimited + return null; + } + + public Integer getThreadCountPerMessageTypeWarningThreshold() { + return this.threadCountPerMessageTypeWarningThreshold; + } } From bf270a63ff06ec0f18ee0522f8668a9a99a14899 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 24 Sep 2023 15:19:07 +0200 Subject: [PATCH 49/74] Update bouncycastle --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 29b7ac58..621c96ae 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ true 7dc8c6f 0.15.10 - 1.69 + 1.70 ${maven.build.timestamp} 1.4.1 3.8.0 From 499e2ac3f4d9e103da015bac1d848e8f9e9d67cd Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 10 Oct 2023 23:24:57 +0200 Subject: [PATCH 50/74] hide-failed-trade --- src/main/java/org/qortal/controller/tradebot/TradeBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/controller/tradebot/TradeBot.java b/src/main/java/org/qortal/controller/tradebot/TradeBot.java index 147554dd..c8bc0eba 100644 --- a/src/main/java/org/qortal/controller/tradebot/TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/TradeBot.java @@ -712,7 +712,7 @@ public class TradeBot implements Listener { } try { - List signatures = repository.getTransactionRepository().getSignaturesMatchingCriteria(null, null, null, Arrays.asList(Transaction.TransactionType.MESSAGE), null, null, crossChainTradeData.qortalCreatorTradeAddress, TransactionsResource.ConfirmationStatus.CONFIRMED, null, null, null); + List signatures = repository.getTransactionRepository().getSignaturesMatchingCriteria(null, null, null, Arrays.asList(Transaction.TransactionType.MESSAGE), null, null, crossChainTradeData.qortalCreatorTradeAddress, TransactionsResource.ConfirmationStatus.BOTH, null, null, null); if (signatures.size() < getMaxTradeOfferAttempts) { // Less than 3 (or user-specified number of) MESSAGE transactions relate to this trade, so assume it is ok validTrades.put(crossChainTradeData.qortalAtAddress, now); From 6d202b2b48e17bf5f59e95e7aab8b4f4eaeed4c9 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Thu, 12 Oct 2023 11:23:36 +0200 Subject: [PATCH 51/74] Create settings.json --- .vscode/settings.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..7b016a89 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "automatic" +} \ No newline at end of file From db7b17e52e4192d33d017995a276d1b4e628227f Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:57:43 +0200 Subject: [PATCH 52/74] Revert HSQLDB update --- pom.xml | 4 ++-- .../hsqldb/HSQLDBDatabaseUpdates.java | 23 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 621c96ae..b7e27464 100644 --- a/pom.xml +++ b/pom.xml @@ -20,12 +20,12 @@ 1.9 1.2.2 32.1.2-jre - 2.7.2 + 2.5.1 1.2.1 73.2 1.1 2.29.1 - 9.4.52.v20230823 + 9.4.53.v20231009 2.20.0 UTF-8 1.7.36 diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index c2e9cd62..8763961d 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -454,40 +454,40 @@ public class HSQLDBDatabaseUpdates { case 12: // Groups - stmt.execute("CREATE TABLE `Groups` (group_id GroupID, owner QortalAddress NOT NULL, group_name GroupName NOT NULL, " + stmt.execute("CREATE TABLE Groups (group_id GroupID, owner QortalAddress NOT NULL, group_name GroupName NOT NULL, " + "created_when EpochMillis NOT NULL, updated_when EpochMillis, is_open BOOLEAN NOT NULL, " + "approval_threshold TINYINT NOT NULL, min_block_delay INTEGER NOT NULL, max_block_delay INTEGER NOT NULL, " + "reference Signature, creation_group_id GroupID, reduced_group_name GroupName NOT NULL, " + "description GenericDescription NOT NULL, PRIMARY KEY (group_id))"); // For finding groups by name - stmt.execute("CREATE INDEX GroupNameIndex on `Groups` (group_name)"); + stmt.execute("CREATE INDEX GroupNameIndex on Groups (group_name)"); // For finding groups by reduced name - stmt.execute("CREATE INDEX GroupReducedNameIndex on `Groups` (reduced_group_name)"); + stmt.execute("CREATE INDEX GroupReducedNameIndex on Groups (reduced_group_name)"); // For finding groups by owner - stmt.execute("CREATE INDEX GroupOwnerIndex ON `Groups` (owner)"); + stmt.execute("CREATE INDEX GroupOwnerIndex ON Groups (owner)"); // We need a corresponding trigger to make sure new group_id values are assigned sequentially starting from 1 - stmt.execute("CREATE TRIGGER Group_ID_Trigger BEFORE INSERT ON `Groups` " + stmt.execute("CREATE TRIGGER Group_ID_Trigger BEFORE INSERT ON Groups " + "REFERENCING NEW ROW AS new_row FOR EACH ROW WHEN (new_row.group_id IS NULL) " - + "SET new_row.group_id = (SELECT IFNULL(MAX(group_id) + 1, 1) FROM `Groups`)"); + + "SET new_row.group_id = (SELECT IFNULL(MAX(group_id) + 1, 1) FROM Groups)"); // Admins stmt.execute("CREATE TABLE GroupAdmins (group_id GroupID, admin QortalAddress, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, admin), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, admin), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); // For finding groups by admin address stmt.execute("CREATE INDEX GroupAdminIndex ON GroupAdmins (admin)"); // Members stmt.execute("CREATE TABLE GroupMembers (group_id GroupID, address QortalAddress, " + "joined_when EpochMillis NOT NULL, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, address), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, address), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); // For finding groups by member address stmt.execute("CREATE INDEX GroupMemberIndex ON GroupMembers (address)"); // Invites stmt.execute("CREATE TABLE GroupInvites (group_id GroupID, inviter QortalAddress, invitee QortalAddress, " + "expires_when EpochMillis, reference Signature, " - + "PRIMARY KEY (group_id, invitee), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, invitee), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); // For finding invites sent by inviter stmt.execute("CREATE INDEX GroupInviteInviterIndex ON GroupInvites (inviter)"); // For finding invites by group @@ -503,7 +503,7 @@ public class HSQLDBDatabaseUpdates { // NULL expires_when means does not expire! stmt.execute("CREATE TABLE GroupBans (group_id GroupID, offender QortalAddress, admin QortalAddress NOT NULL, " + "banned_when EpochMillis NOT NULL, reason GenericDescription NOT NULL, expires_when EpochMillis, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, offender), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, offender), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); // For expiry maintenance stmt.execute("CREATE INDEX GroupBanExpiryIndex ON GroupBans (expires_when)"); break; @@ -1014,5 +1014,4 @@ public class HSQLDBDatabaseUpdates { LOGGER.info(() -> String.format("HSQLDB repository updated to version %d", databaseVersion + 1)); return true; } - -} +} \ No newline at end of file From 404c5d03009aaaa58d7f78f730ebd712d8981686 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 15 Oct 2023 17:12:02 +0200 Subject: [PATCH 53/74] Filter failed trade after 1 attempt --- .../qortal/controller/tradebot/TradeBot.java | 32 ++++++------------- .../data/transaction/TransactionData.java | 12 +++++-- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/qortal/controller/tradebot/TradeBot.java b/src/main/java/org/qortal/controller/tradebot/TradeBot.java index c8bc0eba..e17f642f 100644 --- a/src/main/java/org/qortal/controller/tradebot/TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/TradeBot.java @@ -712,30 +712,16 @@ public class TradeBot implements Listener { } try { - List signatures = repository.getTransactionRepository().getSignaturesMatchingCriteria(null, null, null, Arrays.asList(Transaction.TransactionType.MESSAGE), null, null, crossChainTradeData.qortalCreatorTradeAddress, TransactionsResource.ConfirmationStatus.BOTH, null, null, null); - if (signatures.size() < getMaxTradeOfferAttempts) { - // Less than 3 (or user-specified number of) MESSAGE transactions relate to this trade, so assume it is ok - validTrades.put(crossChainTradeData.qortalAtAddress, now); - continue; - } + List transactions = repository.getTransactionRepository().getUnconfirmedTransactions(Arrays.asList(Transaction.TransactionType.MESSAGE), null, null, null, null); - List transactions = new ArrayList<>(signatures.size()); - for (byte[] signature : signatures) { - transactions.add(repository.getTransactionRepository().fromSignature(signature)); - } - transactions.sort(Transaction.getDataComparator()); - - // Get timestamp of the first MESSAGE transaction - long firstMessageTimestamp = transactions.get(0).getTimestamp(); - - // Treat as failed if first buy attempt was more than 60 mins ago (as it's still in the OFFERING state) - boolean isFailed = (now - firstMessageTimestamp > 60*60*1000L); - if (isFailed) { - failedTrades.put(crossChainTradeData.qortalAtAddress, now); - updatedCrossChainTrades.remove(crossChainTradeData); - } - else { - validTrades.put(crossChainTradeData.qortalAtAddress, now); + for (TransactionData transactionData : transactions) { + // Treat as failed if buy attempt was more than 60 mins ago (as it's still in the OFFERING state) + if (transactionData.getRecipient().equals(crossChainTradeData.qortalCreatorTradeAddress) && now - transactionData.getTimestamp() > 60*60*1000L) { + failedTrades.put(crossChainTradeData.qortalAtAddress, now); + updatedCrossChainTrades.remove(crossChainTradeData); + } else { + validTrades.put(crossChainTradeData.qortalAtAddress, now); + } } } catch (DataException e) { diff --git a/src/main/java/org/qortal/data/transaction/TransactionData.java b/src/main/java/org/qortal/data/transaction/TransactionData.java index c4a115df..21628bb9 100644 --- a/src/main/java/org/qortal/data/transaction/TransactionData.java +++ b/src/main/java/org/qortal/data/transaction/TransactionData.java @@ -75,6 +75,9 @@ public abstract class TransactionData { @Schema(description = "groupID for this transaction") protected int txGroupId; + @Schema(description = "recipient for this transaction") + protected String recipient; + // Not always present @Schema(accessMode = AccessMode.READ_ONLY, hidden = true, description = "height of block containing transaction") protected Integer blockHeight; @@ -105,7 +108,7 @@ public abstract class TransactionData { /** Constructor for use by transaction subclasses. */ protected TransactionData(TransactionType type, BaseTransactionData baseTransactionData) { this.type = type; - + this.recipient = baseTransactionData.recipient; this.timestamp = baseTransactionData.timestamp; this.txGroupId = baseTransactionData.txGroupId; this.reference = baseTransactionData.reference; @@ -136,6 +139,10 @@ public abstract class TransactionData { return this.txGroupId; } + public String getRecipient() { + return this.recipient; + } + public void setTxGroupId(int txGroupId) { this.txGroupId = txGroupId; } @@ -250,5 +257,4 @@ public abstract class TransactionData { return Arrays.equals(this.signature, otherTransactionData.signature); } - -} +} \ No newline at end of file From 2af8199d9cc4486fcb1dda2532c2c990b4b5539c Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:27:14 +0200 Subject: [PATCH 54/74] Update dependencies --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index b7e27464..c8351bfe 100644 --- a/pom.xml +++ b/pom.xml @@ -14,12 +14,12 @@ 1.4.1 3.8.0 1.10.0 - 2.13.0 + 2.14.0 1.24.0 3.13.0 1.9 1.2.2 - 32.1.2-jre + 32.1.3-jre 2.5.1 1.2.1 73.2 @@ -35,7 +35,7 @@ 1.16.1 4.12 1.58.0 - 3.24.3 + 3.24.4 1.17 @@ -51,7 +51,7 @@ org.codehaus.mojo versions-maven-plugin - 2.16.0 + 2.16.1 false @@ -270,7 +270,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.0 + 3.5.1 false @@ -466,7 +466,7 @@ org.json json - 20230618 + 20231013 org.apache.commons From 2d599ec3c53f746731412af760fbf81b992e7627 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:39:17 +0200 Subject: [PATCH 55/74] Summary of activity past 24 hours --- .../restricted/resource/AdminResource.java | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/qortal/api/restricted/resource/AdminResource.java b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java index ecb8c6c9..178d7547 100644 --- a/src/main/java/org/qortal/api/restricted/resource/AdminResource.java +++ b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java @@ -16,11 +16,6 @@ import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.file.Files; import java.nio.file.Paths; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -38,7 +33,6 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.RollingFileAppender; import org.json.JSONArray; -import org.json.JSONObject; import org.qortal.account.Account; import org.qortal.account.PrivateKeyAccount; import org.qortal.api.*; @@ -269,7 +263,7 @@ public class AdminResource { @GET @Path("/summary") @Operation( - summary = "Summary of activity since midnight, UTC", + summary = "Summary of activity past 24 hours", responses = { @ApiResponse( content = @Content(schema = @Schema(implementation = ActivitySummary.class)) @@ -282,23 +276,21 @@ public class AdminResource { Security.checkApiCallAllowed(request); ActivitySummary summary = new ActivitySummary(); - - LocalDate date = LocalDate.now(); - LocalTime time = LocalTime.of(0, 0); - ZoneOffset offset = ZoneOffset.UTC; - long start = OffsetDateTime.of(date, time, offset).toInstant().toEpochMilli(); + + long now = NTP.getTime(); + long oneday = now - 24 * 60 * 60 * 1000L; try (final Repository repository = RepositoryManager.getRepository()) { - int startHeight = repository.getBlockRepository().getHeightFromTimestamp(start); + int startHeight = repository.getBlockRepository().getHeightFromTimestamp(oneday); int endHeight = repository.getBlockRepository().getBlockchainHeight(); summary.setBlockCount(endHeight - startHeight); summary.setTransactionCountByType(repository.getTransactionRepository().getTransactionSummary(startHeight + 1, endHeight)); - summary.setAssetsIssued(repository.getAssetRepository().getRecentAssetIds(start).size()); + summary.setAssetsIssued(repository.getAssetRepository().getRecentAssetIds(oneday).size()); - summary.setNamesRegistered (repository.getNameRepository().getRecentNames(start).size()); + summary.setNamesRegistered (repository.getNameRepository().getRecentNames(oneday).size()); return summary; } catch (DataException e) { From 7103f41e36eb815410fd47ec8364a821c0b149a5 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:49:53 +0200 Subject: [PATCH 56/74] Reorg pom update dependencies --- pom.xml | 76 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index c8351bfe..6cc84d15 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ 1.4.1 3.8.0 1.10.0 - 2.14.0 + 2.11.0 1.24.0 3.13.0 1.9 @@ -24,19 +24,39 @@ 1.2.1 73.2 1.1 - 2.29.1 + 2.3.3 + 2.40 9.4.53.v20231009 2.20.0 UTF-8 1.7.36 2.0.10 - 3.23.11 + 3.52.5 1.1.0 1.16.1 4.12 1.58.0 3.24.4 1.17 + 2.16.1 + 3.11.0 + 4.9.10 + 1.5.3 + 3.3.1 + 3.4.0 + 3.3.0 + 3.5.1 + 0.16 + 3.1.2 + 1.0.0 + 3.4.0 + 1.1.1 + 20231013 + 0.12.3 + 4.0.1 + 1.5.0-b01 + 5.3.1 + 1.3 src/main/java @@ -51,14 +71,14 @@ org.codehaus.mojo versions-maven-plugin - 2.16.1 + ${versions-maven-plugin.version} false maven-compiler-plugin - 3.11.0 + ${maven-compiler-plugin.version} 11 @@ -89,7 +109,7 @@ pl.project13.maven git-commit-id-plugin - 4.9.10 + ${git-commit-id-plugin.version} get-the-git-infos @@ -121,7 +141,7 @@ com.google.code.maven-replacer-plugin replacer - 1.5.3 + ${replacer.version} replace-swagger-ui @@ -180,7 +200,10 @@ maven-resources-plugin - 3.1.0 + ${maven-resources-plugin.version} + + ISO-8859-1 + copy-resources @@ -234,7 +257,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.4.0 + ${build-helper-maven-plugin.version} generate-sources @@ -252,7 +275,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + ${maven-jar-plugin.version} @@ -270,13 +293,12 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.1 + ${maven-shade-plugin.version} false - + org.webjars:swagger-ui junit:junit @@ -320,7 +342,7 @@ io.github.zlika reproducible-build-maven-plugin - 0.16 + ${reproducible-build-maven-plugin.version} package @@ -337,7 +359,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.1.2 + ${maven-surefire-plugin.version} ${skipTests} @@ -349,7 +371,7 @@ org.eclipse.m2e lifecycle-mapping - 1.0.0 + ${lifecycle-mapping.version} @@ -415,7 +437,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.4.0 + ${build-helper-maven-plugin.version} provided @@ -461,12 +483,12 @@ com.googlecode.json-simple json-simple - 1.1.1 + ${json-simple.version} org.json json - 20231013 + ${json.version} org.apache.commons @@ -497,7 +519,7 @@ io.druid extendedset - 0.12.3 + ${extendedset.version} @@ -568,12 +590,12 @@ javax.servlet javax.servlet-api - 4.0.1 + ${javax.servlet-api.version} javax.mail mail - 1.5.0-b01 + ${mail.version} @@ -687,12 +709,12 @@ org.junit.jupiter junit-jupiter-engine - 5.3.1 + ${junit-jupiter-engine.version} org.hamcrest hamcrest-library - 1.3 + ${hamcrest-library.version} --> @@ -741,5 +763,11 @@ simplemagic ${simplemagic.version} + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + From 5cbd4490cc472390648c6f41777b073b081b8054 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:29:10 +0200 Subject: [PATCH 57/74] Back to Bouncycastle 1.69 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6cc84d15..40d56990 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ true 7dc8c6f 0.15.10 - 1.70 + 1.69 ${maven.build.timestamp} 1.4.1 3.8.0 From 53c3f7899aa9f1e3e9a0102e3b234c16d600867e Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Thu, 19 Oct 2023 13:48:33 -0400 Subject: [PATCH 58/74] Reward share limit activation timestamp set to 1698508800000 (Sat Oct 28 2023 16:00:00 UTC) --- src/main/resources/blockchain.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/blockchain.json b/src/main/resources/blockchain.json index 9a26c99e..760da97c 100644 --- a/src/main/resources/blockchain.json +++ b/src/main/resources/blockchain.json @@ -22,7 +22,8 @@ "maxRewardSharesPerFounderMintingAccount": 6, "maxRewardSharesByTimestamp": [ { "timestamp": 0, "maxShares": 6 }, - { "timestamp": 1657382400000, "maxShares": 3 } + { "timestamp": 1657382400000, "maxShares": 3 }, + { "timestamp": 1698508800000, "maxShares": 2 } ], "founderEffectiveMintingLevel": 10, "onlineAccountSignaturesMinLifetime": 43200000, From 033b6adb7230ec3afefa03f5580feb07cb737056 Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Thu, 19 Oct 2023 13:51:53 -0400 Subject: [PATCH 59/74] Bump version to 4.3.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 40d56990..e623a5dd 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.qortal qortal - 4.3.0 + 4.3.1 jar true From 6525cac66c113f30da2aa495bc4343d34e2d2185 Mon Sep 17 00:00:00 2001 From: karl-dv <38753527+karl-dv@users.noreply.github.com> Date: Sat, 28 Oct 2023 09:11:08 +0200 Subject: [PATCH 60/74] Manual review of "nl" translations --- .../resources/i18n/ApiError_nl.properties | 40 +++++----- src/main/resources/i18n/SysTray_nl.properties | 18 ++--- .../i18n/TransactionValidity_nl.properties | 76 +++++++++---------- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/main/resources/i18n/ApiError_nl.properties b/src/main/resources/i18n/ApiError_nl.properties index 0501fe9a..8c8a3b09 100644 --- a/src/main/resources/i18n/ApiError_nl.properties +++ b/src/main/resources/i18n/ApiError_nl.properties @@ -4,36 +4,36 @@ # "localeLang": "nl", ### Common ### -JSON = lezen van JSON bericht gefaald +JSON = lezen van JSON bericht is mislukt -INSUFFICIENT_BALANCE = insufficient balance +INSUFFICIENT_BALANCE = onvoldoende saldo UNAUTHORIZED = ongeautoriseerde API call -REPOSITORY_ISSUE = repository fout +REPOSITORY_ISSUE = fout in repository NON_PRODUCTION = deze API call is niet toegestaan voor productiesystemen -BLOCKCHAIN_NEEDS_SYNC = blockchain dient eerst gesynchronizeerd te worden +BLOCKCHAIN_NEEDS_SYNC = blockchain dient eerst te synchronizeren -NO_TIME_SYNC = klok nog niet gesynchronizeerd +NO_TIME_SYNC = klok is nog niet gesynchronizeerd ### Validation ### -INVALID_SIGNATURE = ongeldige handtekening +INVALID_SIGNATURE = ongeldige signature INVALID_ADDRESS = ongeldig adres INVALID_PUBLIC_KEY = ongeldige public key -INVALID_DATA = ongeldige gegevens +INVALID_DATA = ongeldige data INVALID_NETWORK_ADDRESS = ongeldig netwerkadres -ADDRESS_UNKNOWN = account adres onbekend +ADDRESS_UNKNOWN = account-adres onbekend INVALID_CRITERIA = ongeldige zoekcriteria -INVALID_REFERENCE = ongeldige verwijzing +INVALID_REFERENCE = ongeldige referentie TRANSFORMATION_ERROR = JSON kon niet omgezet worden in transactie @@ -44,10 +44,10 @@ INVALID_HEIGHT = ongeldige blokhoogte CANNOT_MINT = account kan niet minten ### Blocks ### -BLOCK_UNKNOWN = blok onbekend +BLOCK_UNKNOWN = blok niet gekend ### Transactions ### -TRANSACTION_UNKNOWN = onbekende transactie +TRANSACTION_UNKNOWN = transactie niet gekend PUBLIC_KEY_NOT_FOUND = public key niet gevonden @@ -55,29 +55,29 @@ PUBLIC_KEY_NOT_FOUND = public key niet gevonden TRANSACTION_INVALID = ongeldige transactie: %s (%s) ### Naming ### -NAME_UNKNOWN = onbekende naam +NAME_UNKNOWN = naam niet gekend ### Asset ### INVALID_ASSET_ID = ongeldige asset ID INVALID_ORDER_ID = ongeldige asset order ID -ORDER_UNKNOWN = onbekende asset order ID +ORDER_UNKNOWN = niet gekende asset order ID ### Groups ### -GROUP_UNKNOWN = onbekende groep +GROUP_UNKNOWN = groep niet gekend ### Foreign Blockchain ### -FOREIGN_BLOCKCHAIN_NETWORK_ISSUE = blockchain of ElectrumX network probleem +FOREIGN_BLOCKCHAIN_NETWORK_ISSUE = vreemde blockchain of ElectrumX networkprobleem -FOREIGN_BLOCKCHAIN_BALANCE_ISSUE = onvoldoende saldo blockchain +FOREIGN_BLOCKCHAIN_BALANCE_ISSUE = onvoldoende saldo bij vreemde blockchain -FOREIGN_BLOCKCHAIN_TOO_SOON = nog niet gereed om de blockchain transactie uittevoeren (LockTime/median block time) +FOREIGN_BLOCKCHAIN_TOO_SOON = te vroeg om de blockchain transactie uit te sturen (LockTime/median block time) ### Trade Portal ### -ORDER_SIZE_TOO_SMALL = order bedrag te laag +ORDER_SIZE_TOO_SMALL = order-bedrag te laag ### Data ### -FILE_NOT_FOUND = file niet gevonden +FILE_NOT_FOUND = bestand niet gevonden -NO_REPLY = peer reageerd niet met data +NO_REPLY = peer reageerde niet binnen toegelaten tijd diff --git a/src/main/resources/i18n/SysTray_nl.properties b/src/main/resources/i18n/SysTray_nl.properties index c2acb7ce..3d7de024 100644 --- a/src/main/resources/i18n/SysTray_nl.properties +++ b/src/main/resources/i18n/SysTray_nl.properties @@ -1,17 +1,17 @@ #Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/) # SysTray pop-up menu -APPLYING_UPDATE_AND_RESTARTING = Automatische update en herstart worden uitgevoerd... +APPLYING_UPDATE_AND_RESTARTING = Bezig met automatische update en herstart... AUTO_UPDATE = Automatische Update -BLOCK_HEIGHT = Block hoogte +BLOCK_HEIGHT = blok-hoogte -BLOCKS_REMAINING = blocks remaining +BLOCKS_REMAINING = overblijvende blokken -BUILD_VERSION = Versie nummer +BUILD_VERSION = Versienummer -CHECK_TIME_ACCURACY = Controleer accuraatheid van de tijd +CHECK_TIME_ACCURACY = Controleer of de tijd correct is CONNECTING = Verbinden @@ -33,16 +33,16 @@ LITE_NODE = Lite node MINTING_DISABLED = Minten is uitgeschakeld -MINTING_ENABLED = \u2714 Minten is ingeschakeld +MINTING_ENABLED = \u2714 Minten is actief OPEN_UI = Open UI -PERFORMING_DB_CHECKPOINT = De database wordt gecontroleerd... +PERFORMING_DB_CHECKPOINT = De database wordt bijgewerkt... -PERFORMING_DB_MAINTENANCE = Uitvoeren van gepland onderhoud... +PERFORMING_DB_MAINTENANCE = Bezig met gepland onderhoud... SYNCHRONIZE_CLOCK = Synchronizeer klok -SYNCHRONIZING_BLOCKCHAIN = Aan het synchronizeren +SYNCHRONIZING_BLOCKCHAIN = Bezig met synchronizeren SYNCHRONIZING_CLOCK = Klok wordt gesynchronizeerd diff --git a/src/main/resources/i18n/TransactionValidity_nl.properties b/src/main/resources/i18n/TransactionValidity_nl.properties index 36b0fec9..f92adf72 100644 --- a/src/main/resources/i18n/TransactionValidity_nl.properties +++ b/src/main/resources/i18n/TransactionValidity_nl.properties @@ -1,28 +1,28 @@ # -ACCOUNT_ALREADY_EXISTS = account bestaat al +ACCOUNT_ALREADY_EXISTS = account bestaat reeds ACCOUNT_CANNOT_REWARD_SHARE = account kan geen beloningen delen -ADDRESS_ABOVE_RATE_LIMIT = adres heeft een waarde limiet bereikt +ADDRESS_ABOVE_RATE_LIMIT = adres heeft opgegeven limietwaarde bereikt -ADDRESS_BLOCKED = adres is geblokkeerd +ADDRESS_BLOCKED = dit adres is geblokkeerd -ALREADY_GROUP_ADMIN = groeps administrator bestaat al +ALREADY_GROUP_ADMIN = reeds gekend als groepsadministrator -ALREADY_GROUP_MEMBER = groeps lid bestaat al +ALREADY_GROUP_MEMBER = reeds gekend als groepslid ALREADY_VOTED_FOR_THAT_OPTION = reeds gestemd voor die optie -ASSET_ALREADY_EXISTS = asset bestaat al +ASSET_ALREADY_EXISTS = asset bestaat reeds ASSET_DOES_NOT_EXIST = asset bestaat niet ASSET_DOES_NOT_MATCH_AT = asset komt niet overeen met de asset van de AT -ASSET_NOT_SPENDABLE = asset is niet toerijkend +ASSET_NOT_SPENDABLE = asset kan niet uitbetaald worden -AT_ALREADY_EXISTS = AT bestaat al +AT_ALREADY_EXISTS = AT bestaat reeds AT_IS_FINISHED = AT is afgelopen @@ -38,25 +38,25 @@ BUYER_ALREADY_OWNER = koper is al de eigenaar CLOCK_NOT_SYNCED = klok is niet gesynchronizeerd -DUPLICATE_MESSAGE = dubbel adres bericht +DUPLICATE_MESSAGE = adres heeft dubbel bericht verzonden DUPLICATE_OPTION = dubbele optie GROUP_ALREADY_EXISTS = groep bestaat reeds -GROUP_APPROVAL_DECIDED = groeps goedkeuring afgewezen +GROUP_APPROVAL_DECIDED = groeps-goedkeuring afgewezen -GROUP_APPROVAL_NOT_REQUIRED = groeps goedkeuring niet vereist +GROUP_APPROVAL_NOT_REQUIRED = groeps-goedkeuring niet vereist GROUP_DOES_NOT_EXIST = groep bestaat niet GROUP_ID_MISMATCH = groeps ID komt niet overeen -GROUP_OWNER_CANNOT_LEAVE = groep eigenaar kan de groep niet verlaten +GROUP_OWNER_CANNOT_LEAVE = groep-eigenaar kan groep niet verlaten -HAVE_EQUALS_WANT = asset is gelijk aan Want-asset +HAVE_EQUALS_WANT = asset is gelijk aan Wens-asset -INCORRECT_NONCE = incorrecte PoW nonce +INCORRECT_NONCE = foutieve PoW nonce INSUFFICIENT_FEE = vergoeding te laag @@ -72,19 +72,19 @@ INVALID_AT_TYPE_LENGTH = ongeldige lengte voor AT type INVALID_BUT_OK = ongeldig maar is in orde -INVALID_CREATION_BYTES = ongeldige gecreerde bytes +INVALID_CREATION_BYTES = ongeldige creatie-bytes -INVALID_DATA_LENGTH = ongeldige data lengte +INVALID_DATA_LENGTH = ongeldige data-lengte -INVALID_DESCRIPTION_LENGTH = ongeldige lengte voor de beschrijving +INVALID_DESCRIPTION_LENGTH = ongeldige lengte voor beschrijving INVALID_GROUP_APPROVAL_THRESHOLD = ongeldige drempelwaarde voor groepsgoedkeuring -INVALID_GROUP_BLOCK_DELAY = ongeldige groep blok vertraging +INVALID_GROUP_BLOCK_DELAY = ongeldige blok-vertraging bij groepsgoedkeuring INVALID_GROUP_ID = ongeldige groep-ID -INVALID_GROUP_OWNER = ongeldige groep eigenaar +INVALID_GROUP_OWNER = ongeldige groep-eigenaar INVALID_LIFETIME = ongeldige levensduur @@ -94,27 +94,27 @@ INVALID_NAME_OWNER = ongeldige naam voor eigenaar INVALID_OPTION_LENGTH = ongeldige lengte voor opties -INVALID_OPTIONS_COUNT = ongeldige hoeveelheid opties +INVALID_OPTIONS_COUNT = ongeldig aantal opties -INVALID_ORDER_CREATOR = ongeldige gebruiker voor deze order +INVALID_ORDER_CREATOR = ongeldige order-creatie-gebruiker -INVALID_PAYMENTS_COUNT = ongeldige betalings waarde +INVALID_PAYMENTS_COUNT = ongeldig aantal betalingen INVALID_PUBLIC_KEY = ongeldige public key INVALID_QUANTITY = ongeldige hoeveelheid -INVALID_REFERENCE = ongeldige verwijzing +INVALID_REFERENCE = ongeldige referentie -INVALID_RETURN = ongeldige return +INVALID_RETURN = ongeldig resultaat -INVALID_REWARD_SHARE_PERCENT = ongeldig belonings percentage +INVALID_REWARD_SHARE_PERCENT = ongeldig belonings-deelpercentage INVALID_SELLER = ongeldige verkoper INVALID_TAGS_LENGTH = ongeldige lengte voor 'tags' -INVALID_TIMESTAMP_SIGNATURE = ongeldig tijd aanduiding +INVALID_TIMESTAMP_SIGNATURE = ongeldig tijd-aanduiding INVALID_TX_GROUP_ID = ongeldige transactiegroep-ID @@ -124,15 +124,15 @@ INVITE_UNKNOWN = onbekende groepsuitnodiging JOIN_REQUEST_EXISTS = aanvraag om lid van groep te worden bestaat al -MAXIMUM_REWARD_SHARES = limiet aan belonen voor dit account bereikt +MAXIMUM_REWARD_SHARES = maximum bereikt voor beloning-delen voor dit account -MISSING_CREATOR = ontbrekende aanmaker +MISSING_CREATOR = creator niet gekend MULTIPLE_NAMES_FORBIDDEN = het registreren van meerdere namen op een account is niet toegestaan -NAME_ALREADY_FOR_SALE = naam reeds te koop +NAME_ALREADY_FOR_SALE = naam is reeds te koop -NAME_ALREADY_REGISTERED = naam reeds geregistreerd +NAME_ALREADY_REGISTERED = naam is reeds geregistreerd NAME_BLOCKED = deze naam is geblokkeerd @@ -140,7 +140,7 @@ NAME_DOES_NOT_EXIST = naam bestaat niet NAME_NOT_FOR_SALE = naam is niet te koop -NAME_NOT_NORMALIZED = naam voldoet niet aan Unicode-vorm +NAME_NOT_NORMALIZED = naam niet in Unicode-'nomaal'-vorm NEGATIVE_AMOUNT = negatieve hoeveelheid @@ -148,9 +148,9 @@ NEGATIVE_FEE = negatieve vergoeding NEGATIVE_PRICE = negatieve prijs -NO_BALANCE = onvoldoende balans +NO_BALANCE = onvoldoende saldo -NO_BLOCKCHAIN_LOCK = geen blockchain slot +NO_BLOCKCHAIN_LOCK = blockchain op node is momenteel bezet NO_FLAG_PERMISSION = account heeft hier geen toestemming voor @@ -176,9 +176,9 @@ POLL_OPTION_DOES_NOT_EXIST = peilingsoptie bestaat niet PUBLIC_KEY_UNKNOWN = public key onbekend -REWARD_SHARE_UNKNOWN = beloning vergoeding onbekend +REWARD_SHARE_UNKNOWN = beloningsdeel is onbekend -SELF_SHARE_EXISTS = zelf vergoeding bestaat reeds +SELF_SHARE_EXISTS = zelf-beloning (belonings-delen) bestaat reeds TIMESTAMP_TOO_NEW = tijdstempel te nieuw @@ -186,10 +186,10 @@ TIMESTAMP_TOO_OLD = tijdstempel te oud TOO_MANY_UNCONFIRMED = account heeft te veel onbevestigde transacties in afwachting -TRANSACTION_ALREADY_CONFIRMED = transactie is reeds bevestigd +TRANSACTION_ALREADY_CONFIRMED = transactie werd reeds bevestigd -TRANSACTION_ALREADY_EXISTS = transactie bestaat al +TRANSACTION_ALREADY_EXISTS = transactie bestaat reeds TRANSACTION_UNKNOWN = transactie onbekend -TX_GROUP_ID_MISMATCH = groep ID komt niet overeen +TX_GROUP_ID_MISMATCH = groep-ID komt niet overeen From 9b64f12b7affbb6b35b8daa31f75a6d731a6df4c Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Mon, 30 Oct 2023 22:01:48 -0400 Subject: [PATCH 61/74] Default minPeerVersion set to 4.3.1 --- src/main/java/org/qortal/settings/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index 679fe120..babef614 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -226,7 +226,7 @@ public class Settings { public long recoveryModeTimeout = 9999999999999L; /** Minimum peer version number required in order to sync with them */ - private String minPeerVersion = "4.3.0"; + private String minPeerVersion = "4.3.1"; /** Whether to allow connections with peers below minPeerVersion * If true, we won't sync with them but they can still sync with us, and will show in the peers list * If false, sync will be blocked both ways, and they will not appear in the peers list */ From e885a69688b1c79e3f4e93c039c1376b17cb3c35 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:30:28 +0100 Subject: [PATCH 62/74] Fix status --- .../org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index 2ef44371..2a11f199 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -1019,7 +1019,7 @@ public class HSQLDBDatabaseUpdates { stmt.execute("CREATE TABLE ArbitraryResourcesCache (service SMALLINT NOT NULL, " + "name RegisteredName NOT NULL, identifier VARCHAR(64), size INT NOT NULL, " - + "status INTEGER, created_when EpochMillis NOT NULL, updated_when EpochMillis, " + + "status INTEGER DEFAULT 1, created_when EpochMillis NOT NULL, updated_when EpochMillis, " + "PRIMARY KEY (service, name, identifier))"); // For finding resources by service. stmt.execute("CREATE INDEX ArbitraryResourcesServiceIndex ON ArbitraryResourcesCache (service)"); @@ -1057,4 +1057,4 @@ public class HSQLDBDatabaseUpdates { LOGGER.info(() -> String.format("HSQLDB repository updated to version %d", databaseVersion + 1)); return true; } -} \ No newline at end of file +} From 85300178c75350bbfc448f73712a9d5dcaad0fed Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:32:24 +0100 Subject: [PATCH 63/74] Update Advance Installer --- WindowsInstaller/Qortal.aip | 1642 ++++++++++++++++++----------------- WindowsInstaller/README.md | 6 +- 2 files changed, 825 insertions(+), 823 deletions(-) diff --git a/WindowsInstaller/Qortal.aip b/WindowsInstaller/Qortal.aip index 51ba5f69..1b0c944b 100755 --- a/WindowsInstaller/Qortal.aip +++ b/WindowsInstaller/Qortal.aip @@ -1,9 +1,13 @@ - + + + + - + + @@ -17,10 +21,10 @@ - + - + @@ -47,8 +51,6 @@ - - @@ -75,7 +77,6 @@ - @@ -86,6 +87,8 @@ + + @@ -102,6 +105,7 @@ + @@ -110,13 +114,10 @@ - - - - - + + @@ -132,240 +133,232 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + @@ -380,501 +373,489 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -889,7 +870,7 @@ - + @@ -898,6 +879,18 @@ + + + + + + + + + + + + @@ -913,6 +906,7 @@ + @@ -1136,13 +1130,13 @@ - + + - @@ -1165,10 +1159,12 @@ + + @@ -1221,6 +1217,7 @@ + @@ -1230,7 +1227,6 @@ - @@ -1241,12 +1237,10 @@ - - @@ -1255,7 +1249,6 @@ - @@ -1276,23 +1269,25 @@ - + + + + - @@ -1302,14 +1297,6 @@ - - - - - - - - @@ -1317,107 +1304,109 @@ - + + + + + + + - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + @@ -1457,8 +1446,6 @@ - - @@ -1472,6 +1459,8 @@ + + @@ -1520,8 +1509,11 @@ + + + @@ -1530,16 +1522,28 @@ + + + + + + + + + + + + diff --git a/WindowsInstaller/README.md b/WindowsInstaller/README.md index 0a9f2522..29a7b64a 100644 --- a/WindowsInstaller/README.md +++ b/WindowsInstaller/README.md @@ -2,8 +2,8 @@ ## Prerequisites -* AdvancedInstaller v16 or better, and enterprise licence if translations are required -* Installed AdoptOpenJDK v11 64bit, full JDK *not* JRE +* AdvancedInstaller v19.4 or better, and enterprise licence if translations are required +* Installed AdoptOpenJDK v17 64bit, full JDK *not* JRE ## General build instructions @@ -15,10 +15,8 @@ Typical build procedure: * Place the `qortal.jar` file in `Install-Files\` * Open AdvancedInstaller with qortal.aip file * If releasing a new version, change version number in: - + "Product Information" side menu + "Product Details" side menu entry + "Product Details" tab in "Product Details" pane - + "Product Version" entry box * Click away to a different side menu entry, e.g. "Resources" -> "Files and Folders" * You should be prompted whether to generate a new product key, click "Generate New" * Click "Build" button From 8bd9b41a13f2808380394e3e787b80d17680034d Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:36:59 +0100 Subject: [PATCH 64/74] Update dependencies --- pom.xml | 97 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/pom.xml b/pom.xml index e623a5dd..3fcf18ea 100644 --- a/pom.xml +++ b/pom.xml @@ -10,53 +10,52 @@ 7dc8c6f 0.15.10 1.69 + 3.4.0 ${maven.build.timestamp} 1.4.1 - 3.8.0 - 1.10.0 + 3.10.0 + 1.11.0 2.11.0 1.24.0 3.13.0 - 1.9 1.2.2 - 32.1.3-jre - 2.5.1 - 1.2.1 - 73.2 - 1.1 - 2.3.3 - 2.40 - 9.4.53.v20231009 - 2.20.0 - UTF-8 - 1.7.36 - 2.0.10 - 3.52.5 - 1.1.0 - 1.16.1 - 4.12 - 1.58.0 - 3.24.4 - 1.17 - 2.16.1 - 3.11.0 + 0.12.3 4.9.10 - 1.5.3 - 3.3.1 - 3.4.0 - 3.3.0 - 3.5.1 - 0.16 - 3.1.2 - 1.0.0 - 3.4.0 + 1.59.0 + 32.1.3-jre + 2.2 + 1.2.1 + 2.5.1 + 74.1 + 4.12 + 4.0.1 + 2.3.3 + 2.41 + 9.4.53.v20231009 1.1.1 20231013 - 0.12.3 - 4.0.1 + 1.16.2 + 5.10.0 + 1.0.0 + 2.21.1 1.5.0-b01 - 5.3.1 - 1.3 + 3.11.0 + 3.3.0 + 3.3.1 + 3.5.1 + 3.2.1 + 1.1.0 + UTF-8 + 3.24.4 + 1.5.3 + 0.16 + 1.17 + 1.7.36 + 2.0.10 + 5.9.0 + 1.2 + 2.16.1 + 1.9 src/main/java @@ -152,22 +151,34 @@ false ${project.build.directory}/swagger-ui.unpacked/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/index.html + + + Swagger UI + Qortal API Documentation + + + + + + replace-swagger-ui-json + generate-resources + + replace + + false + + ${project.build.directory}/swagger-ui.unpacked/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/swagger-initializer.js https://petstore.swagger.io/v2/swagger.json /openapi.json - - Swagger UI - API Documentation - deepLinking: true, deepLinking: true, tagsSorter: "alpha", - operationsSorter: - "alpha", + operationsSorter: "alpha", validatorUrl: false, From dfcc7bb370608c651c2638ea105b0e683d545dbc Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:44:18 +0100 Subject: [PATCH 65/74] Update UPnP --- lib/com/dosse/WaifUPnP/1.2/WaifUPnP-1.2.jar | Bin 0 -> 10254 bytes lib/com/dosse/WaifUPnP/1.2/WaifUPnP-1.2.pom | 9 +++++++++ lib/com/dosse/WaifUPnP/maven-metadata-local.xml | 5 +++-- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 lib/com/dosse/WaifUPnP/1.2/WaifUPnP-1.2.jar create mode 100644 lib/com/dosse/WaifUPnP/1.2/WaifUPnP-1.2.pom diff --git a/lib/com/dosse/WaifUPnP/1.2/WaifUPnP-1.2.jar b/lib/com/dosse/WaifUPnP/1.2/WaifUPnP-1.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..3baee4fd30dc56026cc72838941ca4c199034edb GIT binary patch literal 10254 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 + + 4.0.0 + com.dosse + WaifUPnP + 1.2 + POM was created from install:install-file + diff --git a/lib/com/dosse/WaifUPnP/maven-metadata-local.xml b/lib/com/dosse/WaifUPnP/maven-metadata-local.xml index 07d6ffd0..224e347d 100644 --- a/lib/com/dosse/WaifUPnP/maven-metadata-local.xml +++ b/lib/com/dosse/WaifUPnP/maven-metadata-local.xml @@ -3,10 +3,11 @@ com.dosse WaifUPnP - 1.1 + 1.2 1.1 + 1.2 - 20220218200127 + 20231026200127 From 3190fed3b9a151c1b6b07636bb787c987f75e700 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 4 Nov 2023 17:11:07 +0100 Subject: [PATCH 66/74] Optimize imports --- pom.xml | 2 +- src/main/java/org/hsqldb/jdbc/HSQLDBPool.java | 4 +- src/main/java/org/qortal/ApplyUpdate.java | 18 +++--- .../org/qortal/RepositoryMaintenance.java | 6 +- src/main/java/org/qortal/XorUpdate.java | 4 +- src/main/java/org/qortal/account/Account.java | 10 ++-- .../org/qortal/account/AccountRefCache.java | 10 ++-- .../org/qortal/api/AmountTypeAdapter.java | 5 +- src/main/java/org/qortal/api/ApiError.java | 9 ++- .../java/org/qortal/api/ApiErrorHandler.java | 13 ++--- .../org/qortal/api/ApiExceptionFactory.java | 4 +- src/main/java/org/qortal/api/ApiRequest.java | 38 +++++-------- src/main/java/org/qortal/api/ApiService.java | 37 +++++------- .../org/qortal/api/Base58TypeAdapter.java | 4 +- .../org/qortal/api/BigDecimalTypeAdapter.java | 3 +- src/main/java/org/qortal/api/Constants.java | 4 +- .../api/RewardSharePercentTypeAdapter.java | 3 +- src/main/java/org/qortal/api/Security.java | 3 +- .../api/TransactionCountMapXmlAdapter.java | 13 ++--- .../api/gateway/resource/GatewayResource.java | 4 +- .../qortal/api/model/AccountPenaltyStats.java | 2 - .../org/qortal/api/model/ActivitySummary.java | 11 ++-- .../org/qortal/api/model/AggregatedOrder.java | 4 +- .../qortal/api/model/AtCreationRequest.java | 5 +- .../qortal/api/model/BlockSignerSummary.java | 4 +- .../model/CrossChainBitcoinRedeemRequest.java | 5 +- .../model/CrossChainBitcoinRefundRequest.java | 5 +- .../CrossChainBitcoinTemplateRequest.java | 4 +- .../model/CrossChainBitcoinyHTLCStatus.java | 5 +- .../api/model/CrossChainBuildRequest.java | 4 +- .../api/model/CrossChainCancelRequest.java | 4 +- .../api/model/CrossChainOfferSummary.java | 9 ++- .../api/model/CrossChainSecretRequest.java | 4 +- .../api/model/CrossChainTradeRequest.java | 4 +- .../api/model/CrossChainTradeSummary.java | 7 +-- .../org/qortal/api/model/GroupMembers.java | 5 +- .../org/qortal/api/model/NameSummary.java | 4 +- .../java/org/qortal/api/model/NodeStatus.java | 6 +- .../java/org/qortal/api/model/PollVotes.java | 9 ++- .../api/model/RewardShareKeyRequest.java | 4 +- .../api/model/SimpleForeignTransaction.java | 5 +- .../model/SimpleTransactionSignRequest.java | 4 +- .../qortal/api/model/TradeWithOrderInfo.java | 9 ++- .../model/crosschain/BitcoinSendRequest.java | 4 +- .../model/crosschain/DigibyteSendRequest.java | 4 +- .../model/crosschain/LitecoinSendRequest.java | 4 +- .../crosschain/RavencoinSendRequest.java | 4 +- .../crosschain/TradeBotCreateRequest.java | 7 +-- .../crosschain/TradeBotRespondRequest.java | 4 +- .../api/resource/AddressesResource.java | 29 ++++------ .../api/resource/AnnotationPostProcessor.java | 10 ++-- .../qortal/api/resource/ApiDefinition.java | 1 - .../api/resource/ApiExceptionMapper.java | 10 ++-- .../org/qortal/api/resource/AppsResource.java | 8 ++- .../api/resource/ArbitraryResource.java | 42 +++++++------- .../qortal/api/resource/AssetsResource.java | 40 ++++--------- .../org/qortal/api/resource/AtResource.java | 21 +++---- .../qortal/api/resource/BlocksResource.java | 38 ++++++------- .../org/qortal/api/resource/ChatResource.java | 15 ++--- .../CrossChainBitcoinACCTv1Resource.java | 22 ++++--- .../resource/CrossChainBitcoinResource.java | 20 +++---- .../resource/CrossChainDigibyteResource.java | 20 +++---- .../resource/CrossChainDogecoinResource.java | 4 +- .../api/resource/CrossChainHtlcResource.java | 20 +++---- .../CrossChainLitecoinACCTv1Resource.java | 5 -- .../resource/CrossChainLitecoinResource.java | 20 +++---- .../CrossChainPirateChainResource.java | 2 +- .../resource/CrossChainRavencoinResource.java | 22 ++++--- .../api/resource/CrossChainResource.java | 18 +++--- .../resource/CrossChainTradeBotResource.java | 22 ++++--- .../qortal/api/resource/GroupsResource.java | 57 ++++--------------- .../qortal/api/resource/ListsResource.java | 11 ++-- .../qortal/api/resource/NamesResource.java | 32 +++-------- .../qortal/api/resource/PaymentsResource.java | 13 ++--- .../qortal/api/resource/PeersResource.java | 24 ++++---- .../qortal/api/resource/PollsResource.java | 23 +++----- .../qortal/api/resource/StatsResource.java | 6 +- .../api/resource/TransactionsResource.java | 33 +++++------ .../qortal/api/resource/UtilsResource.java | 27 +++------ .../restricted/resource/AdminResource.java | 33 +++++------ .../resource/BootstrapResource.java | 6 +- .../restricted/resource/RenderResource.java | 37 ++++-------- .../api/websocket/ActiveChatsWebSocket.java | 20 +++---- .../api/websocket/AdminStatusWebSocket.java | 14 ++--- .../qortal/api/websocket/ApiWebSocket.java | 21 +++---- .../qortal/api/websocket/BlocksWebSocket.java | 14 ++--- .../api/websocket/ChatMessagesWebSocket.java | 14 ++--- .../api/websocket/PresenceWebSocket.java | 25 +++----- .../api/websocket/TradeBotWebSocket.java | 16 ++---- .../api/websocket/TradeOffersWebSocket.java | 28 +++------ .../ArbitraryDataBuildQueueItem.java | 2 +- .../arbitrary/ArbitraryDataBuilder.java | 2 +- .../qortal/arbitrary/ArbitraryDataCache.java | 2 +- .../qortal/arbitrary/ArbitraryDataDiff.java | 8 ++- .../qortal/arbitrary/ArbitraryDataMerge.java | 8 ++- .../qortal/arbitrary/ArbitraryDataReader.java | 6 +- .../arbitrary/ArbitraryDataRenderer.java | 2 +- .../ArbitraryDataTransactionBuilder.java | 9 ++- .../qortal/arbitrary/ArbitraryDataWriter.java | 15 +++-- .../metadata/ArbitraryDataMetadataPatch.java | 2 +- .../metadata/ArbitraryDataQortalMetadata.java | 1 - .../org/qortal/arbitrary/misc/Service.java | 3 +- src/main/java/org/qortal/asset/Order.java | 12 ++-- src/main/java/org/qortal/at/AT.java | 8 +-- src/main/java/org/qortal/at/QortalATAPI.java | 25 +++----- .../org/qortal/at/QortalFunctionCode.java | 8 +-- src/main/java/org/qortal/block/Block.java | 40 ++++++------- .../java/org/qortal/block/Block212937.java | 19 +++---- .../java/org/qortal/block/BlockChain.java | 31 +++++----- .../java/org/qortal/block/GenesisBlock.java | 24 ++++---- .../block/SelfSponsorshipAlgoV1Block.java | 5 +- .../org/qortal/controller/AutoUpdate.java | 35 ++++++------ .../org/qortal/controller/BlockMinter.java | 22 +++---- .../org/qortal/controller/ChatNotifier.java | 6 +- .../org/qortal/controller/Controller.java | 51 ++++++++--------- .../controller/OnlineAccountsManager.java | 4 +- .../org/qortal/controller/Synchronizer.java | 18 +++--- .../arbitrary/ArbitraryDataBuilderThread.java | 2 +- .../arbitrary/ArbitraryDataCacheManager.java | 4 +- .../ArbitraryDataCleanupManager.java | 5 +- .../ArbitraryDataFileRequestThread.java | 5 +- .../arbitrary/ArbitraryDataManager.java | 13 ++--- .../arbitrary/ArbitraryDataRenderManager.java | 5 +- .../arbitrary/ArbitraryMetadataManager.java | 4 +- .../controller/repository/BlockArchiver.java | 5 +- .../controller/repository/PruneManager.java | 1 - .../controller/tradebot/AcctTradeBot.java | 4 +- .../tradebot/BitcoinACCTv1TradeBot.java | 31 ++++------ .../tradebot/LitecoinACCTv1TradeBot.java | 31 ++++------ .../tradebot/PirateChainACCTv3TradeBot.java | 3 +- .../qortal/controller/tradebot/TradeBot.java | 12 ++-- .../java/org/qortal/crosschain/AcctMode.java | 4 +- .../java/org/qortal/crosschain/Bitcoin.java | 10 ++-- .../org/qortal/crosschain/BitcoinACCTv1.java | 22 +++---- .../java/org/qortal/crosschain/Bitcoiny.java | 24 ++------ .../BitcoinyBlockchainProvider.java | 2 +- .../org/qortal/crosschain/BitcoinyHTLC.java | 24 ++------ .../crosschain/BitcoinyTransaction.java | 7 +-- .../java/org/qortal/crosschain/Digibyte.java | 10 ++-- .../java/org/qortal/crosschain/ElectrumX.java | 28 +++++---- .../java/org/qortal/crosschain/Litecoin.java | 10 ++-- .../org/qortal/crosschain/LitecoinACCTv1.java | 22 +++---- .../org/qortal/crosschain/PirateChain.java | 6 -- .../qortal/crosschain/PirateChainHTLC.java | 1 + .../qortal/crosschain/PirateLightClient.java | 2 +- .../java/org/qortal/crosschain/Ravencoin.java | 10 ++-- .../crosschain/SupportedBlockchain.java | 6 +- src/main/java/org/qortal/crypto/AES.java | 15 +---- .../qortal/crypto/BouncyCastleEd25519.java | 4 +- .../java/org/qortal/crypto/Credentials.java | 6 +- src/main/java/org/qortal/crypto/Crypto.java | 17 +++--- .../crypto/TrustlessSSLSocketFactory.java | 3 +- .../data/account/AccountBalanceData.java | 4 +- .../org/qortal/data/account/AccountData.java | 4 +- .../data/account/MintingAccountData.java | 13 ++--- .../qortal/data/account/RewardShareData.java | 8 +-- .../data/arbitrary/ArbitraryRelayInfo.java | 1 + .../java/org/qortal/data/asset/AssetData.java | 4 +- .../java/org/qortal/data/asset/OrderData.java | 9 ++- .../qortal/data/asset/RecentTradeData.java | 5 +- .../java/org/qortal/data/asset/TradeData.java | 6 +- .../qortal/data/block/BlockArchiveData.java | 2 - .../java/org/qortal/data/block/BlockData.java | 12 ++-- .../org/qortal/data/chat/ActiveChats.java | 3 +- .../data/crosschain/CrossChainTradeData.java | 7 +-- .../qortal/data/crosschain/TradeBotData.java | 9 ++- .../org/qortal/data/group/GroupAdminData.java | 4 +- .../org/qortal/data/group/GroupBanData.java | 4 +- .../java/org/qortal/data/group/GroupData.java | 7 +-- .../qortal/data/group/GroupInviteData.java | 4 +- .../data/group/GroupJoinRequestData.java | 4 +- .../qortal/data/group/GroupMemberData.java | 4 +- .../java/org/qortal/data/naming/NameData.java | 4 +- .../data/network/OnlineAccountData.java | 7 +-- .../org/qortal/data/network/PeerData.java | 7 +-- .../data/transaction/ATTransactionData.java | 9 ++- .../AccountFlagsTransactionData.java | 11 ++-- .../AccountLevelTransactionData.java | 11 ++-- .../AddGroupAdminTransactionData.java | 9 ++- .../transaction/ArbitraryTransactionData.java | 14 ++--- .../transaction/BuyNameTransactionData.java | 7 +-- .../CancelAssetOrderTransactionData.java | 9 ++- .../CancelGroupBanTransactionData.java | 7 +-- .../CancelGroupInviteTransactionData.java | 7 +-- .../CancelSellNameTransactionData.java | 7 +-- .../data/transaction/ChatTransactionData.java | 9 ++- .../CreateAssetOrderTransactionData.java | 9 ++- .../CreateGroupTransactionData.java | 15 +++-- .../CreatePollTransactionData.java | 12 ++-- .../transaction/DeployAtTransactionData.java | 7 +-- .../transaction/GenesisTransactionData.java | 9 ++- .../GroupApprovalTransactionData.java | 7 +-- .../transaction/GroupBanTransactionData.java | 7 +-- .../GroupInviteTransactionData.java | 9 ++- .../transaction/GroupKickTransactionData.java | 7 +-- .../IssueAssetTransactionData.java | 15 +++-- .../transaction/JoinGroupTransactionData.java | 9 ++- .../LeaveGroupTransactionData.java | 7 +-- .../transaction/MessageTransactionData.java | 9 ++- .../MultiPaymentTransactionData.java | 12 ++-- .../transaction/PaymentTransactionData.java | 7 +-- .../transaction/PresenceTransactionData.java | 11 ++-- .../transaction/PublicizeTransactionData.java | 9 ++- .../RegisterNameTransactionData.java | 11 ++-- .../RemoveGroupAdminTransactionData.java | 7 +-- .../RewardShareTransactionData.java | 9 ++- .../transaction/SellNameTransactionData.java | 7 +-- .../transaction/SetGroupTransactionData.java | 7 +-- .../data/transaction/TransactionData.java | 18 ++---- .../TransferAssetTransactionData.java | 9 ++- .../TransferPrivsTransactionData.java | 7 +-- .../UpdateAssetTransactionData.java | 7 +-- .../UpdateGroupTransactionData.java | 11 ++-- .../UpdateNameTransactionData.java | 9 ++- .../VoteOnPollTransactionData.java | 9 ++- src/main/java/org/qortal/event/EventBus.java | 6 +- .../qortal/globalization/BIP39WordList.java | 6 +- .../org/qortal/globalization/Translator.java | 10 +--- src/main/java/org/qortal/group/Group.java | 32 +++-------- src/main/java/org/qortal/gui/Gui.java | 15 ++--- src/main/java/org/qortal/gui/SplashFrame.java | 15 +++-- src/main/java/org/qortal/gui/SysTray.java | 32 ++++------- src/main/java/org/qortal/naming/Name.java | 7 +-- .../java/org/qortal/network/Handshake.java | 17 ++---- src/main/java/org/qortal/network/Peer.java | 1 - .../java/org/qortal/network/PeerAddress.java | 16 ++---- .../network/message/ArbitraryDataMessage.java | 7 +-- .../qortal/network/message/BlockMessage.java | 7 +-- .../message/BlockSummariesMessage.java | 11 ++-- .../network/message/CachedBlockMessage.java | 9 ++- .../network/message/ChallengeMessage.java | 4 +- .../message/GetArbitraryDataMessage.java | 4 +- .../network/message/GetBlockMessage.java | 4 +- .../message/GetBlockSummariesMessage.java | 7 +-- .../message/GetOnlineAccountsV3Message.java | 4 +- .../message/GetSignaturesV2Message.java | 7 +-- .../message/GetTransactionMessage.java | 4 +- .../network/message/GoodbyeMessage.java | 6 +- .../network/message/HeightV2Message.java | 11 ++-- .../qortal/network/message/HelloMessage.java | 9 ++- .../org/qortal/network/message/Message.java | 3 +- .../network/message/PeersV2Message.java | 9 ++- .../network/message/ResponseMessage.java | 4 +- .../network/message/SignaturesMessage.java | 7 +-- .../network/message/TransactionMessage.java | 4 +- .../message/TransactionSignaturesMessage.java | 7 +-- .../qortal/network/task/BroadcastTask.java | 3 - .../qortal/network/task/ChannelReadTask.java | 1 - .../qortal/network/task/PeerConnectTask.java | 4 -- src/main/java/org/qortal/payment/Payment.java | 10 +--- .../org/qortal/repository/ATRepository.java | 8 +-- .../qortal/repository/AccountRepository.java | 4 +- .../repository/ArbitraryRepository.java | 2 +- .../qortal/repository/AssetRepository.java | 4 +- .../qortal/repository/BlockArchiveReader.java | 4 +- .../qortal/repository/BlockRepository.java | 4 +- .../org/qortal/repository/ChatRepository.java | 4 +- .../repository/CrossChainRepository.java | 4 +- .../qortal/repository/GroupRepository.java | 9 +-- .../qortal/repository/MessageRepository.java | 4 +- .../org/qortal/repository/NameRepository.java | 4 +- .../qortal/repository/NetworkRepository.java | 4 +- .../repository/TransactionRepository.java | 8 +-- .../qortal/repository/VotingRepository.java | 4 +- .../repository/hsqldb/HSQLDBATRepository.java | 13 ++--- .../hsqldb/HSQLDBAccountRepository.java | 10 ++-- .../hsqldb/HSQLDBArbitraryRepository.java | 6 +- .../hsqldb/HSQLDBAssetRepository.java | 12 ++-- .../hsqldb/HSQLDBBlockRepository.java | 19 +++---- .../hsqldb/HSQLDBChatRepository.java | 10 ++-- .../hsqldb/HSQLDBCrossChainRepository.java | 8 +-- .../hsqldb/HSQLDBDatabaseUpdates.java | 12 ++-- .../hsqldb/HSQLDBGroupRepository.java | 15 ++--- .../hsqldb/HSQLDBMessageRepository.java | 10 ++-- .../hsqldb/HSQLDBNameRepository.java | 8 +-- .../hsqldb/HSQLDBNetworkRepository.java | 10 ++-- .../repository/hsqldb/HSQLDBRepository.java | 36 +++++------- .../hsqldb/HSQLDBRepositoryFactory.java | 12 ++-- .../hsqldb/HSQLDBVotingRepository.java | 10 ++-- ...QLDBAccountFlagsTransactionRepository.java | 6 +- ...QLDBAccountLevelTransactionRepository.java | 6 +- ...LDBAddGroupAdminTransactionRepository.java | 6 +- .../HSQLDBArbitraryTransactionRepository.java | 19 +++---- .../HSQLDBAtTransactionRepository.java | 6 +- .../HSQLDBBuyNameTransactionRepository.java | 6 +- ...CancelAssetOrderTransactionRepository.java | 6 +- ...DBCancelGroupBanTransactionRepository.java | 6 +- ...ancelGroupInviteTransactionRepository.java | 6 +- ...DBCancelSellNameTransactionRepository.java | 6 +- .../HSQLDBChatTransactionRepository.java | 6 +- ...CreateAssetOrderTransactionRepository.java | 6 +- ...SQLDBCreateGroupTransactionRepository.java | 6 +- ...HSQLDBCreatePollTransactionRepository.java | 10 ++-- .../HSQLDBDeployAtTransactionRepository.java | 6 +- .../HSQLDBGenesisTransactionRepository.java | 6 +- ...LDBGroupApprovalTransactionRepository.java | 6 +- .../HSQLDBGroupBanTransactionRepository.java | 6 +- ...SQLDBGroupInviteTransactionRepository.java | 6 +- .../HSQLDBGroupKickTransactionRepository.java | 6 +- ...HSQLDBIssueAssetTransactionRepository.java | 6 +- .../HSQLDBJoinGroupTransactionRepository.java | 6 +- ...HSQLDBLeaveGroupTransactionRepository.java | 6 +- .../HSQLDBMessageTransactionRepository.java | 6 +- ...QLDBMultiPaymentTransactionRepository.java | 8 +-- .../HSQLDBPaymentTransactionRepository.java | 6 +- .../HSQLDBPresenceTransactionRepository.java | 6 +- .../HSQLDBPublicizeTransactionRepository.java | 6 +- ...QLDBRegisterNameTransactionRepository.java | 6 +- ...RemoveGroupAdminTransactionRepository.java | 6 +- ...SQLDBRewardShareTransactionRepository.java | 6 +- .../HSQLDBSellNameTransactionRepository.java | 6 +- .../HSQLDBSetGroupTransactionRepository.java | 6 +- .../HSQLDBTransactionRepository.java | 18 +++--- ...LDBTransferAssetTransactionRepository.java | 6 +- ...LDBTransferPrivsTransactionRepository.java | 6 +- ...SQLDBUpdateAssetTransactionRepository.java | 6 +- ...SQLDBUpdateGroupTransactionRepository.java | 6 +- ...HSQLDBUpdateNameTransactionRepository.java | 6 +- ...HSQLDBVoteOnPollTransactionRepository.java | 6 +- .../java/org/qortal/settings/Settings.java | 41 ++++++------- .../transaction/AccountFlagsTransaction.java | 6 +- .../transaction/AccountLevelTransaction.java | 6 +- .../transaction/AddGroupAdminTransaction.java | 8 +-- .../transaction/ArbitraryTransaction.java | 13 ++--- .../org/qortal/transaction/AtTransaction.java | 7 +-- .../transaction/BuyNameTransaction.java | 7 +-- .../CancelAssetOrderTransaction.java | 8 +-- .../CancelGroupBanTransaction.java | 6 +- .../CancelGroupInviteTransaction.java | 6 +- .../CancelSellNameTransaction.java | 7 +-- .../qortal/transaction/ChatTransaction.java | 12 ++-- .../CreateAssetOrderTransaction.java | 8 +-- .../transaction/CreateGroupTransaction.java | 7 +-- .../transaction/CreatePollTransaction.java | 9 ++- .../transaction/DeployAtTransaction.java | 9 ++- .../transaction/GenesisTransaction.java | 9 ++- .../transaction/GroupApprovalTransaction.java | 6 +- .../transaction/GroupBanTransaction.java | 6 +- .../transaction/GroupInviteTransaction.java | 6 +- .../transaction/GroupKickTransaction.java | 6 +- .../transaction/IssueAssetTransaction.java | 7 +-- .../transaction/JoinGroupTransaction.java | 6 +- .../transaction/LeaveGroupTransaction.java | 6 +- .../transaction/MessageTransaction.java | 8 +-- .../transaction/MultiPaymentTransaction.java | 6 +- .../transaction/PaymentTransaction.java | 6 +- .../transaction/PresenceTransaction.java | 19 +++---- .../transaction/PublicizeTransaction.java | 6 +- .../transaction/RegisterNameTransaction.java | 7 +-- .../RemoveGroupAdminTransaction.java | 8 +-- .../transaction/RewardShareTransaction.java | 8 +-- .../transaction/SellNameTransaction.java | 7 +-- .../transaction/SetGroupTransaction.java | 6 +- .../org/qortal/transaction/Transaction.java | 15 +++-- .../transaction/TransferAssetTransaction.java | 6 +- .../transaction/TransferPrivsTransaction.java | 8 +-- .../transaction/UpdateAssetTransaction.java | 7 +-- .../transaction/UpdateGroupTransaction.java | 7 +-- .../transaction/UpdateNameTransaction.java | 9 ++- .../transaction/VoteOnPollTransaction.java | 7 +-- .../qortal/transform/PaymentTransformer.java | 9 ++- .../transform/block/BlockTransformer.java | 22 ++++--- .../AccountFlagsTransactionTransformer.java | 11 ++-- .../AccountLevelTransactionTransformer.java | 9 ++- .../AddGroupAdminTransactionTransformer.java | 11 ++-- .../ArbitraryTransactionTransformer.java | 17 +++--- .../transaction/AtTransactionTransformer.java | 11 ++-- .../BuyNameTransactionTransformer.java | 11 ++-- ...ancelAssetOrderTransactionTransformer.java | 9 ++- .../CancelGroupBanTransactionTransformer.java | 11 ++-- ...ncelGroupInviteTransactionTransformer.java | 11 ++-- .../CancelSellNameTransactionTransformer.java | 11 ++-- .../ChatTransactionTransformer.java | 11 ++-- ...reateAssetOrderTransactionTransformer.java | 9 ++- .../CreateGroupTransactionTransformer.java | 13 ++--- .../CreatePollTransactionTransformer.java | 17 +++--- .../DeployAtTransactionTransformer.java | 13 ++--- .../GenesisTransactionTransformer.java | 11 ++-- .../GroupApprovalTransactionTransformer.java | 9 ++- .../GroupBanTransactionTransformer.java | 13 ++--- .../GroupInviteTransactionTransformer.java | 11 ++-- .../GroupKickTransactionTransformer.java | 13 ++--- .../IssueAssetTransactionTransformer.java | 11 ++-- .../JoinGroupTransactionTransformer.java | 11 ++-- .../LeaveGroupTransactionTransformer.java | 11 ++-- .../MessageTransactionTransformer.java | 11 ++-- .../MultiPaymentTransactionTransformer.java | 15 +++-- .../PaymentTransactionTransformer.java | 9 ++- .../PresenceTransactionTransformer.java | 11 ++-- .../PublicizeTransactionTransformer.java | 11 ++-- .../RegisterNameTransactionTransformer.java | 11 ++-- ...emoveGroupAdminTransactionTransformer.java | 11 ++-- .../RewardShareTransactionTransformer.java | 9 ++- .../SellNameTransactionTransformer.java | 11 ++-- .../SetGroupTransactionTransformer.java | 11 ++-- .../transaction/TransactionTransformer.java | 32 +++++------ .../TransferAssetTransactionTransformer.java | 9 ++- .../TransferPrivsTransactionTransformer.java | 9 ++- .../UpdateAssetTransactionTransformer.java | 11 ++-- .../UpdateGroupTransactionTransformer.java | 13 ++--- .../UpdateNameTransactionTransformer.java | 11 ++-- .../VoteOnPollTransactionTransformer.java | 13 ++--- .../utils/ArbitraryTransactionUtils.java | 6 +- .../org/qortal/utils/BlockArchiveUtils.java | 2 - .../qortal/utils/ExecuteProduceConsume.java | 11 ++-- .../java/org/qortal/utils/LoggingUtils.java | 1 - src/main/java/org/qortal/utils/NTP.java | 22 +++---- .../java/org/qortal/utils/Serialization.java | 9 ++- src/main/java/org/qortal/utils/SevenZ.java | 5 +- .../qortal/utils/StringLongMapXmlAdapter.java | 11 ++-- src/main/java/org/qortal/utils/URLViewer.java | 10 ++-- src/main/java/org/qortal/utils/Unicode.java | 22 ++----- .../org/qortal/test/AccountBalanceTests.java | 21 +++---- .../org/qortal/test/AccountRefCacheTests.java | 10 ++-- .../java/org/qortal/test/AmountsTests.java | 4 +- src/test/java/org/qortal/test/BlockTests.java | 14 ++--- .../java/org/qortal/test/ByteArrayTests.java | 14 ++--- .../org/qortal/test/ChainWeightTests.java | 24 ++++---- .../java/org/qortal/test/CryptoTests.java | 27 ++++----- src/test/java/org/qortal/test/EPCTests.java | 8 +-- src/test/java/org/qortal/test/GuiTests.java | 4 +- .../java/org/qortal/test/MemoryPoWTests.java | 4 +- .../java/org/qortal/test/MessageTests.java | 4 +- .../java/org/qortal/test/RepositoryTests.java | 7 +-- .../java/org/qortal/test/SchnorrTests.java | 3 +- .../test/SelfSponsorshipAlgoV1Tests.java | 12 +++- .../qortal/test/TransactionSearchTests.java | 8 +-- .../org/qortal/test/TransferPrivsTests.java | 10 +--- .../java/org/qortal/test/UnicodeTests.java | 7 ++- .../qortal/test/api/AddressesApiTests.java | 8 +-- .../org/qortal/test/api/AdminApiTests.java | 4 +- .../qortal/test/api/ArbitraryApiTests.java | 4 +- .../org/qortal/test/api/AssetsApiTests.java | 17 +++--- .../org/qortal/test/api/BlockApiTests.java | 12 ++-- .../org/qortal/test/api/GroupApiTests.java | 4 +- .../org/qortal/test/api/NamesApiTests.java | 5 +- .../qortal/test/api/TransactionsApiTests.java | 10 ++-- .../qortal/test/apps/BuildCheckpoints.java | 21 ++----- .../qortal/test/apps/CheckTranslations.java | 8 +-- .../test/apps/DecodeOnlineAccounts.java | 7 +-- .../org/qortal/test/apps/MemoryPoWTest.java | 4 +- .../java/org/qortal/test/apps/NTPTests.java | 10 ++-- .../java/org/qortal/test/apps/ProxyTest.java | 13 +---- .../org/qortal/test/apps/RewardShareKeys.java | 4 +- .../org/qortal/test/apps/SettingsTests.java | 17 +++--- .../java/org/qortal/test/apps/SyncReport.java | 7 +-- .../java/org/qortal/test/apps/VanityGen.java | 13 ++--- .../org/qortal/test/apps/brokenmd160.java | 2 +- .../java/org/qortal/test/apps/orphan.java | 3 +- .../arbitrary/ArbitraryDataDigestTests.java | 3 +- .../arbitrary/ArbitraryDataFileTests.java | 2 +- .../ArbitraryDataStoragePolicyTests.java | 1 - .../test/arbitrary/ArbitraryDataTests.java | 5 +- .../arbitrary/ArbitraryEncryptionTests.java | 2 - .../ArbitraryTransactionMetadataTests.java | 2 +- .../qortal/test/assets/CancellingTests.java | 8 +-- .../qortal/test/assets/GranularityTests.java | 8 +-- .../org/qortal/test/assets/MiscTests.java | 5 +- .../org/qortal/test/assets/TradingTests.java | 4 +- .../org/qortal/test/at/AtRepositoryTests.java | 8 +-- .../qortal/test/at/GetMessageLengthTests.java | 10 ++-- .../test/at/GetNextTransactionTests.java | 18 +++--- .../test/at/GetPartialMessageTests.java | 8 +-- .../at/SleepUntilMessageOrHeightTests.java | 18 +++--- .../test/at/SleepUntilMessageTests.java | 18 +++--- .../org/qortal/test/common/AccountUtils.java | 12 ++-- .../org/qortal/test/common/ApiCommon.java | 9 +-- .../org/qortal/test/common/AssetUtils.java | 18 ++---- .../java/org/qortal/test/common/Common.java | 35 +++++------- .../java/org/qortal/test/common/FakePeer.java | 4 +- .../org/qortal/test/common/GroupUtils.java | 6 +- .../org/qortal/test/common/PeerMessage.java | 1 - .../qortal/test/common/TransactionUtils.java | 14 ++--- .../AccountLevelTestTransaction.java | 4 +- .../transaction/ArbitraryTestTransaction.java | 8 +-- .../CancelAssetOrderTestTransaction.java | 4 +- .../CreateGroupTestTransaction.java | 4 +- .../CreatePollTestTransaction.java | 8 +-- .../transaction/DeployAtTestTransaction.java | 4 +- .../GroupApprovalTestTransaction.java | 4 +- .../IssueAssetTestTransaction.java | 4 +- .../MultiPaymentTestTransaction.java | 6 +- .../common/transaction/TestTransaction.java | 5 +- .../VoteOnPollTestTransaction.java | 4 +- .../test/crosschain/ElectrumXTests.java | 21 +++---- .../org/qortal/test/crosschain/HtlcTests.java | 7 +-- .../test/crosschain/PirateChainTests.java | 2 +- .../test/crosschain/apps/BuildHTLC.java | 11 ++-- .../test/crosschain/apps/CheckHTLC.java | 11 ++-- .../qortal/test/crosschain/apps/Common.java | 15 +++-- .../apps/GetNextReceiveAddress.java | 4 +- .../test/crosschain/apps/GetTransaction.java | 7 +-- .../apps/GetWalletTransactions.java | 10 ++-- .../test/crosschain/apps/RedeemHTLC.java | 17 ++---- .../test/crosschain/apps/RefundHTLC.java | 17 ++---- .../bitcoinv1/BitcoinACCTv1Tests.java | 12 ++-- .../test/crosschain/bitcoinv1/DeployAT.java | 3 +- .../test/crosschain/litecoinv1/DeployAT.java | 5 +- .../litecoinv1/LitecoinACCTv1Tests.java | 3 +- .../litecoinv1/SendRedeemMessage.java | 3 +- .../litecoinv1/SendTradeMessage.java | 3 +- .../org/qortal/test/group/AdminTests.java | 11 +--- .../qortal/test/group/DevGroupAdminTests.java | 3 - .../qortal/test/group/GroupApprovalTests.java | 4 +- .../test/group/GroupBlockDelayTests.java | 5 +- .../java/org/qortal/test/group/MiscTests.java | 5 +- .../org/qortal/test/group/OwnerTests.java | 4 +- .../test/minting/BlocksMintedCountTests.java | 6 +- .../test/minting/DisagreementTests.java | 13 ++--- .../qortal/test/minting/RewardShareTests.java | 4 +- .../org/qortal/test/minting/RewardTests.java | 13 +++-- .../org/qortal/test/naming/BuySellTests.java | 9 ++- .../org/qortal/test/naming/MiscTests.java | 21 ++++--- .../org/qortal/test/naming/UpdateTests.java | 5 +- .../test/network/OnlineAccountsTests.java | 5 +- .../test/network/OnlineAccountsV3Tests.java | 5 +- .../serialization/SerializationTests.java | 12 ++-- 517 files changed, 2232 insertions(+), 2876 deletions(-) diff --git a/pom.xml b/pom.xml index 3fcf18ea..0c1cad7c 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 74.1 4.12 4.0.1 - 2.3.3 + 2.3.9 2.41 9.4.53.v20231009 1.1.1 diff --git a/src/main/java/org/hsqldb/jdbc/HSQLDBPool.java b/src/main/java/org/hsqldb/jdbc/HSQLDBPool.java index 0bf9d2ef..f2f6484c 100644 --- a/src/main/java/org/hsqldb/jdbc/HSQLDBPool.java +++ b/src/main/java/org/hsqldb/jdbc/HSQLDBPool.java @@ -1,10 +1,10 @@ package org.hsqldb.jdbc; +import org.hsqldb.jdbc.pool.JDBCPooledConnection; + import java.sql.Connection; import java.sql.SQLException; -import org.hsqldb.jdbc.pool.JDBCPooledConnection; - public class HSQLDBPool extends JDBCPool { public HSQLDBPool(int poolSize) { diff --git a/src/main/java/org/qortal/ApplyUpdate.java b/src/main/java/org/qortal/ApplyUpdate.java index 7a870460..f1f9d22f 100644 --- a/src/main/java/org/qortal/ApplyUpdate.java +++ b/src/main/java/org/qortal/ApplyUpdate.java @@ -1,5 +1,14 @@ package org.qortal; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; +import org.qortal.api.ApiKey; +import org.qortal.api.ApiRequest; +import org.qortal.controller.AutoUpdate; +import org.qortal.settings.Settings; + import java.io.IOException; import java.lang.management.ManagementFactory; import java.nio.file.Files; @@ -10,15 +19,6 @@ import java.security.Security; import java.util.*; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; -import org.qortal.api.ApiKey; -import org.qortal.api.ApiRequest; -import org.qortal.controller.AutoUpdate; -import org.qortal.settings.Settings; - import static org.qortal.controller.AutoUpdate.AGENTLIB_JVM_HOLDER_ARG; public class ApplyUpdate { diff --git a/src/main/java/org/qortal/RepositoryMaintenance.java b/src/main/java/org/qortal/RepositoryMaintenance.java index b085822b..0d60d7f9 100644 --- a/src/main/java/org/qortal/RepositoryMaintenance.java +++ b/src/main/java/org/qortal/RepositoryMaintenance.java @@ -1,8 +1,5 @@ package org.qortal; -import java.security.Security; -import java.util.concurrent.TimeoutException; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -15,6 +12,9 @@ import org.qortal.repository.RepositoryManager; import org.qortal.repository.hsqldb.HSQLDBRepositoryFactory; import org.qortal.settings.Settings; +import java.security.Security; +import java.util.concurrent.TimeoutException; + public class RepositoryMaintenance { static { diff --git a/src/main/java/org/qortal/XorUpdate.java b/src/main/java/org/qortal/XorUpdate.java index 9880f1de..32ff7a72 100644 --- a/src/main/java/org/qortal/XorUpdate.java +++ b/src/main/java/org/qortal/XorUpdate.java @@ -1,5 +1,7 @@ package org.qortal; +import org.qortal.controller.AutoUpdate; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -7,8 +9,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import org.qortal.controller.AutoUpdate; - public class XorUpdate { private static final byte XOR_VALUE = AutoUpdate.XOR_VALUE; diff --git a/src/main/java/org/qortal/account/Account.java b/src/main/java/org/qortal/account/Account.java index 2c75dbc0..756128f9 100644 --- a/src/main/java/org/qortal/account/Account.java +++ b/src/main/java/org/qortal/account/Account.java @@ -1,10 +1,5 @@ package org.qortal.account; -import static org.qortal.utils.Amounts.prettyAmount; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.block.BlockChain; @@ -17,6 +12,11 @@ import org.qortal.repository.Repository; import org.qortal.settings.Settings; import org.qortal.utils.Base58; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import static org.qortal.utils.Amounts.prettyAmount; + @XmlAccessorType(XmlAccessType.NONE) // Stops JAX-RS errors when unmarshalling blockchain config public class Account { diff --git a/src/main/java/org/qortal/account/AccountRefCache.java b/src/main/java/org/qortal/account/AccountRefCache.java index 13017bd3..11252710 100644 --- a/src/main/java/org/qortal/account/AccountRefCache.java +++ b/src/main/java/org/qortal/account/AccountRefCache.java @@ -1,15 +1,15 @@ package org.qortal.account; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.BinaryOperator; - import org.qortal.data.account.AccountData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Pair; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.BinaryOperator; + /** * Account lastReference caching *

diff --git a/src/main/java/org/qortal/api/AmountTypeAdapter.java b/src/main/java/org/qortal/api/AmountTypeAdapter.java index 5cbf81ee..5db3df45 100644 --- a/src/main/java/org/qortal/api/AmountTypeAdapter.java +++ b/src/main/java/org/qortal/api/AmountTypeAdapter.java @@ -1,10 +1,9 @@ package org.qortal.api; -import java.math.BigDecimal; +import org.qortal.utils.Amounts; import javax.xml.bind.annotation.adapters.XmlAdapter; - -import org.qortal.utils.Amounts; +import java.math.BigDecimal; public class AmountTypeAdapter extends XmlAdapter { diff --git a/src/main/java/org/qortal/api/ApiError.java b/src/main/java/org/qortal/api/ApiError.java index b52332b1..5a634a76 100644 --- a/src/main/java/org/qortal/api/ApiError.java +++ b/src/main/java/org/qortal/api/ApiError.java @@ -1,13 +1,12 @@ package org.qortal.api; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -import java.util.Map; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; @XmlAccessorType(XmlAccessType.NONE) @XmlRootElement diff --git a/src/main/java/org/qortal/api/ApiErrorHandler.java b/src/main/java/org/qortal/api/ApiErrorHandler.java index a6a77eed..7ae0d89a 100644 --- a/src/main/java/org/qortal/api/ApiErrorHandler.java +++ b/src/main/java/org/qortal/api/ApiErrorHandler.java @@ -1,18 +1,17 @@ package org.qortal.api; -import java.io.IOException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.ErrorHandler; import org.qortal.settings.Settings; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + public class ApiErrorHandler extends ErrorHandler { private static final Logger LOGGER = LogManager.getLogger(ApiErrorHandler.class); diff --git a/src/main/java/org/qortal/api/ApiExceptionFactory.java b/src/main/java/org/qortal/api/ApiExceptionFactory.java index 294cef83..7826eb6d 100644 --- a/src/main/java/org/qortal/api/ApiExceptionFactory.java +++ b/src/main/java/org/qortal/api/ApiExceptionFactory.java @@ -1,9 +1,9 @@ package org.qortal.api; -import javax.servlet.http.HttpServletRequest; - import org.qortal.globalization.Translator; +import javax.servlet.http.HttpServletRequest; + public enum ApiExceptionFactory { INSTANCE; diff --git a/src/main/java/org/qortal/api/ApiRequest.java b/src/main/java/org/qortal/api/ApiRequest.java index a51a117e..59bd791a 100644 --- a/src/main/java/org/qortal/api/ApiRequest.java +++ b/src/main/java/org/qortal/api/ApiRequest.java @@ -1,34 +1,24 @@ package org.qortal.api; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.URL; -import java.net.URLEncoder; -import java.util.Collections; -import java.util.Map; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SNIHostName; -import javax.net.ssl.SNIServerName; -import javax.net.ssl.SSLParameters; -import javax.net.ssl.SSLSocket; -import javax.xml.bind.*; -import javax.xml.transform.stream.StreamSource; - import org.eclipse.persistence.exceptions.XMLMarshalException; import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.MarshallerProperties; import org.eclipse.persistence.jaxb.UnmarshallerProperties; +import javax.net.ssl.*; +import javax.xml.bind.*; +import javax.xml.transform.stream.StreamSource; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.net.*; +import java.util.Collections; +import java.util.Map; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class ApiRequest { private static final Pattern proxyUrlPattern = Pattern.compile("(https://)([^@:/]+)@([0-9.]{7,15})(/.*)"); diff --git a/src/main/java/org/qortal/api/ApiService.java b/src/main/java/org/qortal/api/ApiService.java index 1ee733c6..fbef50d3 100644 --- a/src/main/java/org/qortal/api/ApiService.java +++ b/src/main/java/org/qortal/api/ApiService.java @@ -1,33 +1,10 @@ package org.qortal.api; import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource; - -import java.io.InputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.KeyStore; -import java.security.SecureRandom; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.servlet.http.HttpServletRequest; - import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.rewrite.handler.RedirectPatternRule; import org.eclipse.jetty.rewrite.handler.RewriteHandler; -import org.eclipse.jetty.server.CustomRequestLog; -import org.eclipse.jetty.server.DetectorConnectionFactory; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.RequestLogWriter; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.InetAccessHandler; import org.eclipse.jetty.servlet.DefaultServlet; @@ -44,6 +21,18 @@ import org.qortal.api.websocket.*; import org.qortal.network.Network; import org.qortal.settings.Settings; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.servlet.http.HttpServletRequest; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.security.SecureRandom; + public class ApiService { private static ApiService instance; diff --git a/src/main/java/org/qortal/api/Base58TypeAdapter.java b/src/main/java/org/qortal/api/Base58TypeAdapter.java index d7561031..b84cc657 100644 --- a/src/main/java/org/qortal/api/Base58TypeAdapter.java +++ b/src/main/java/org/qortal/api/Base58TypeAdapter.java @@ -1,9 +1,9 @@ package org.qortal.api; -import javax.xml.bind.annotation.adapters.XmlAdapter; - import org.qortal.utils.Base58; +import javax.xml.bind.annotation.adapters.XmlAdapter; + public class Base58TypeAdapter extends XmlAdapter { @Override diff --git a/src/main/java/org/qortal/api/BigDecimalTypeAdapter.java b/src/main/java/org/qortal/api/BigDecimalTypeAdapter.java index fae55d0a..157c98c7 100644 --- a/src/main/java/org/qortal/api/BigDecimalTypeAdapter.java +++ b/src/main/java/org/qortal/api/BigDecimalTypeAdapter.java @@ -1,8 +1,7 @@ package org.qortal.api; -import java.math.BigDecimal; - import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.math.BigDecimal; public class BigDecimalTypeAdapter extends XmlAdapter { diff --git a/src/main/java/org/qortal/api/Constants.java b/src/main/java/org/qortal/api/Constants.java index e74a0059..d77d325a 100644 --- a/src/main/java/org/qortal/api/Constants.java +++ b/src/main/java/org/qortal/api/Constants.java @@ -4,9 +4,11 @@ import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.responses.ApiResponse; -import static java.util.Arrays.asList; + import java.util.List; +import static java.util.Arrays.asList; + class Constants { public static final String APIERROR_CONTEXT_PATH = "/Api"; public static final String APIERROR_KEY = "ApiError/%s"; diff --git a/src/main/java/org/qortal/api/RewardSharePercentTypeAdapter.java b/src/main/java/org/qortal/api/RewardSharePercentTypeAdapter.java index 1ad2034c..a1d416dc 100644 --- a/src/main/java/org/qortal/api/RewardSharePercentTypeAdapter.java +++ b/src/main/java/org/qortal/api/RewardSharePercentTypeAdapter.java @@ -1,8 +1,7 @@ package org.qortal.api; -import java.math.BigDecimal; - import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.math.BigDecimal; public class RewardSharePercentTypeAdapter extends XmlAdapter { diff --git a/src/main/java/org/qortal/api/Security.java b/src/main/java/org/qortal/api/Security.java index f009d79f..19178dd0 100644 --- a/src/main/java/org/qortal/api/Security.java +++ b/src/main/java/org/qortal/api/Security.java @@ -5,12 +5,11 @@ import org.qortal.arbitrary.misc.Service; import org.qortal.controller.arbitrary.ArbitraryDataRenderManager; import org.qortal.settings.Settings; +import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import javax.servlet.http.HttpServletRequest; - public abstract class Security { public static final String API_KEY_HEADER = "X-API-KEY"; diff --git a/src/main/java/org/qortal/api/TransactionCountMapXmlAdapter.java b/src/main/java/org/qortal/api/TransactionCountMapXmlAdapter.java index bb2b4d8c..0aba8800 100644 --- a/src/main/java/org/qortal/api/TransactionCountMapXmlAdapter.java +++ b/src/main/java/org/qortal/api/TransactionCountMapXmlAdapter.java @@ -1,18 +1,17 @@ package org.qortal.api; +import org.eclipse.persistence.oxm.annotations.XmlVariableNode; +import org.qortal.transaction.Transaction.TransactionType; + +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.XmlAdapter; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import javax.xml.bind.annotation.XmlTransient; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.XmlAdapter; - -import org.eclipse.persistence.oxm.annotations.XmlVariableNode; -import org.qortal.transaction.Transaction.TransactionType; - public class TransactionCountMapXmlAdapter extends XmlAdapter> { public static class StringIntegerMap { diff --git a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java index bf4e1ea6..7169fd4a 100644 --- a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java +++ b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java @@ -20,7 +20,9 @@ import org.qortal.repository.RepositoryManager; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.*; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/org/qortal/api/model/AccountPenaltyStats.java b/src/main/java/org/qortal/api/model/AccountPenaltyStats.java index aafe25fc..929819f6 100644 --- a/src/main/java/org/qortal/api/model/AccountPenaltyStats.java +++ b/src/main/java/org/qortal/api/model/AccountPenaltyStats.java @@ -2,11 +2,9 @@ package org.qortal.api.model; import org.qortal.block.SelfSponsorshipAlgoV1Block; import org.qortal.data.account.AccountData; -import org.qortal.data.naming.NameData; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/qortal/api/model/ActivitySummary.java b/src/main/java/org/qortal/api/model/ActivitySummary.java index e8e9a3aa..ce30aa99 100644 --- a/src/main/java/org/qortal/api/model/ActivitySummary.java +++ b/src/main/java/org/qortal/api/model/ActivitySummary.java @@ -1,15 +1,14 @@ package org.qortal.api.model; -import java.util.Collections; -import java.util.EnumMap; -import java.util.Map; +import org.qortal.api.TransactionCountMapXmlAdapter; +import org.qortal.transaction.Transaction.TransactionType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import org.qortal.api.TransactionCountMapXmlAdapter; -import org.qortal.transaction.Transaction.TransactionType; +import java.util.Collections; +import java.util.EnumMap; +import java.util.Map; @XmlAccessorType(XmlAccessType.FIELD) public class ActivitySummary { diff --git a/src/main/java/org/qortal/api/model/AggregatedOrder.java b/src/main/java/org/qortal/api/model/AggregatedOrder.java index ff8ebfe2..f9c1d1ef 100644 --- a/src/main/java/org/qortal/api/model/AggregatedOrder.java +++ b/src/main/java/org/qortal/api/model/AggregatedOrder.java @@ -1,13 +1,13 @@ package org.qortal.api.model; +import org.qortal.data.asset.OrderData; + import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.data.asset.OrderData; - @XmlAccessorType(XmlAccessType.NONE) public class AggregatedOrder { diff --git a/src/main/java/org/qortal/api/model/AtCreationRequest.java b/src/main/java/org/qortal/api/model/AtCreationRequest.java index 14ccdaa2..43010775 100644 --- a/src/main/java/org/qortal/api/model/AtCreationRequest.java +++ b/src/main/java/org/qortal/api/model/AtCreationRequest.java @@ -1,14 +1,13 @@ package org.qortal.api.model; import io.swagger.v3.oas.annotations.media.Schema; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.DecoderException; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.util.encoders.DecoderException; - @XmlAccessorType(XmlAccessType.FIELD) public class AtCreationRequest { diff --git a/src/main/java/org/qortal/api/model/BlockSignerSummary.java b/src/main/java/org/qortal/api/model/BlockSignerSummary.java index 61961f28..479678be 100644 --- a/src/main/java/org/qortal/api/model/BlockSignerSummary.java +++ b/src/main/java/org/qortal/api/model/BlockSignerSummary.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import org.qortal.crypto.Crypto; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import org.qortal.crypto.Crypto; - @XmlAccessorType(XmlAccessType.FIELD) public class BlockSignerSummary { diff --git a/src/main/java/org/qortal/api/model/CrossChainBitcoinRedeemRequest.java b/src/main/java/org/qortal/api/model/CrossChainBitcoinRedeemRequest.java index 074fd24d..588cd243 100644 --- a/src/main/java/org/qortal/api/model/CrossChainBitcoinRedeemRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainBitcoinRedeemRequest.java @@ -1,11 +1,10 @@ package org.qortal.api.model; -import java.math.BigDecimal; +import io.swagger.v3.oas.annotations.media.Schema; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; - -import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainBitcoinRedeemRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainBitcoinRefundRequest.java b/src/main/java/org/qortal/api/model/CrossChainBitcoinRefundRequest.java index f2485389..4b1a0cea 100644 --- a/src/main/java/org/qortal/api/model/CrossChainBitcoinRefundRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainBitcoinRefundRequest.java @@ -1,11 +1,10 @@ package org.qortal.api.model; -import java.math.BigDecimal; +import io.swagger.v3.oas.annotations.media.Schema; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; - -import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainBitcoinRefundRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainBitcoinTemplateRequest.java b/src/main/java/org/qortal/api/model/CrossChainBitcoinTemplateRequest.java index b7510eaa..675581d2 100644 --- a/src/main/java/org/qortal/api/model/CrossChainBitcoinTemplateRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainBitcoinTemplateRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainBitcoinTemplateRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainBitcoinyHTLCStatus.java b/src/main/java/org/qortal/api/model/CrossChainBitcoinyHTLCStatus.java index 2772eae1..586c8e5e 100644 --- a/src/main/java/org/qortal/api/model/CrossChainBitcoinyHTLCStatus.java +++ b/src/main/java/org/qortal/api/model/CrossChainBitcoinyHTLCStatus.java @@ -1,11 +1,10 @@ package org.qortal.api.model; -import java.math.BigDecimal; +import io.swagger.v3.oas.annotations.media.Schema; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; - -import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainBitcoinyHTLCStatus { diff --git a/src/main/java/org/qortal/api/model/CrossChainBuildRequest.java b/src/main/java/org/qortal/api/model/CrossChainBuildRequest.java index e8d38703..e4fb8fdc 100644 --- a/src/main/java/org/qortal/api/model/CrossChainBuildRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainBuildRequest.java @@ -1,11 +1,11 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainBuildRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainCancelRequest.java b/src/main/java/org/qortal/api/model/CrossChainCancelRequest.java index 25a18952..ea2117ac 100644 --- a/src/main/java/org/qortal/api/model/CrossChainCancelRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainCancelRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainCancelRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainOfferSummary.java b/src/main/java/org/qortal/api/model/CrossChainOfferSummary.java index bf71c2d2..8f5fbc74 100644 --- a/src/main/java/org/qortal/api/model/CrossChainOfferSummary.java +++ b/src/main/java/org/qortal/api/model/CrossChainOfferSummary.java @@ -1,14 +1,13 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.crosschain.AcctMode; +import org.qortal.data.crosschain.CrossChainTradeData; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.crosschain.AcctMode; -import org.qortal.data.crosschain.CrossChainTradeData; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainOfferSummary { diff --git a/src/main/java/org/qortal/api/model/CrossChainSecretRequest.java b/src/main/java/org/qortal/api/model/CrossChainSecretRequest.java index 2db475e5..17a6274d 100644 --- a/src/main/java/org/qortal/api/model/CrossChainSecretRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainSecretRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainSecretRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainTradeRequest.java b/src/main/java/org/qortal/api/model/CrossChainTradeRequest.java index 1afd7290..60b49a03 100644 --- a/src/main/java/org/qortal/api/model/CrossChainTradeRequest.java +++ b/src/main/java/org/qortal/api/model/CrossChainTradeRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainTradeRequest { diff --git a/src/main/java/org/qortal/api/model/CrossChainTradeSummary.java b/src/main/java/org/qortal/api/model/CrossChainTradeSummary.java index edc137c0..0e12b8a4 100644 --- a/src/main/java/org/qortal/api/model/CrossChainTradeSummary.java +++ b/src/main/java/org/qortal/api/model/CrossChainTradeSummary.java @@ -1,13 +1,12 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.data.crosschain.CrossChainTradeData; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.data.crosschain.CrossChainTradeData; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainTradeSummary { diff --git a/src/main/java/org/qortal/api/model/GroupMembers.java b/src/main/java/org/qortal/api/model/GroupMembers.java index 1cd13efa..b2833779 100644 --- a/src/main/java/org/qortal/api/model/GroupMembers.java +++ b/src/main/java/org/qortal/api/model/GroupMembers.java @@ -1,12 +1,11 @@ package org.qortal.api.model; -import java.util.List; +import io.swagger.v3.oas.annotations.media.Schema; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; - -import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; @Schema(description = "Group info, maybe including members") // All properties to be converted to JSON via JAX-RS diff --git a/src/main/java/org/qortal/api/model/NameSummary.java b/src/main/java/org/qortal/api/model/NameSummary.java index 1e2caa87..63bc7158 100644 --- a/src/main/java/org/qortal/api/model/NameSummary.java +++ b/src/main/java/org/qortal/api/model/NameSummary.java @@ -1,11 +1,11 @@ package org.qortal.api.model; +import org.qortal.data.naming.NameData; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; -import org.qortal.data.naming.NameData; - @XmlAccessorType(XmlAccessType.NONE) public class NameSummary { diff --git a/src/main/java/org/qortal/api/model/NodeStatus.java b/src/main/java/org/qortal/api/model/NodeStatus.java index ab5e766e..16e407b8 100644 --- a/src/main/java/org/qortal/api/model/NodeStatus.java +++ b/src/main/java/org/qortal/api/model/NodeStatus.java @@ -1,13 +1,13 @@ package org.qortal.api.model; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - import org.qortal.controller.Controller; import org.qortal.controller.OnlineAccountsManager; import org.qortal.controller.Synchronizer; import org.qortal.network.Network; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + @XmlAccessorType(XmlAccessType.FIELD) public class NodeStatus { diff --git a/src/main/java/org/qortal/api/model/PollVotes.java b/src/main/java/org/qortal/api/model/PollVotes.java index c57ebc37..2768694f 100644 --- a/src/main/java/org/qortal/api/model/PollVotes.java +++ b/src/main/java/org/qortal/api/model/PollVotes.java @@ -1,13 +1,12 @@ package org.qortal.api.model; -import java.util.List; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.data.voting.VoteOnPollData; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; - -import io.swagger.v3.oas.annotations.media.Schema; - -import org.qortal.data.voting.VoteOnPollData; +import java.util.List; @Schema(description = "Poll vote info, including voters") // All properties to be converted to JSON via JAX-RS diff --git a/src/main/java/org/qortal/api/model/RewardShareKeyRequest.java b/src/main/java/org/qortal/api/model/RewardShareKeyRequest.java index 9448dba0..a3bcbdf5 100644 --- a/src/main/java/org/qortal/api/model/RewardShareKeyRequest.java +++ b/src/main/java/org/qortal/api/model/RewardShareKeyRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class RewardShareKeyRequest { diff --git a/src/main/java/org/qortal/api/model/SimpleForeignTransaction.java b/src/main/java/org/qortal/api/model/SimpleForeignTransaction.java index acc1120f..927f9baa 100644 --- a/src/main/java/org/qortal/api/model/SimpleForeignTransaction.java +++ b/src/main/java/org/qortal/api/model/SimpleForeignTransaction.java @@ -1,13 +1,12 @@ package org.qortal.api.model; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - @XmlAccessorType(XmlAccessType.FIELD) public class SimpleForeignTransaction { diff --git a/src/main/java/org/qortal/api/model/SimpleTransactionSignRequest.java b/src/main/java/org/qortal/api/model/SimpleTransactionSignRequest.java index 2ee80289..443e8b4b 100644 --- a/src/main/java/org/qortal/api/model/SimpleTransactionSignRequest.java +++ b/src/main/java/org/qortal/api/model/SimpleTransactionSignRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class SimpleTransactionSignRequest { diff --git a/src/main/java/org/qortal/api/model/TradeWithOrderInfo.java b/src/main/java/org/qortal/api/model/TradeWithOrderInfo.java index f773487b..c43856a7 100644 --- a/src/main/java/org/qortal/api/model/TradeWithOrderInfo.java +++ b/src/main/java/org/qortal/api/model/TradeWithOrderInfo.java @@ -1,14 +1,13 @@ package org.qortal.api.model; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.data.asset.OrderData; +import org.qortal.data.asset.TradeData; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; -import org.qortal.data.asset.OrderData; -import org.qortal.data.asset.TradeData; - -import io.swagger.v3.oas.annotations.media.Schema; - @Schema(description = "Asset trade, including order info") // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/api/model/crosschain/BitcoinSendRequest.java b/src/main/java/org/qortal/api/model/crosschain/BitcoinSendRequest.java index 86d3d7c8..0c5d089a 100644 --- a/src/main/java/org/qortal/api/model/crosschain/BitcoinSendRequest.java +++ b/src/main/java/org/qortal/api/model/crosschain/BitcoinSendRequest.java @@ -1,11 +1,11 @@ package org.qortal.api.model.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class BitcoinSendRequest { diff --git a/src/main/java/org/qortal/api/model/crosschain/DigibyteSendRequest.java b/src/main/java/org/qortal/api/model/crosschain/DigibyteSendRequest.java index a09c14a3..63c2f328 100644 --- a/src/main/java/org/qortal/api/model/crosschain/DigibyteSendRequest.java +++ b/src/main/java/org/qortal/api/model/crosschain/DigibyteSendRequest.java @@ -1,11 +1,11 @@ package org.qortal.api.model.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class DigibyteSendRequest { diff --git a/src/main/java/org/qortal/api/model/crosschain/LitecoinSendRequest.java b/src/main/java/org/qortal/api/model/crosschain/LitecoinSendRequest.java index 5f215740..79ee6ed2 100644 --- a/src/main/java/org/qortal/api/model/crosschain/LitecoinSendRequest.java +++ b/src/main/java/org/qortal/api/model/crosschain/LitecoinSendRequest.java @@ -1,11 +1,11 @@ package org.qortal.api.model.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class LitecoinSendRequest { diff --git a/src/main/java/org/qortal/api/model/crosschain/RavencoinSendRequest.java b/src/main/java/org/qortal/api/model/crosschain/RavencoinSendRequest.java index 0165b91d..a585bf45 100644 --- a/src/main/java/org/qortal/api/model/crosschain/RavencoinSendRequest.java +++ b/src/main/java/org/qortal/api/model/crosschain/RavencoinSendRequest.java @@ -1,11 +1,11 @@ package org.qortal.api.model.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class RavencoinSendRequest { diff --git a/src/main/java/org/qortal/api/model/crosschain/TradeBotCreateRequest.java b/src/main/java/org/qortal/api/model/crosschain/TradeBotCreateRequest.java index 1f96488e..09e58bcc 100644 --- a/src/main/java/org/qortal/api/model/crosschain/TradeBotCreateRequest.java +++ b/src/main/java/org/qortal/api/model/crosschain/TradeBotCreateRequest.java @@ -1,13 +1,12 @@ package org.qortal.api.model.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.crosschain.SupportedBlockchain; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.crosschain.SupportedBlockchain; - -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class TradeBotCreateRequest { diff --git a/src/main/java/org/qortal/api/model/crosschain/TradeBotRespondRequest.java b/src/main/java/org/qortal/api/model/crosschain/TradeBotRespondRequest.java index ecc8ed6f..25a4282b 100644 --- a/src/main/java/org/qortal/api/model/crosschain/TradeBotRespondRequest.java +++ b/src/main/java/org/qortal/api/model/crosschain/TradeBotRespondRequest.java @@ -1,10 +1,10 @@ package org.qortal.api.model.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import io.swagger.v3.oas.annotations.media.Schema; - @XmlAccessorType(XmlAccessType.FIELD) public class TradeBotRespondRequest { diff --git a/src/main/java/org/qortal/api/resource/AddressesResource.java b/src/main/java/org/qortal/api/resource/AddressesResource.java index 79cb6e05..688b17fc 100644 --- a/src/main/java/org/qortal/api/resource/AddressesResource.java +++ b/src/main/java/org/qortal/api/resource/AddressesResource.java @@ -1,5 +1,6 @@ package org.qortal.api.resource; +import com.google.common.primitives.Bytes; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -9,25 +10,9 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.account.Account; import org.qortal.account.PrivateKeyAccount; -import org.qortal.api.ApiError; -import org.qortal.api.ApiErrors; -import org.qortal.api.ApiException; -import org.qortal.api.ApiExceptionFactory; -import org.qortal.api.Security; +import org.qortal.api.*; import org.qortal.api.model.AccountPenaltyStats; import org.qortal.api.model.ApiOnlineAccount; import org.qortal.api.model.RewardShareKeyRequest; @@ -59,7 +44,15 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Amounts; import org.qortal.utils.Base58; -import com.google.common.primitives.Bytes; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; @Path("/addresses") @Tag(name = "Addresses") diff --git a/src/main/java/org/qortal/api/resource/AnnotationPostProcessor.java b/src/main/java/org/qortal/api/resource/AnnotationPostProcessor.java index 7b4a1ab2..da2fdc7c 100644 --- a/src/main/java/org/qortal/api/resource/AnnotationPostProcessor.java +++ b/src/main/java/org/qortal/api/resource/AnnotationPostProcessor.java @@ -13,12 +13,6 @@ import io.swagger.v3.oas.models.media.MediaType; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.responses.ApiResponse; - -import java.lang.reflect.Method; -import java.util.Locale; - -import javax.ws.rs.Path; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.api.ApiError; @@ -27,6 +21,10 @@ import org.qortal.api.ApiErrors; import org.qortal.api.ApiService; import org.qortal.globalization.Translator; +import javax.ws.rs.Path; +import java.lang.reflect.Method; +import java.util.Locale; + public class AnnotationPostProcessor implements ReaderListener { private static final Logger LOGGER = LogManager.getLogger(AnnotationPostProcessor.class); diff --git a/src/main/java/org/qortal/api/resource/ApiDefinition.java b/src/main/java/org/qortal/api/resource/ApiDefinition.java index f9ec7459..98db58c7 100644 --- a/src/main/java/org/qortal/api/resource/ApiDefinition.java +++ b/src/main/java/org/qortal/api/resource/ApiDefinition.java @@ -9,7 +9,6 @@ import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.security.SecurityScheme; import io.swagger.v3.oas.annotations.security.SecuritySchemes; import io.swagger.v3.oas.annotations.tags.Tag; - import org.qortal.api.Security; @OpenAPIDefinition( diff --git a/src/main/java/org/qortal/api/resource/ApiExceptionMapper.java b/src/main/java/org/qortal/api/resource/ApiExceptionMapper.java index d0f7ada7..15bb1913 100644 --- a/src/main/java/org/qortal/api/resource/ApiExceptionMapper.java +++ b/src/main/java/org/qortal/api/resource/ApiExceptionMapper.java @@ -1,5 +1,10 @@ package org.qortal.api.resource; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.glassfish.jersey.server.ParamException; +import org.qortal.settings.Settings; + import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.WebApplicationException; @@ -8,11 +13,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.glassfish.jersey.server.ParamException; -import org.qortal.settings.Settings; - @Provider public class ApiExceptionMapper implements ExceptionMapper { diff --git a/src/main/java/org/qortal/api/resource/AppsResource.java b/src/main/java/org/qortal/api/resource/AppsResource.java index 19a4a184..a5f50935 100644 --- a/src/main/java/org/qortal/api/resource/AppsResource.java +++ b/src/main/java/org/qortal/api/resource/AppsResource.java @@ -1,18 +1,20 @@ package org.qortal.api.resource; import com.google.common.io.Resources; +import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.tags.Tag; -import org.qortal.api.*; +import org.qortal.api.ApiError; +import org.qortal.api.ApiExceptionFactory; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.*; +import javax.ws.rs.GET; +import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.io.IOException; diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 441492a8..7752be8c 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -12,24 +12,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.io.*; -import java.net.FileNameMap; -import java.net.URLConnection; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.logging.log4j.LogManager; @@ -50,7 +32,10 @@ import org.qortal.controller.arbitrary.ArbitraryDataRenderManager; import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; import org.qortal.controller.arbitrary.ArbitraryMetadataManager; import org.qortal.data.account.AccountData; -import org.qortal.data.arbitrary.*; +import org.qortal.data.arbitrary.ArbitraryCategoryInfo; +import org.qortal.data.arbitrary.ArbitraryResourceData; +import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; @@ -68,6 +53,25 @@ import org.qortal.transform.transaction.ArbitraryTransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.*; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.FileNameMap; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + @Path("/arbitrary") @Tag(name = "Arbitrary") public class ArbitraryResource { diff --git a/src/main/java/org/qortal/api/resource/AssetsResource.java b/src/main/java/org/qortal/api/resource/AssetsResource.java index 8af91e45..40e04256 100644 --- a/src/main/java/org/qortal/api/resource/AssetsResource.java +++ b/src/main/java/org/qortal/api/resource/AssetsResource.java @@ -8,22 +8,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiException; @@ -39,27 +23,27 @@ import org.qortal.data.asset.AssetData; import org.qortal.data.asset.OrderData; import org.qortal.data.asset.RecentTradeData; import org.qortal.data.asset.TradeData; -import org.qortal.data.transaction.CancelAssetOrderTransactionData; -import org.qortal.data.transaction.CreateAssetOrderTransactionData; -import org.qortal.data.transaction.IssueAssetTransactionData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.data.transaction.TransferAssetTransactionData; -import org.qortal.data.transaction.UpdateAssetTransactionData; +import org.qortal.data.transaction.*; +import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; -import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.settings.Settings; import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transform.TransformationException; -import org.qortal.transform.transaction.CancelAssetOrderTransactionTransformer; -import org.qortal.transform.transaction.CreateAssetOrderTransactionTransformer; -import org.qortal.transform.transaction.IssueAssetTransactionTransformer; -import org.qortal.transform.transaction.TransferAssetTransactionTransformer; -import org.qortal.transform.transaction.UpdateAssetTransactionTransformer; +import org.qortal.transform.transaction.*; import org.qortal.utils.Base58; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + @Path("/assets") @Tag(name = "Assets") public class AssetsResource { diff --git a/src/main/java/org/qortal/api/resource/AtResource.java b/src/main/java/org/qortal/api/resource/AtResource.java index 13bfec83..a9661a1c 100644 --- a/src/main/java/org/qortal/api/resource/AtResource.java +++ b/src/main/java/org/qortal/api/resource/AtResource.java @@ -8,26 +8,14 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.ciyam.at.MachineState; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiException; import org.qortal.api.ApiExceptionFactory; +import org.qortal.api.model.AtCreationRequest; import org.qortal.data.at.ATData; import org.qortal.data.at.ATStateData; -import org.qortal.api.model.AtCreationRequest; import org.qortal.data.transaction.DeployAtTransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -38,10 +26,15 @@ import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.DeployAtTransactionTransformer; import org.qortal.utils.Base58; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; + @Path("/at") @Tag(name = "Automated Transactions") diff --git a/src/main/java/org/qortal/api/resource/BlocksResource.java b/src/main/java/org/qortal/api/resource/BlocksResource.java index ad5e466d..22b40a1f 100644 --- a/src/main/java/org/qortal/api/resource/BlocksResource.java +++ b/src/main/java/org/qortal/api/resource/BlocksResource.java @@ -8,26 +8,6 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.account.Account; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; @@ -35,7 +15,6 @@ import org.qortal.api.ApiExceptionFactory; import org.qortal.api.model.BlockMintingInfo; import org.qortal.api.model.BlockSignerSummary; import org.qortal.block.Block; -import org.qortal.controller.Controller; import org.qortal.crypto.Crypto; import org.qortal.data.account.AccountData; import org.qortal.data.block.BlockData; @@ -50,6 +29,23 @@ import org.qortal.transform.block.BlockTransformer; import org.qortal.utils.Base58; import org.qortal.utils.Triple; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + @Path("/blocks") @Tag(name = "Blocks") public class BlocksResource { diff --git a/src/main/java/org/qortal/api/resource/ChatResource.java b/src/main/java/org/qortal/api/resource/ChatResource.java index 22e90a43..66a2bd46 100644 --- a/src/main/java/org/qortal/api/resource/ChatResource.java +++ b/src/main/java/org/qortal/api/resource/ChatResource.java @@ -1,5 +1,6 @@ package org.qortal.api.resource; +import com.google.common.primitives.Bytes; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -9,14 +10,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; @@ -38,7 +31,11 @@ import org.qortal.transform.transaction.ChatTransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; -import com.google.common.primitives.Bytes; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; import static org.qortal.data.chat.ChatMessage.Encoding; diff --git a/src/main/java/org/qortal/api/resource/CrossChainBitcoinACCTv1Resource.java b/src/main/java/org/qortal/api/resource/CrossChainBitcoinACCTv1Resource.java index 6cfa130a..59472621 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainBitcoinACCTv1Resource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainBitcoinACCTv1Resource.java @@ -7,17 +7,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.Arrays; -import java.util.Random; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.account.PublicKeyAccount; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; @@ -27,9 +16,9 @@ import org.qortal.api.model.CrossChainBuildRequest; import org.qortal.api.model.CrossChainDualSecretRequest; import org.qortal.api.model.CrossChainTradeRequest; import org.qortal.asset.Asset; +import org.qortal.crosschain.AcctMode; import org.qortal.crosschain.BitcoinACCTv1; import org.qortal.crosschain.Bitcoiny; -import org.qortal.crosschain.AcctMode; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.crosschain.CrossChainTradeData; @@ -53,6 +42,15 @@ import org.qortal.transform.transaction.MessageTransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.Arrays; +import java.util.Random; + @Path("/crosschain/BitcoinACCTv1") @Tag(name = "Cross-Chain (BitcoinACCTv1)") public class CrossChainBitcoinACCTv1Resource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java index 1e276e59..efefd4c9 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java @@ -8,17 +8,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.bitcoinj.core.Transaction; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; @@ -29,6 +18,15 @@ import org.qortal.crosschain.Bitcoin; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.SimpleTransaction; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; + @Path("/crosschain/btc") @Tag(name = "Cross-Chain (Bitcoin)") public class CrossChainBitcoinResource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java b/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java index 781d78f6..60a4aa0d 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java @@ -8,17 +8,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.bitcoinj.core.Transaction; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; @@ -29,6 +18,15 @@ import org.qortal.crosschain.Digibyte; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.SimpleTransaction; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; + @Path("/crosschain/dgb") @Tag(name = "Cross-Chain (Digibyte)") public class CrossChainDigibyteResource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java index ff1d6d14..3c04b0e8 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java @@ -14,14 +14,14 @@ import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; import org.qortal.api.model.crosschain.DogecoinSendRequest; -import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Dogecoin; +import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.SimpleTransaction; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; -import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; diff --git a/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java b/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java index 45b92c7c..3f05643d 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java @@ -7,17 +7,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bitcoinj.core.*; @@ -35,6 +24,15 @@ import org.qortal.repository.RepositoryManager; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.math.BigDecimal; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + @Path("/crosschain/htlc") @Tag(name = "Cross-Chain (Hash time-locked contracts)") public class CrossChainHtlcResource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainLitecoinACCTv1Resource.java b/src/main/java/org/qortal/api/resource/CrossChainLitecoinACCTv1Resource.java index 7b6bc962..b768d8a1 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainLitecoinACCTv1Resource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainLitecoinACCTv1Resource.java @@ -24,11 +24,7 @@ import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.transaction.MessageTransaction; import org.qortal.transaction.Transaction.ValidationResult; -import org.qortal.transform.TransformationException; import org.qortal.transform.Transformer; -import org.qortal.transform.transaction.MessageTransactionTransformer; -import org.qortal.utils.Base58; -import org.qortal.utils.NTP; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.HeaderParam; @@ -37,7 +33,6 @@ import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.util.Arrays; -import java.util.Random; @Path("/crosschain/LitecoinACCTv1") @Tag(name = "Cross-Chain (LitecoinACCTv1)") diff --git a/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java index 3e2ff799..e96e27a7 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java @@ -8,17 +8,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.bitcoinj.core.Transaction; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; @@ -29,6 +18,15 @@ import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Litecoin; import org.qortal.crosschain.SimpleTransaction; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; + @Path("/crosschain/ltc") @Tag(name = "Cross-Chain (Litecoin)") public class CrossChainLitecoinResource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java b/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java index 6989e7c7..550b86b9 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java @@ -18,9 +18,9 @@ import org.qortal.crosschain.PirateChain; import org.qortal.crosschain.SimpleTransaction; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; -import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; diff --git a/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java index b1d6aed4..fc66ba8c 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java @@ -8,27 +8,25 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.bitcoinj.core.Transaction; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; import org.qortal.api.model.crosschain.RavencoinSendRequest; -import org.qortal.crosschain.Ravencoin; import org.qortal.crosschain.ForeignBlockchainException; +import org.qortal.crosschain.Ravencoin; import org.qortal.crosschain.SimpleTransaction; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; + @Path("/crosschain/rvn") @Tag(name = "Cross-Chain (Ravencoin)") public class CrossChainRavencoinResource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainResource.java b/src/main/java/org/qortal/api/resource/CrossChainResource.java index 44ef62ad..1161dc63 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainResource.java @@ -10,15 +10,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.*; -import java.util.function.Supplier; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; @@ -26,9 +17,9 @@ import org.qortal.api.Security; import org.qortal.api.model.CrossChainCancelRequest; import org.qortal.api.model.CrossChainTradeSummary; import org.qortal.controller.tradebot.TradeBot; -import org.qortal.crosschain.SupportedBlockchain; import org.qortal.crosschain.ACCT; import org.qortal.crosschain.AcctMode; +import org.qortal.crosschain.SupportedBlockchain; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.at.ATStateData; @@ -50,6 +41,13 @@ import org.qortal.utils.Base58; import org.qortal.utils.ByteArray; import org.qortal.utils.NTP; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.*; +import java.util.function.Supplier; + @Path("/crosschain") @Tag(name = "Cross-Chain") public class CrossChainResource { diff --git a/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java b/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java index aefca016..5a50222a 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java @@ -9,16 +9,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.api.ApiError; @@ -31,10 +21,10 @@ import org.qortal.asset.Asset; import org.qortal.controller.Controller; import org.qortal.controller.tradebot.AcctTradeBot; import org.qortal.controller.tradebot.TradeBot; -import org.qortal.crosschain.ForeignBlockchain; -import org.qortal.crosschain.SupportedBlockchain; import org.qortal.crosschain.ACCT; import org.qortal.crosschain.AcctMode; +import org.qortal.crosschain.ForeignBlockchain; +import org.qortal.crosschain.SupportedBlockchain; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.crosschain.CrossChainTradeData; @@ -48,6 +38,14 @@ import org.qortal.transaction.Transaction; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + @Path("/crosschain/tradebot") @Tag(name = "Cross-Chain (Trade-Bot)") public class CrossChainTradeBotResource { diff --git a/src/main/java/org/qortal/api/resource/GroupsResource.java b/src/main/java/org/qortal/api/resource/GroupsResource.java index 187687a9..7c3054e1 100644 --- a/src/main/java/org/qortal/api/resource/GroupsResource.java +++ b/src/main/java/org/qortal/api/resource/GroupsResource.java @@ -8,45 +8,14 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.model.GroupMembers; import org.qortal.api.model.GroupMembers.MemberInfo; import org.qortal.crypto.Crypto; -import org.qortal.data.group.GroupAdminData; -import org.qortal.data.group.GroupBanData; -import org.qortal.data.group.GroupData; -import org.qortal.data.group.GroupInviteData; -import org.qortal.data.group.GroupJoinRequestData; -import org.qortal.data.group.GroupMemberData; -import org.qortal.data.transaction.AddGroupAdminTransactionData; -import org.qortal.data.transaction.CancelGroupBanTransactionData; -import org.qortal.data.transaction.CancelGroupInviteTransactionData; -import org.qortal.data.transaction.CreateGroupTransactionData; -import org.qortal.data.transaction.GroupApprovalTransactionData; -import org.qortal.data.transaction.GroupBanTransactionData; -import org.qortal.data.transaction.GroupInviteTransactionData; -import org.qortal.data.transaction.GroupKickTransactionData; -import org.qortal.data.transaction.JoinGroupTransactionData; -import org.qortal.data.transaction.LeaveGroupTransactionData; -import org.qortal.data.transaction.RemoveGroupAdminTransactionData; -import org.qortal.data.transaction.SetGroupTransactionData; -import org.qortal.data.transaction.UpdateGroupTransactionData; +import org.qortal.data.group.*; +import org.qortal.data.transaction.*; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; @@ -54,21 +23,17 @@ import org.qortal.settings.Settings; import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transform.TransformationException; -import org.qortal.transform.transaction.AddGroupAdminTransactionTransformer; -import org.qortal.transform.transaction.CancelGroupBanTransactionTransformer; -import org.qortal.transform.transaction.CancelGroupInviteTransactionTransformer; -import org.qortal.transform.transaction.CreateGroupTransactionTransformer; -import org.qortal.transform.transaction.GroupApprovalTransactionTransformer; -import org.qortal.transform.transaction.GroupBanTransactionTransformer; -import org.qortal.transform.transaction.GroupInviteTransactionTransformer; -import org.qortal.transform.transaction.GroupKickTransactionTransformer; -import org.qortal.transform.transaction.JoinGroupTransactionTransformer; -import org.qortal.transform.transaction.LeaveGroupTransactionTransformer; -import org.qortal.transform.transaction.RemoveGroupAdminTransactionTransformer; -import org.qortal.transform.transaction.SetGroupTransactionTransformer; -import org.qortal.transform.transaction.UpdateGroupTransactionTransformer; +import org.qortal.transform.transaction.*; import org.qortal.utils.Base58; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + @Path("/groups") @Tag(name = "Groups") public class GroupsResource { diff --git a/src/main/java/org/qortal/api/resource/ListsResource.java b/src/main/java/org/qortal/api/resource/ListsResource.java index e0f558df..68747889 100644 --- a/src/main/java/org/qortal/api/resource/ListsResource.java +++ b/src/main/java/org/qortal/api/resource/ListsResource.java @@ -8,15 +8,12 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import org.qortal.api.*; +import org.qortal.api.ApiError; +import org.qortal.api.ApiErrors; +import org.qortal.api.ApiExceptionFactory; +import org.qortal.api.Security; import org.qortal.api.model.ListRequest; -import org.qortal.crypto.Crypto; -import org.qortal.data.account.AccountData; import org.qortal.list.ResourceListManager; -import org.qortal.repository.DataException; -import org.qortal.repository.Repository; -import org.qortal.repository.RepositoryManager; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; diff --git a/src/main/java/org/qortal/api/resource/NamesResource.java b/src/main/java/org/qortal/api/resource/NamesResource.java index 6cde26b3..c7d4a425 100644 --- a/src/main/java/org/qortal/api/resource/NamesResource.java +++ b/src/main/java/org/qortal/api/resource/NamesResource.java @@ -8,19 +8,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.util.List; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiException; @@ -29,11 +16,7 @@ import org.qortal.api.model.NameSummary; import org.qortal.controller.LiteNode; import org.qortal.crypto.Crypto; import org.qortal.data.naming.NameData; -import org.qortal.data.transaction.BuyNameTransactionData; -import org.qortal.data.transaction.CancelSellNameTransactionData; -import org.qortal.data.transaction.RegisterNameTransactionData; -import org.qortal.data.transaction.SellNameTransactionData; -import org.qortal.data.transaction.UpdateNameTransactionData; +import org.qortal.data.transaction.*; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; @@ -41,14 +24,17 @@ import org.qortal.settings.Settings; import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transform.TransformationException; -import org.qortal.transform.transaction.BuyNameTransactionTransformer; -import org.qortal.transform.transaction.CancelSellNameTransactionTransformer; -import org.qortal.transform.transaction.RegisterNameTransactionTransformer; -import org.qortal.transform.transaction.SellNameTransactionTransformer; -import org.qortal.transform.transaction.UpdateNameTransactionTransformer; +import org.qortal.transform.transaction.*; import org.qortal.utils.Base58; import org.qortal.utils.Unicode; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; +import java.util.stream.Collectors; + @Path("/names") @Tag(name = "Names") public class NamesResource { diff --git a/src/main/java/org/qortal/api/resource/PaymentsResource.java b/src/main/java/org/qortal/api/resource/PaymentsResource.java index 111a3fee..6bfa5d42 100644 --- a/src/main/java/org/qortal/api/resource/PaymentsResource.java +++ b/src/main/java/org/qortal/api/resource/PaymentsResource.java @@ -6,13 +6,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; @@ -27,6 +20,12 @@ import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.PaymentTransactionTransformer; import org.qortal.utils.Base58; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + @Path("/payments") @Tag(name = "Payments") public class PaymentsResource { diff --git a/src/main/java/org/qortal/api/resource/PeersResource.java b/src/main/java/org/qortal/api/resource/PeersResource.java index d89f99c4..4008d7ed 100644 --- a/src/main/java/org/qortal/api/resource/PeersResource.java +++ b/src/main/java/org/qortal/api/resource/PeersResource.java @@ -8,23 +8,11 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.LoggerConfig; -import org.apache.logging.log4j.core.LoggerContext; import org.qortal.api.*; import org.qortal.api.model.ConnectedPeer; import org.qortal.api.model.PeersSummary; @@ -42,6 +30,16 @@ import org.qortal.repository.RepositoryManager; import org.qortal.utils.ExecuteProduceConsume; import org.qortal.utils.NTP; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + @Path("/peers") @Tag(name = "Peers") public class PeersResource { diff --git a/src/main/java/org/qortal/api/resource/PollsResource.java b/src/main/java/org/qortal/api/resource/PollsResource.java index c64a8caf..aaa4f79c 100644 --- a/src/main/java/org/qortal/api/resource/PollsResource.java +++ b/src/main/java/org/qortal/api/resource/PollsResource.java @@ -1,6 +1,8 @@ package org.qortal.api.resource; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; @@ -8,10 +10,14 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; +import org.qortal.api.ApiException; import org.qortal.api.ApiExceptionFactory; +import org.qortal.api.model.PollVotes; import org.qortal.data.transaction.CreatePollTransactionData; -import org.qortal.data.transaction.PaymentTransactionData; import org.qortal.data.transaction.VoteOnPollTransactionData; +import org.qortal.data.voting.PollData; +import org.qortal.data.voting.PollOptionData; +import org.qortal.data.voting.VoteOnPollData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; @@ -19,30 +25,17 @@ import org.qortal.settings.Settings; import org.qortal.transaction.Transaction; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.CreatePollTransactionTransformer; -import org.qortal.transform.transaction.PaymentTransactionTransformer; import org.qortal.transform.transaction.VoteOnPollTransactionTransformer; import org.qortal.utils.Base58; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.POST; -import javax.ws.rs.Path; +import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; - -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.ArraySchema; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import javax.ws.rs.GET; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import org.qortal.api.ApiException; -import org.qortal.api.model.PollVotes; -import org.qortal.data.voting.PollData; -import org.qortal.data.voting.PollOptionData; -import org.qortal.data.voting.VoteOnPollData; @Path("/polls") @Tag(name = "Polls") diff --git a/src/main/java/org/qortal/api/resource/StatsResource.java b/src/main/java/org/qortal/api/resource/StatsResource.java index c1588490..35761cf4 100644 --- a/src/main/java/org/qortal/api/resource/StatsResource.java +++ b/src/main/java/org/qortal/api/resource/StatsResource.java @@ -7,7 +7,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.qortal.api.*; +import org.qortal.api.ApiError; +import org.qortal.api.ApiExceptionFactory; import org.qortal.block.BlockChain; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -15,7 +16,8 @@ import org.qortal.repository.RepositoryManager; import org.qortal.utils.Amounts; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; +import javax.ws.rs.GET; +import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.math.BigDecimal; diff --git a/src/main/java/org/qortal/api/resource/TransactionsResource.java b/src/main/java/org/qortal/api/resource/TransactionsResource.java index 61cef867..ca2404ea 100644 --- a/src/main/java/org/qortal/api/resource/TransactionsResource.java +++ b/src/main/java/org/qortal/api/resource/TransactionsResource.java @@ -1,5 +1,6 @@ package org.qortal.api.resource; +import com.google.common.primitives.Bytes; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -8,22 +9,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.io.IOException; -import java.io.StringWriter; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantLock; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.account.PrivateKeyAccount; import org.qortal.api.*; import org.qortal.api.model.SimpleTransactionSignRequest; @@ -42,10 +27,22 @@ import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; - -import com.google.common.primitives.Bytes; import org.qortal.utils.NTP; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.io.StringWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + @Path("/transactions") @Tag(name = "Transactions") public class TransactionsResource { diff --git a/src/main/java/org/qortal/api/resource/UtilsResource.java b/src/main/java/org/qortal/api/resource/UtilsResource.java index 54ea660b..097a321e 100644 --- a/src/main/java/org/qortal/api/resource/UtilsResource.java +++ b/src/main/java/org/qortal/api/resource/UtilsResource.java @@ -1,5 +1,6 @@ package org.qortal.api.resource; +import com.google.common.hash.HashCode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; @@ -7,22 +8,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Base64; -import java.util.List; -import java.util.UUID; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.qortal.account.PrivateKeyAccount; import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; @@ -35,9 +20,13 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer.Transformation; import org.qortal.utils.Base58; -import com.google.common.hash.HashCode; -import com.google.common.primitives.Bytes; -import com.google.common.primitives.Longs; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.security.SecureRandom; +import java.util.Base64; +import java.util.List; @Path("/utils") @Tag(name = "Utilities") diff --git a/src/main/java/org/qortal/api/restricted/resource/AdminResource.java b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java index 178d7547..57bf59c0 100644 --- a/src/main/java/org/qortal/api/restricted/resource/AdminResource.java +++ b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java @@ -1,5 +1,6 @@ package org.qortal.api.restricted.resource; +import com.google.common.collect.Lists; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -10,23 +11,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -57,7 +41,20 @@ import org.qortal.settings.Settings; import org.qortal.utils.Base58; import org.qortal.utils.NTP; -import com.google.common.collect.Lists; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; @Path("/admin") @Tag(name = "Admin") diff --git a/src/main/java/org/qortal/api/restricted/resource/BootstrapResource.java b/src/main/java/org/qortal/api/restricted/resource/BootstrapResource.java index 47b7cf42..dc12161d 100644 --- a/src/main/java/org/qortal/api/restricted/resource/BootstrapResource.java +++ b/src/main/java/org/qortal/api/restricted/resource/BootstrapResource.java @@ -17,10 +17,12 @@ import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import java.io.IOException; @Path("/bootstrap") diff --git a/src/main/java/org/qortal/api/restricted/resource/RenderResource.java b/src/main/java/org/qortal/api/restricted/resource/RenderResource.java index 92f72032..5eb169a4 100644 --- a/src/main/java/org/qortal/api/restricted/resource/RenderResource.java +++ b/src/main/java/org/qortal/api/restricted/resource/RenderResource.java @@ -1,35 +1,22 @@ package org.qortal.api.restricted.resource; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.api.Security; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; +import org.qortal.arbitrary.ArbitraryDataRenderer; +import org.qortal.arbitrary.ArbitraryDataResource; +import org.qortal.arbitrary.misc.Service; +import org.qortal.controller.arbitrary.ArbitraryDataRenderManager; +import org.qortal.settings.Settings; + import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.*; import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import java.io.*; -import java.nio.file.Paths; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.parameters.RequestBody; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.security.SecurityRequirement; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.qortal.api.ApiError; -import org.qortal.api.ApiExceptionFactory; -import org.qortal.api.Security; -import org.qortal.arbitrary.misc.Service; -import org.qortal.arbitrary.*; -import org.qortal.arbitrary.exception.MissingDataException; -import org.qortal.controller.arbitrary.ArbitraryDataRenderManager; -import org.qortal.data.transaction.ArbitraryTransactionData.*; -import org.qortal.repository.DataException; -import org.qortal.arbitrary.ArbitraryDataFile.*; -import org.qortal.settings.Settings; -import org.qortal.utils.Base58; @Path("/render") diff --git a/src/main/java/org/qortal/api/websocket/ActiveChatsWebSocket.java b/src/main/java/org/qortal/api/websocket/ActiveChatsWebSocket.java index 9ac9f87d..b92fb19f 100644 --- a/src/main/java/org/qortal/api/websocket/ActiveChatsWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/ActiveChatsWebSocket.java @@ -1,19 +1,8 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; - import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketException; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.controller.ChatNotifier; import org.qortal.crypto.Crypto; @@ -23,6 +12,13 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; +import java.io.IOException; +import java.io.StringWriter; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + import static org.qortal.data.chat.ChatMessage.Encoding; @WebSocket diff --git a/src/main/java/org/qortal/api/websocket/AdminStatusWebSocket.java b/src/main/java/org/qortal/api/websocket/AdminStatusWebSocket.java index 6556d140..4d65956e 100644 --- a/src/main/java/org/qortal/api/websocket/AdminStatusWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/AdminStatusWebSocket.java @@ -1,16 +1,8 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.concurrent.atomic.AtomicReference; - import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketException; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.api.model.NodeStatus; import org.qortal.controller.Controller; @@ -18,6 +10,10 @@ import org.qortal.event.Event; import org.qortal.event.EventBus; import org.qortal.event.Listener; +import java.io.IOException; +import java.io.StringWriter; +import java.util.concurrent.atomic.AtomicReference; + @WebSocket @SuppressWarnings("serial") public class AdminStatusWebSocket extends ApiWebSocket implements Listener { diff --git a/src/main/java/org/qortal/api/websocket/ApiWebSocket.java b/src/main/java/org/qortal/api/websocket/ApiWebSocket.java index f6a439ea..d402250f 100644 --- a/src/main/java/org/qortal/api/websocket/ApiWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/ApiWebSocket.java @@ -1,18 +1,5 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; - import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; @@ -22,6 +9,14 @@ import org.eclipse.persistence.jaxb.MarshallerProperties; import org.qortal.api.ApiError; import org.qortal.api.ApiErrorRoot; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.*; + @SuppressWarnings("serial") abstract class ApiWebSocket extends WebSocketServlet { diff --git a/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java b/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java index 20847b7b..01235755 100644 --- a/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java @@ -1,16 +1,8 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.List; - import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketException; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.api.ApiError; import org.qortal.controller.Controller; @@ -24,6 +16,10 @@ import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.utils.Base58; +import java.io.IOException; +import java.io.StringWriter; +import java.util.List; + @WebSocket @SuppressWarnings("serial") public class BlocksWebSocket extends ApiWebSocket implements Listener { diff --git a/src/main/java/org/qortal/api/websocket/ChatMessagesWebSocket.java b/src/main/java/org/qortal/api/websocket/ChatMessagesWebSocket.java index 3046c1c1..4340ad58 100644 --- a/src/main/java/org/qortal/api/websocket/ChatMessagesWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/ChatMessagesWebSocket.java @@ -1,16 +1,8 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.*; - import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketException; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.controller.ChatNotifier; import org.qortal.data.chat.ChatMessage; @@ -19,6 +11,10 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; +import java.io.IOException; +import java.io.StringWriter; +import java.util.*; + import static org.qortal.data.chat.ChatMessage.Encoding; @WebSocket diff --git a/src/main/java/org/qortal/api/websocket/PresenceWebSocket.java b/src/main/java/org/qortal/api/websocket/PresenceWebSocket.java index c579ac86..510b712f 100644 --- a/src/main/java/org/qortal/api/websocket/PresenceWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/PresenceWebSocket.java @@ -1,23 +1,7 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.controller.Controller; import org.qortal.controller.Synchronizer; @@ -35,6 +19,13 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.io.IOException; +import java.io.StringWriter; +import java.util.*; +import java.util.stream.Collectors; + @WebSocket @SuppressWarnings("serial") public class PresenceWebSocket extends ApiWebSocket implements Listener { diff --git a/src/main/java/org/qortal/api/websocket/TradeBotWebSocket.java b/src/main/java/org/qortal/api/websocket/TradeBotWebSocket.java index 8d7a13cd..7746f8f8 100644 --- a/src/main/java/org/qortal/api/websocket/TradeBotWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/TradeBotWebSocket.java @@ -1,16 +1,7 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.*; -import java.util.stream.Collectors; - import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.controller.tradebot.TradeBot; import org.qortal.crosschain.SupportedBlockchain; @@ -23,6 +14,11 @@ import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.utils.Base58; +import java.io.IOException; +import java.io.StringWriter; +import java.util.*; +import java.util.stream.Collectors; + @WebSocket @SuppressWarnings("serial") public class TradeBotWebSocket extends ApiWebSocket implements Listener { diff --git a/src/main/java/org/qortal/api/websocket/TradeOffersWebSocket.java b/src/main/java/org/qortal/api/websocket/TradeOffersWebSocket.java index 9c48b018..3f61fb98 100644 --- a/src/main/java/org/qortal/api/websocket/TradeOffersWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/TradeOffersWebSocket.java @@ -1,33 +1,16 @@ package org.qortal.api.websocket; -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.api.model.CrossChainOfferSummary; -import org.qortal.controller.Controller; import org.qortal.controller.Synchronizer; import org.qortal.controller.tradebot.TradeBot; -import org.qortal.crosschain.SupportedBlockchain; import org.qortal.crosschain.ACCT; import org.qortal.crosschain.AcctMode; +import org.qortal.crosschain.SupportedBlockchain; import org.qortal.data.at.ATStateData; import org.qortal.data.block.BlockData; import org.qortal.data.crosschain.CrossChainTradeData; @@ -40,6 +23,13 @@ import org.qortal.repository.RepositoryManager; import org.qortal.utils.ByteArray; import org.qortal.utils.NTP; +import java.io.IOException; +import java.io.StringWriter; +import java.util.*; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + @WebSocket @SuppressWarnings("serial") public class TradeOffersWebSocket extends ApiWebSocket implements Listener { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java index 465d1391..bab4cc38 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java @@ -1,7 +1,7 @@ package org.qortal.arbitrary; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.exception.MissingDataException; -import org.qortal.arbitrary.ArbitraryDataFile.*; import org.qortal.arbitrary.misc.Service; import org.qortal.repository.DataException; import org.qortal.utils.ArbitraryTransactionUtils; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java index fba6a32b..f438cef6 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java @@ -2,6 +2,7 @@ package org.qortal.arbitrary; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.exception.DataNotPublishedException; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataCache; @@ -11,7 +12,6 @@ import org.qortal.data.transaction.ArbitraryTransactionData.Method; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; -import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.settings.Settings; import org.qortal.utils.Base58; import org.qortal.utils.NTP; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataCache.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataCache.java index accd808d..a6a63e5f 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataCache.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataCache.java @@ -1,6 +1,6 @@ package org.qortal.arbitrary; -import org.qortal.arbitrary.ArbitraryDataFile.*; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataCache; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.arbitrary.ArbitraryDataManager; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java index 93bc9636..13e22964 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java @@ -9,10 +9,14 @@ import org.qortal.crypto.Crypto; import org.qortal.repository.DataException; import org.qortal.settings.Settings; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; public class ArbitraryDataDiff { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java index eab5c828..d3e31c1d 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java @@ -3,7 +3,8 @@ package org.qortal.arbitrary; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.qortal.arbitrary.ArbitraryDataDiff.*; +import org.qortal.arbitrary.ArbitraryDataDiff.DiffType; +import org.qortal.arbitrary.ArbitraryDataDiff.ModifiedPath; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch; import org.qortal.arbitrary.patch.UnifiedDiffPatch; import org.qortal.repository.DataException; @@ -12,7 +13,10 @@ import org.qortal.utils.FilesystemUtils; import java.io.File; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.List; import java.util.UUID; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java index 8896f44f..09154a32 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java @@ -3,7 +3,7 @@ package org.qortal.arbitrary; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.exception.DataNotPublishedException; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.misc.Service; @@ -11,11 +11,11 @@ import org.qortal.controller.arbitrary.ArbitraryDataBuildManager; import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.crypto.AES; import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.ArbitraryTransactionData.*; +import org.qortal.data.transaction.ArbitraryTransactionData.Compression; +import org.qortal.data.transaction.ArbitraryTransactionData.DataType; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; -import org.qortal.arbitrary.ArbitraryDataFile.*; import org.qortal.settings.Settings; import org.qortal.transform.Transformer; import org.qortal.utils.*; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java index 0f513403..9d20df14 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataRenderer.java @@ -6,7 +6,7 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.api.HTMLParser; -import org.qortal.arbitrary.ArbitraryDataFile.*; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.Controller; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java index c32734dc..9cfc686a 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java @@ -2,9 +2,10 @@ package org.qortal.arbitrary; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.qortal.arbitrary.exception.MissingDataException; +import org.qortal.arbitrary.ArbitraryDataDiff.DiffType; +import org.qortal.arbitrary.ArbitraryDataDiff.ModifiedPath; import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; -import org.qortal.arbitrary.ArbitraryDataDiff.*; +import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Category; @@ -13,7 +14,9 @@ import org.qortal.crypto.AES; import org.qortal.crypto.Crypto; import org.qortal.data.PaymentData; import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.ArbitraryTransactionData.*; +import org.qortal.data.transaction.ArbitraryTransactionData.Compression; +import org.qortal.data.transaction.ArbitraryTransactionData.DataType; +import org.qortal.data.transaction.ArbitraryTransactionData.Method; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.group.Group; import org.qortal.repository.DataException; diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataWriter.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataWriter.java index db29ee20..0098e4fa 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataWriter.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataWriter.java @@ -5,15 +5,16 @@ import com.j256.simplemagic.ContentInfoUtil; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.qortal.arbitrary.ArbitraryDataFile.ValidationResult; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; -import org.qortal.crypto.Crypto; -import org.qortal.data.transaction.ArbitraryTransactionData.*; import org.qortal.crypto.AES; +import org.qortal.crypto.Crypto; +import org.qortal.data.transaction.ArbitraryTransactionData.Compression; +import org.qortal.data.transaction.ArbitraryTransactionData.Method; import org.qortal.repository.DataException; -import org.qortal.arbitrary.ArbitraryDataFile.*; import org.qortal.settings.Settings; import org.qortal.utils.Base58; import org.qortal.utils.FilesystemUtils; @@ -27,11 +28,15 @@ import java.io.File; import java.io.IOException; import java.net.FileNameMap; import java.net.URLConnection; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; diff --git a/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataMetadataPatch.java b/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataMetadataPatch.java index 46a1f57e..200df844 100644 --- a/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataMetadataPatch.java +++ b/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataMetadataPatch.java @@ -5,7 +5,7 @@ import org.apache.logging.log4j.Logger; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.qortal.arbitrary.ArbitraryDataDiff.*; +import org.qortal.arbitrary.ArbitraryDataDiff.ModifiedPath; import org.qortal.repository.DataException; import org.qortal.utils.Base58; diff --git a/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataQortalMetadata.java b/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataQortalMetadata.java index eb3d6cc9..c1e6563d 100644 --- a/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataQortalMetadata.java +++ b/src/main/java/org/qortal/arbitrary/metadata/ArbitraryDataQortalMetadata.java @@ -2,7 +2,6 @@ package org.qortal.arbitrary.metadata; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.json.JSONException; import org.qortal.repository.DataException; import java.io.BufferedWriter; diff --git a/src/main/java/org/qortal/arbitrary/misc/Service.java b/src/main/java/org/qortal/arbitrary/misc/Service.java index 2b8f8d02..02a513fd 100644 --- a/src/main/java/org/qortal/arbitrary/misc/Service.java +++ b/src/main/java/org/qortal/arbitrary/misc/Service.java @@ -1,5 +1,6 @@ package org.qortal.arbitrary.misc; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.FilenameUtils; import org.json.JSONObject; import org.qortal.arbitrary.ArbitraryDataRenderer; @@ -13,8 +14,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; -import com.fasterxml.jackson.databind.ObjectMapper; - import static java.util.Arrays.stream; import static java.util.stream.Collectors.toMap; diff --git a/src/main/java/org/qortal/asset/Order.java b/src/main/java/org/qortal/asset/Order.java index 953ff6ac..77affe55 100644 --- a/src/main/java/org/qortal/asset/Order.java +++ b/src/main/java/org/qortal/asset/Order.java @@ -1,11 +1,5 @@ package org.qortal.asset; -import static org.qortal.utils.Amounts.prettyAmount; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.List; - import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -19,6 +13,12 @@ import org.qortal.repository.Repository; import org.qortal.utils.Amounts; import org.qortal.utils.Base58; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; + +import static org.qortal.utils.Amounts.prettyAmount; + public class Order { private static final Logger LOGGER = LogManager.getLogger(Order.class); diff --git a/src/main/java/org/qortal/at/AT.java b/src/main/java/org/qortal/at/AT.java index 005bb0cd..e5cbf4e7 100644 --- a/src/main/java/org/qortal/at/AT.java +++ b/src/main/java/org/qortal/at/AT.java @@ -1,9 +1,5 @@ package org.qortal.at; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.ciyam.at.MachineState; import org.ciyam.at.Timestamp; import org.qortal.crypto.Crypto; @@ -15,6 +11,10 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.transaction.AtTransaction; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + public class AT { // Properties diff --git a/src/main/java/org/qortal/at/QortalATAPI.java b/src/main/java/org/qortal/at/QortalATAPI.java index 829c391f..93dac568 100644 --- a/src/main/java/org/qortal/at/QortalATAPI.java +++ b/src/main/java/org/qortal/at/QortalATAPI.java @@ -1,18 +1,9 @@ package org.qortal.at; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - +import com.google.common.primitives.Bytes; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.ciyam.at.API; -import org.ciyam.at.ExecutionException; -import org.ciyam.at.FunctionData; -import org.ciyam.at.IllegalFunctionCodeException; -import org.ciyam.at.MachineState; -import org.ciyam.at.OpCode; -import org.ciyam.at.Timestamp; +import org.ciyam.at.*; import org.qortal.account.Account; import org.qortal.account.NullAccount; import org.qortal.account.PublicKeyAccount; @@ -23,22 +14,20 @@ import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.block.BlockData; import org.qortal.data.block.BlockSummaryData; -import org.qortal.data.transaction.ATTransactionData; -import org.qortal.data.transaction.BaseTransactionData; -import org.qortal.data.transaction.MessageTransactionData; -import org.qortal.data.transaction.PaymentTransactionData; -import org.qortal.data.transaction.TransactionData; +import org.qortal.data.transaction.*; import org.qortal.group.Group; import org.qortal.repository.ATRepository; +import org.qortal.repository.ATRepository.NextTransactionInfo; import org.qortal.repository.DataException; import org.qortal.repository.Repository; -import org.qortal.repository.ATRepository.NextTransactionInfo; import org.qortal.transaction.AtTransaction; import org.qortal.transaction.Transaction.TransactionType; import org.qortal.utils.Base58; import org.qortal.utils.BitTwiddling; -import com.google.common.primitives.Bytes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class QortalATAPI extends API { diff --git a/src/main/java/org/qortal/at/QortalFunctionCode.java b/src/main/java/org/qortal/at/QortalFunctionCode.java index a2d43ac8..152f310e 100644 --- a/src/main/java/org/qortal/at/QortalFunctionCode.java +++ b/src/main/java/org/qortal/at/QortalFunctionCode.java @@ -1,9 +1,5 @@ package org.qortal.at; -import java.util.Arrays; -import java.util.Map; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.ciyam.at.ExecutionException; @@ -17,6 +13,10 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.settings.Settings; +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + /** * Qortal-specific CIYAM-AT Functions. *

diff --git a/src/main/java/org/qortal/block/Block.java b/src/main/java/org/qortal/block/Block.java index 16c061da..51d55eb4 100644 --- a/src/main/java/org/qortal/block/Block.java +++ b/src/main/java/org/qortal/block/Block.java @@ -1,19 +1,8 @@ package org.qortal.block; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.RoundingMode; -import java.nio.charset.StandardCharsets; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.*; -import java.util.stream.Collectors; - +import com.google.common.primitives.Bytes; +import com.google.common.primitives.Longs; +import io.druid.extendedset.intset.ConciseSet; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -23,16 +12,12 @@ import org.qortal.account.PrivateKeyAccount; import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; import org.qortal.at.AT; -import org.qortal.block.BlockChain.BlockTimingByHeight; import org.qortal.block.BlockChain.AccountLevelShareBin; +import org.qortal.block.BlockChain.BlockTimingByHeight; import org.qortal.controller.OnlineAccountsManager; import org.qortal.crypto.Crypto; import org.qortal.crypto.Qortal25519Extras; -import org.qortal.data.account.AccountBalanceData; -import org.qortal.data.account.AccountData; -import org.qortal.data.account.EligibleQoraHolderData; -import org.qortal.data.account.QortFromQoraData; -import org.qortal.data.account.RewardShareData; +import org.qortal.data.account.*; import org.qortal.data.at.ATData; import org.qortal.data.at.ATStateData; import org.qortal.data.block.BlockData; @@ -56,10 +41,19 @@ import org.qortal.utils.Amounts; import org.qortal.utils.Base58; import org.qortal.utils.NTP; -import com.google.common.primitives.Bytes; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.*; +import java.util.stream.Collectors; -import io.druid.extendedset.intset.ConciseSet; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; public class Block { diff --git a/src/main/java/org/qortal/block/Block212937.java b/src/main/java/org/qortal/block/Block212937.java index a53c9d31..a7cc42e8 100644 --- a/src/main/java/org/qortal/block/Block212937.java +++ b/src/main/java/org/qortal/block/Block212937.java @@ -1,15 +1,5 @@ package org.qortal.block; -import java.io.InputStream; -import java.util.List; -import java.util.stream.Collectors; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.UnmarshalException; -import javax.xml.bind.Unmarshaller; -import javax.xml.transform.stream.StreamSource; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.persistence.jaxb.JAXBContextFactory; @@ -17,6 +7,15 @@ import org.eclipse.persistence.jaxb.UnmarshallerProperties; import org.qortal.data.account.AccountBalanceData; import org.qortal.repository.DataException; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.UnmarshalException; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.stream.StreamSource; +import java.io.InputStream; +import java.util.List; +import java.util.stream.Collectors; + /** * Block 212937 *

diff --git a/src/main/java/org/qortal/block/BlockChain.java b/src/main/java/org/qortal/block/BlockChain.java index 540e6cf4..4dcc148d 100644 --- a/src/main/java/org/qortal/block/BlockChain.java +++ b/src/main/java/org/qortal/block/BlockChain.java @@ -1,21 +1,5 @@ package org.qortal.block; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.sql.SQLException; -import java.util.*; -import java.util.concurrent.locks.ReentrantLock; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.UnmarshalException; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.transform.stream.StreamSource; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.persistence.exceptions.XMLMarshalException; @@ -29,6 +13,21 @@ import org.qortal.settings.Settings; import org.qortal.utils.Base58; import org.qortal.utils.StringLongMapXmlAdapter; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.UnmarshalException; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.locks.ReentrantLock; + /** * Class representing the blockchain as a whole. * diff --git a/src/main/java/org/qortal/block/GenesisBlock.java b/src/main/java/org/qortal/block/GenesisBlock.java index 4d4c407a..991db4b5 100644 --- a/src/main/java/org/qortal/block/GenesisBlock.java +++ b/src/main/java/org/qortal/block/GenesisBlock.java @@ -1,15 +1,8 @@ package org.qortal.block; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - +import com.google.common.primitives.Bytes; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.NullAccount; @@ -24,9 +17,14 @@ import org.qortal.transaction.Transaction.ApprovalStatus; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.TransactionTransformer; -import com.google.common.primitives.Bytes; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; public class GenesisBlock extends Block { diff --git a/src/main/java/org/qortal/block/SelfSponsorshipAlgoV1Block.java b/src/main/java/org/qortal/block/SelfSponsorshipAlgoV1Block.java index a9a016b6..c3c374d1 100644 --- a/src/main/java/org/qortal/block/SelfSponsorshipAlgoV1Block.java +++ b/src/main/java/org/qortal/block/SelfSponsorshipAlgoV1Block.java @@ -13,7 +13,10 @@ import org.qortal.repository.Repository; import org.qortal.utils.Base58; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; /** diff --git a/src/main/java/org/qortal/controller/AutoUpdate.java b/src/main/java/org/qortal/controller/AutoUpdate.java index fde52fb1..bc232e1b 100644 --- a/src/main/java/org/qortal/controller/AutoUpdate.java +++ b/src/main/java/org/qortal/controller/AutoUpdate.java @@ -1,5 +1,22 @@ package org.qortal.controller; +import com.google.common.hash.HashCode; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.ApplyUpdate; +import org.qortal.api.ApiRequest; +import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.data.transaction.TransactionData; +import org.qortal.globalization.Translator; +import org.qortal.gui.SysTray; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; +import org.qortal.settings.Settings; +import org.qortal.transaction.ArbitraryTransaction; +import org.qortal.transaction.Transaction.TransactionType; +import org.qortal.transform.Transformer; + import java.awt.TrayIcon.MessageType; import java.io.IOException; import java.io.InputStream; @@ -17,24 +34,6 @@ import java.util.List; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.qortal.ApplyUpdate; -import org.qortal.api.ApiRequest; -import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.globalization.Translator; -import org.qortal.gui.SysTray; -import org.qortal.repository.DataException; -import org.qortal.repository.Repository; -import org.qortal.repository.RepositoryManager; -import org.qortal.settings.Settings; -import org.qortal.transaction.ArbitraryTransaction; -import org.qortal.transaction.Transaction.TransactionType; -import org.qortal.transform.Transformer; - -import com.google.common.hash.HashCode; - /* NOTE: It is CRITICAL that we use OpenJDK and not Java SE because our uber jar repacks BouncyCastle which, in turn, unsigns BC causing it to be rejected as a security provider by Java SE. */ public class AutoUpdate extends Thread { diff --git a/src/main/java/org/qortal/controller/BlockMinter.java b/src/main/java/org/qortal/controller/BlockMinter.java index 35c89778..15660f97 100644 --- a/src/main/java/org/qortal/controller/BlockMinter.java +++ b/src/main/java/org/qortal/controller/BlockMinter.java @@ -1,16 +1,5 @@ package org.qortal.controller; -import java.math.BigInteger; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; @@ -35,6 +24,17 @@ import org.qortal.transaction.Transaction; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; + import static org.junit.Assert.assertNotNull; // Minting new blocks diff --git a/src/main/java/org/qortal/controller/ChatNotifier.java b/src/main/java/org/qortal/controller/ChatNotifier.java index 61146faa..abfcee0d 100644 --- a/src/main/java/org/qortal/controller/ChatNotifier.java +++ b/src/main/java/org/qortal/controller/ChatNotifier.java @@ -1,13 +1,13 @@ package org.qortal.controller; +import org.eclipse.jetty.websocket.api.Session; +import org.qortal.data.transaction.ChatTransactionData; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.eclipse.jetty.websocket.api.Session; -import org.qortal.data.transaction.ChatTransactionData; - public class ChatNotifier { private static ChatNotifier instance; diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index bbf72038..6d2562ab 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -1,30 +1,5 @@ package org.qortal.controller; -import java.awt.TrayIcon.MessageType; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.Security; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -38,8 +13,8 @@ import org.qortal.block.Block; import org.qortal.block.BlockChain; import org.qortal.block.BlockChain.BlockTimingByHeight; import org.qortal.controller.arbitrary.*; -import org.qortal.controller.repository.PruneManager; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; +import org.qortal.controller.repository.PruneManager; import org.qortal.controller.tradebot.TradeBot; import org.qortal.data.account.AccountBalanceData; import org.qortal.data.account.AccountData; @@ -66,6 +41,30 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.*; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.awt.TrayIcon.MessageType; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.Security; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + public class Controller extends Thread { static { diff --git a/src/main/java/org/qortal/controller/OnlineAccountsManager.java b/src/main/java/org/qortal/controller/OnlineAccountsManager.java index 25cace2f..17501a75 100644 --- a/src/main/java/org/qortal/controller/OnlineAccountsManager.java +++ b/src/main/java/org/qortal/controller/OnlineAccountsManager.java @@ -16,7 +16,9 @@ import org.qortal.data.account.RewardShareData; import org.qortal.data.network.OnlineAccountData; import org.qortal.network.Network; import org.qortal.network.Peer; -import org.qortal.network.message.*; +import org.qortal.network.message.GetOnlineAccountsV3Message; +import org.qortal.network.message.Message; +import org.qortal.network.message.OnlineAccountsV3Message; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; diff --git a/src/main/java/org/qortal/controller/Synchronizer.java b/src/main/java/org/qortal/controller/Synchronizer.java index 804bacbb..113b5846 100644 --- a/src/main/java/org/qortal/controller/Synchronizer.java +++ b/src/main/java/org/qortal/controller/Synchronizer.java @@ -1,14 +1,5 @@ package org.qortal.controller; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; @@ -35,6 +26,15 @@ import org.qortal.utils.Base58; import org.qortal.utils.ByteArray; import org.qortal.utils.NTP; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; + public class Synchronizer extends Thread { private static final Logger LOGGER = LogManager.getLogger(Synchronizer.class); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java index a2165a9e..11f613ae 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java @@ -14,7 +14,7 @@ import java.io.IOException; import java.util.Comparator; import java.util.Map; -import static org.qortal.data.arbitrary.ArbitraryResourceStatus.Status.*; +import static org.qortal.data.arbitrary.ArbitraryResourceStatus.Status.NOT_PUBLISHED; public class ArbitraryDataBuilderThread implements Runnable { diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java index 0c56769f..36d53761 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCacheManager.java @@ -15,7 +15,9 @@ import org.qortal.transaction.ArbitraryTransaction; import org.qortal.transaction.Transaction; import org.qortal.utils.Base58; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class ArbitraryDataCacheManager extends Thread { diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCleanupManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCleanupManager.java index e0c62acb..8611ab88 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCleanupManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataCleanupManager.java @@ -19,7 +19,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.SecureRandom; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; import static org.qortal.controller.arbitrary.ArbitraryDataStorageManager.DELETION_THRESHOLD; diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileRequestThread.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileRequestThread.java index 654c6844..12a03aee 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileRequestThread.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileRequestThread.java @@ -13,8 +13,9 @@ import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.Base58; import org.qortal.utils.NTP; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; public class ArbitraryDataFileRequestThread implements Runnable { diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index af4e4fc5..398dcb5b 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -1,11 +1,5 @@ package org.qortal.controller.arbitrary; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; @@ -14,7 +8,6 @@ import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.Controller; -import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.network.Network; @@ -30,6 +23,12 @@ import org.qortal.utils.Base58; import org.qortal.utils.ListUtils; import org.qortal.utils.NTP; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + public class ArbitraryDataManager extends Thread { private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataManager.class); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataRenderManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataRenderManager.java index 2844cef8..809db7af 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataRenderManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataRenderManager.java @@ -3,7 +3,10 @@ package org.qortal.controller.arbitrary; import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.utils.NTP; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; public class ArbitraryDataRenderManager extends Thread { diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index 1fee6753..9133e86c 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -10,7 +10,9 @@ import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.network.Network; import org.qortal.network.Peer; -import org.qortal.network.message.*; +import org.qortal.network.message.ArbitraryMetadataMessage; +import org.qortal.network.message.GetArbitraryMetadataMessage; +import org.qortal.network.message.Message; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; diff --git a/src/main/java/org/qortal/controller/repository/BlockArchiver.java b/src/main/java/org/qortal/controller/repository/BlockArchiver.java index 63d61ef8..a643d9b9 100644 --- a/src/main/java/org/qortal/controller/repository/BlockArchiver.java +++ b/src/main/java/org/qortal/controller/repository/BlockArchiver.java @@ -5,7 +5,10 @@ import org.apache.logging.log4j.Logger; import org.qortal.controller.Controller; import org.qortal.controller.Synchronizer; import org.qortal.data.block.BlockData; -import org.qortal.repository.*; +import org.qortal.repository.BlockArchiveWriter; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; import org.qortal.settings.Settings; import org.qortal.transform.TransformationException; import org.qortal.utils.NTP; diff --git a/src/main/java/org/qortal/controller/repository/PruneManager.java b/src/main/java/org/qortal/controller/repository/PruneManager.java index dfb6290b..d48f85f7 100644 --- a/src/main/java/org/qortal/controller/repository/PruneManager.java +++ b/src/main/java/org/qortal/controller/repository/PruneManager.java @@ -4,7 +4,6 @@ import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.controller.Controller; - import org.qortal.data.block.BlockData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; diff --git a/src/main/java/org/qortal/controller/tradebot/AcctTradeBot.java b/src/main/java/org/qortal/controller/tradebot/AcctTradeBot.java index 84a0d484..5c93b3e9 100644 --- a/src/main/java/org/qortal/controller/tradebot/AcctTradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/AcctTradeBot.java @@ -1,7 +1,5 @@ package org.qortal.controller.tradebot; -import java.util.List; - import org.qortal.api.model.crosschain.TradeBotCreateRequest; import org.qortal.crosschain.ACCT; import org.qortal.crosschain.ForeignBlockchainException; @@ -11,6 +9,8 @@ import org.qortal.data.crosschain.TradeBotData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.List; + public interface AcctTradeBot { public enum ResponseResult { OK, BALANCE_ISSUE, NETWORK_ISSUE, TRADE_ALREADY_EXISTS } diff --git a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java index 038ecded..259a16b8 100644 --- a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java @@ -1,33 +1,14 @@ package org.qortal.controller.tradebot; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bitcoinj.core.Address; -import org.bitcoinj.core.AddressFormatException; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; +import org.bitcoinj.core.*; import org.bitcoinj.script.Script.ScriptType; import org.qortal.account.PrivateKeyAccount; import org.qortal.account.PublicKeyAccount; import org.qortal.api.model.crosschain.TradeBotCreateRequest; import org.qortal.asset.Asset; -import org.qortal.crosschain.ACCT; -import org.qortal.crosschain.AcctMode; -import org.qortal.crosschain.Bitcoin; -import org.qortal.crosschain.BitcoinACCTv1; -import org.qortal.crosschain.ForeignBlockchainException; -import org.qortal.crosschain.SupportedBlockchain; -import org.qortal.crosschain.BitcoinyHTLC; +import org.qortal.crosschain.*; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.crosschain.CrossChainTradeData; @@ -46,6 +27,14 @@ import org.qortal.transform.transaction.DeployAtTransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; + /** * Performing cross-chain trading steps on behalf of user. *

diff --git a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java index fd0682b6..0b612d11 100644 --- a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java @@ -1,33 +1,14 @@ package org.qortal.controller.tradebot; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bitcoinj.core.Address; -import org.bitcoinj.core.AddressFormatException; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; +import org.bitcoinj.core.*; import org.bitcoinj.script.Script.ScriptType; import org.qortal.account.PrivateKeyAccount; import org.qortal.account.PublicKeyAccount; import org.qortal.api.model.crosschain.TradeBotCreateRequest; import org.qortal.asset.Asset; -import org.qortal.crosschain.ACCT; -import org.qortal.crosschain.AcctMode; -import org.qortal.crosschain.ForeignBlockchainException; -import org.qortal.crosschain.Litecoin; -import org.qortal.crosschain.LitecoinACCTv1; -import org.qortal.crosschain.SupportedBlockchain; -import org.qortal.crosschain.BitcoinyHTLC; +import org.qortal.crosschain.*; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.crosschain.CrossChainTradeData; @@ -46,6 +27,14 @@ import org.qortal.transform.transaction.DeployAtTransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.NTP; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; + /** * Performing cross-chain trading steps on behalf of user. *

diff --git a/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java index 4b5126d9..c48f23e2 100644 --- a/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java @@ -4,7 +4,8 @@ import com.google.common.hash.HashCode; import com.rust.litewalletjni.LiteWalletJni; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bitcoinj.core.*; +import org.bitcoinj.core.Bech32; +import org.bitcoinj.core.Coin; import org.qortal.account.PrivateKeyAccount; import org.qortal.account.PublicKeyAccount; import org.qortal.api.model.crosschain.TradeBotCreateRequest; diff --git a/src/main/java/org/qortal/controller/tradebot/TradeBot.java b/src/main/java/org/qortal/controller/tradebot/TradeBot.java index e17f642f..43330b07 100644 --- a/src/main/java/org/qortal/controller/tradebot/TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/TradeBot.java @@ -1,16 +1,11 @@ package org.qortal.controller.tradebot; -import java.awt.TrayIcon.MessageType; -import java.security.SecureRandom; -import java.util.*; -import java.util.function.Supplier; - +import com.google.common.primitives.Longs; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bitcoinj.core.ECKey; import org.qortal.account.PrivateKeyAccount; import org.qortal.api.model.crosschain.TradeBotCreateRequest; -import org.qortal.api.resource.TransactionsResource; import org.qortal.controller.Controller; import org.qortal.controller.Synchronizer; import org.qortal.controller.tradebot.AcctTradeBot.ResponseResult; @@ -39,7 +34,10 @@ import org.qortal.transaction.Transaction; import org.qortal.utils.ByteArray; import org.qortal.utils.NTP; -import com.google.common.primitives.Longs; +import java.awt.TrayIcon.MessageType; +import java.security.SecureRandom; +import java.util.*; +import java.util.function.Supplier; /** * Performing cross-chain trading steps on behalf of user. diff --git a/src/main/java/org/qortal/crosschain/AcctMode.java b/src/main/java/org/qortal/crosschain/AcctMode.java index 21496032..5c871943 100644 --- a/src/main/java/org/qortal/crosschain/AcctMode.java +++ b/src/main/java/org/qortal/crosschain/AcctMode.java @@ -1,10 +1,10 @@ package org.qortal.crosschain; +import java.util.Map; + import static java.util.Arrays.stream; import static java.util.stream.Collectors.toMap; -import java.util.Map; - public enum AcctMode { OFFERING(0), TRADING(1), CANCELLED(2), REFUNDED(3), REDEEMED(4); diff --git a/src/main/java/org/qortal/crosschain/Bitcoin.java b/src/main/java/org/qortal/crosschain/Bitcoin.java index 7925dd4e..801b141c 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoin.java +++ b/src/main/java/org/qortal/crosschain/Bitcoin.java @@ -1,10 +1,5 @@ package org.qortal.crosschain; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumMap; -import java.util.Map; - import org.bitcoinj.core.Context; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Transaction; @@ -15,6 +10,11 @@ import org.qortal.crosschain.ElectrumX.Server; import org.qortal.crosschain.ElectrumX.Server.ConnectionType; import org.qortal.settings.Settings; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumMap; +import java.util.Map; + public class Bitcoin extends Bitcoiny { public static final String CURRENCY_CODE = "BTC"; diff --git a/src/main/java/org/qortal/crosschain/BitcoinACCTv1.java b/src/main/java/org/qortal/crosschain/BitcoinACCTv1.java index eea541ad..9de95c17 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinACCTv1.java +++ b/src/main/java/org/qortal/crosschain/BitcoinACCTv1.java @@ -1,17 +1,8 @@ package org.qortal.crosschain; -import static org.ciyam.at.OpCode.calcOffset; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import org.ciyam.at.API; -import org.ciyam.at.CompilationException; -import org.ciyam.at.FunctionCode; -import org.ciyam.at.MachineState; -import org.ciyam.at.OpCode; -import org.ciyam.at.Timestamp; +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.ciyam.at.*; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.at.QortalFunctionCode; @@ -25,8 +16,11 @@ import org.qortal.repository.Repository; import org.qortal.utils.Base58; import org.qortal.utils.BitTwiddling; -import com.google.common.hash.HashCode; -import com.google.common.primitives.Bytes; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import static org.ciyam.at.OpCode.calcOffset; /** * Cross-chain trade AT diff --git a/src/main/java/org/qortal/crosschain/Bitcoiny.java b/src/main/java/org/qortal/crosschain/Bitcoiny.java index d1523b50..db901395 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoiny.java +++ b/src/main/java/org/qortal/crosschain/Bitcoiny.java @@ -1,24 +1,9 @@ package org.qortal.crosschain; -import java.util.*; -import java.util.stream.Collectors; - +import com.google.common.hash.HashCode; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bitcoinj.core.Address; -import org.bitcoinj.core.AddressFormatException; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.Context; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.LegacyAddress; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Sha256Hash; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; -import org.bitcoinj.core.UTXO; -import org.bitcoinj.core.UTXOProvider; -import org.bitcoinj.core.UTXOProviderException; +import org.bitcoinj.core.*; import org.bitcoinj.crypto.ChildNumber; import org.bitcoinj.crypto.DeterministicHierarchy; import org.bitcoinj.crypto.DeterministicKey; @@ -32,10 +17,11 @@ import org.qortal.crypto.Crypto; import org.qortal.settings.Settings; import org.qortal.utils.Amounts; import org.qortal.utils.BitTwiddling; - -import com.google.common.hash.HashCode; import org.qortal.utils.NTP; +import java.util.*; +import java.util.stream.Collectors; + /** Bitcoin-like (Bitcoin, Litecoin, etc.) support */ public abstract class Bitcoiny implements ForeignBlockchain { diff --git a/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java b/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java index 8075bfff..d8b4f653 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java +++ b/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java @@ -1,6 +1,6 @@ package org.qortal.crosschain; -import cash.z.wallet.sdk.rpc.CompactFormats.*; +import cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock; import java.util.List; diff --git a/src/main/java/org/qortal/crosschain/BitcoinyHTLC.java b/src/main/java/org/qortal/crosschain/BitcoinyHTLC.java index 8ebfffa2..8b6a6b07 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinyHTLC.java +++ b/src/main/java/org/qortal/crosschain/BitcoinyHTLC.java @@ -1,23 +1,9 @@ package org.qortal.crosschain; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import org.bitcoinj.core.Address; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.LegacyAddress; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Transaction; +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.bitcoinj.core.*; import org.bitcoinj.core.Transaction.SigHash; -import org.bitcoinj.core.TransactionInput; -import org.bitcoinj.core.TransactionOutput; import org.bitcoinj.crypto.TransactionSignature; import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptBuilder; @@ -27,8 +13,8 @@ import org.qortal.crypto.Crypto; import org.qortal.utils.Base58; import org.qortal.utils.BitTwiddling; -import com.google.common.hash.HashCode; -import com.google.common.primitives.Bytes; +import java.util.*; +import java.util.function.Function; public class BitcoinyHTLC { diff --git a/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java b/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java index 90ee2b23..203e11f8 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java +++ b/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java @@ -1,12 +1,11 @@ package org.qortal.crosschain; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; @XmlAccessorType(XmlAccessType.FIELD) public class BitcoinyTransaction { diff --git a/src/main/java/org/qortal/crosschain/Digibyte.java b/src/main/java/org/qortal/crosschain/Digibyte.java index 8e316173..4e725e89 100644 --- a/src/main/java/org/qortal/crosschain/Digibyte.java +++ b/src/main/java/org/qortal/crosschain/Digibyte.java @@ -1,10 +1,5 @@ package org.qortal.crosschain; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumMap; -import java.util.Map; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.Context; import org.bitcoinj.core.NetworkParameters; @@ -15,6 +10,11 @@ import org.qortal.crosschain.ElectrumX.Server; import org.qortal.crosschain.ElectrumX.Server.ConnectionType; import org.qortal.settings.Settings; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumMap; +import java.util.Map; + public class Digibyte extends Bitcoiny { public static final String CURRENCY_CODE = "DGB"; diff --git a/src/main/java/org/qortal/crosschain/ElectrumX.java b/src/main/java/org/qortal/crosschain/ElectrumX.java index a331b111..5915ba04 100644 --- a/src/main/java/org/qortal/crosschain/ElectrumX.java +++ b/src/main/java/org/qortal/crosschain/ElectrumX.java @@ -1,5 +1,18 @@ package org.qortal.crosschain; +import cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock; +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.qortal.crypto.Crypto; +import org.qortal.crypto.TrustlessSSLSocketFactory; +import org.qortal.utils.BitTwiddling; + +import javax.net.ssl.SSLSocketFactory; import java.io.IOException; import java.math.BigDecimal; import java.net.InetSocketAddress; @@ -10,21 +23,6 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.net.ssl.SSLSocketFactory; - -import cash.z.wallet.sdk.rpc.CompactFormats.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; -import org.qortal.crypto.Crypto; -import org.qortal.crypto.TrustlessSSLSocketFactory; - -import com.google.common.hash.HashCode; -import com.google.common.primitives.Bytes; -import org.qortal.utils.BitTwiddling; - /** ElectrumX network support for querying Bitcoiny-related info like block headers, transaction outputs, etc. */ public class ElectrumX extends BitcoinyBlockchainProvider { diff --git a/src/main/java/org/qortal/crosschain/Litecoin.java b/src/main/java/org/qortal/crosschain/Litecoin.java index 22825c74..a0f7c1cb 100644 --- a/src/main/java/org/qortal/crosschain/Litecoin.java +++ b/src/main/java/org/qortal/crosschain/Litecoin.java @@ -1,10 +1,5 @@ package org.qortal.crosschain; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumMap; -import java.util.Map; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.Context; import org.bitcoinj.core.NetworkParameters; @@ -15,6 +10,11 @@ import org.qortal.crosschain.ElectrumX.Server; import org.qortal.crosschain.ElectrumX.Server.ConnectionType; import org.qortal.settings.Settings; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumMap; +import java.util.Map; + public class Litecoin extends Bitcoiny { public static final String CURRENCY_CODE = "LTC"; diff --git a/src/main/java/org/qortal/crosschain/LitecoinACCTv1.java b/src/main/java/org/qortal/crosschain/LitecoinACCTv1.java index efd7043e..ea91501e 100644 --- a/src/main/java/org/qortal/crosschain/LitecoinACCTv1.java +++ b/src/main/java/org/qortal/crosschain/LitecoinACCTv1.java @@ -1,17 +1,8 @@ package org.qortal.crosschain; -import static org.ciyam.at.OpCode.calcOffset; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import org.ciyam.at.API; -import org.ciyam.at.CompilationException; -import org.ciyam.at.FunctionCode; -import org.ciyam.at.MachineState; -import org.ciyam.at.OpCode; -import org.ciyam.at.Timestamp; +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.ciyam.at.*; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.at.QortalFunctionCode; @@ -25,8 +16,11 @@ import org.qortal.repository.Repository; import org.qortal.utils.Base58; import org.qortal.utils.BitTwiddling; -import com.google.common.hash.HashCode; -import com.google.common.primitives.Bytes; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import static org.ciyam.at.OpCode.calcOffset; /** * Cross-chain trade AT diff --git a/src/main/java/org/qortal/crosschain/PirateChain.java b/src/main/java/org/qortal/crosschain/PirateChain.java index 4881c8bb..403d90e5 100644 --- a/src/main/java/org/qortal/crosschain/PirateChain.java +++ b/src/main/java/org/qortal/crosschain/PirateChain.java @@ -4,12 +4,6 @@ import cash.z.wallet.sdk.rpc.CompactFormats; import com.google.common.hash.HashCode; import com.rust.litewalletjni.LiteWalletJni; import org.bitcoinj.core.*; -import org.bitcoinj.crypto.ChildNumber; -import org.bitcoinj.crypto.DeterministicKey; -import org.bitcoinj.script.Script; -import org.bitcoinj.script.ScriptBuilder; -import org.bitcoinj.wallet.DeterministicKeyChain; -import org.bitcoinj.wallet.Wallet; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/src/main/java/org/qortal/crosschain/PirateChainHTLC.java b/src/main/java/org/qortal/crosschain/PirateChainHTLC.java index 17f7ad74..cf933951 100644 --- a/src/main/java/org/qortal/crosschain/PirateChainHTLC.java +++ b/src/main/java/org/qortal/crosschain/PirateChainHTLC.java @@ -10,6 +10,7 @@ import org.qortal.utils.Base58; import org.qortal.utils.BitTwiddling; import java.util.*; + import static org.qortal.crosschain.BitcoinyHTLC.Status; public class PirateChainHTLC { diff --git a/src/main/java/org/qortal/crosschain/PirateLightClient.java b/src/main/java/org/qortal/crosschain/PirateLightClient.java index 63bcd5fa..be4370a0 100644 --- a/src/main/java/org/qortal/crosschain/PirateLightClient.java +++ b/src/main/java/org/qortal/crosschain/PirateLightClient.java @@ -1,6 +1,6 @@ package org.qortal.crosschain; -import cash.z.wallet.sdk.rpc.CompactFormats.*; +import cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock; import cash.z.wallet.sdk.rpc.CompactTxStreamerGrpc; import cash.z.wallet.sdk.rpc.Service; import cash.z.wallet.sdk.rpc.Service.*; diff --git a/src/main/java/org/qortal/crosschain/Ravencoin.java b/src/main/java/org/qortal/crosschain/Ravencoin.java index 51b65f68..6b267a00 100644 --- a/src/main/java/org/qortal/crosschain/Ravencoin.java +++ b/src/main/java/org/qortal/crosschain/Ravencoin.java @@ -1,10 +1,5 @@ package org.qortal.crosschain; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumMap; -import java.util.Map; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.Context; import org.bitcoinj.core.NetworkParameters; @@ -15,6 +10,11 @@ import org.qortal.crosschain.ElectrumX.Server; import org.qortal.crosschain.ElectrumX.Server.ConnectionType; import org.qortal.settings.Settings; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumMap; +import java.util.Map; + public class Ravencoin extends Bitcoiny { public static final String CURRENCY_CODE = "RVN"; diff --git a/src/main/java/org/qortal/crosschain/SupportedBlockchain.java b/src/main/java/org/qortal/crosschain/SupportedBlockchain.java index 5ddb6aec..7b692644 100644 --- a/src/main/java/org/qortal/crosschain/SupportedBlockchain.java +++ b/src/main/java/org/qortal/crosschain/SupportedBlockchain.java @@ -1,5 +1,8 @@ package org.qortal.crosschain; +import org.qortal.utils.ByteArray; +import org.qortal.utils.Triple; + import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -7,9 +10,6 @@ import java.util.Map; import java.util.function.Supplier; import java.util.stream.Collectors; -import org.qortal.utils.ByteArray; -import org.qortal.utils.Triple; - public enum SupportedBlockchain { BITCOIN(Arrays.asList( diff --git a/src/main/java/org/qortal/crypto/AES.java b/src/main/java/org/qortal/crypto/AES.java index 1286fb81..d42e22f9 100644 --- a/src/main/java/org/qortal/crypto/AES.java +++ b/src/main/java/org/qortal/crypto/AES.java @@ -26,22 +26,11 @@ package org.qortal.crypto; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.BadPaddingException; -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKeyFactory; -import javax.crypto.SealedObject; +import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Serializable; +import java.io.*; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; diff --git a/src/main/java/org/qortal/crypto/BouncyCastleEd25519.java b/src/main/java/org/qortal/crypto/BouncyCastleEd25519.java index ebcf0f97..41f61023 100644 --- a/src/main/java/org/qortal/crypto/BouncyCastleEd25519.java +++ b/src/main/java/org/qortal/crypto/BouncyCastleEd25519.java @@ -1,7 +1,5 @@ package org.qortal.crypto; -import java.security.SecureRandom; - import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.math.ec.rfc7748.X25519; @@ -11,6 +9,8 @@ import org.bouncycastle.math.raw.Nat; import org.bouncycastle.math.raw.Nat256; import org.bouncycastle.util.Arrays; +import java.security.SecureRandom; + /** * Duplicate of {@link org.bouncycastle.math.ec.rfc8032.Ed25519}, * but with {@code private} modifiers replaced with {@code protected}, diff --git a/src/main/java/org/qortal/crypto/Credentials.java b/src/main/java/org/qortal/crypto/Credentials.java index 8fee58b2..2061d1eb 100644 --- a/src/main/java/org/qortal/crypto/Credentials.java +++ b/src/main/java/org/qortal/crypto/Credentials.java @@ -1,10 +1,6 @@ package org.qortal.crypto; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; diff --git a/src/main/java/org/qortal/crypto/Crypto.java b/src/main/java/org/qortal/crypto/Crypto.java index 75e5028e..3beb7abd 100644 --- a/src/main/java/org/qortal/crypto/Crypto.java +++ b/src/main/java/org/qortal/crypto/Crypto.java @@ -1,5 +1,13 @@ package org.qortal.crypto; +import com.google.common.primitives.Bytes; +import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; +import org.bouncycastle.math.ec.rfc8032.Ed25519; +import org.qortal.account.Account; +import org.qortal.utils.Base58; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -8,15 +16,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; -import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; -import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; -import org.bouncycastle.crypto.params.X25519PublicKeyParameters; -import org.bouncycastle.math.ec.rfc8032.Ed25519; -import org.qortal.account.Account; -import org.qortal.utils.Base58; - -import com.google.common.primitives.Bytes; - public abstract class Crypto { public static final int SIGNATURE_LENGTH = 64; diff --git a/src/main/java/org/qortal/crypto/TrustlessSSLSocketFactory.java b/src/main/java/org/qortal/crypto/TrustlessSSLSocketFactory.java index f723e651..f14efae8 100644 --- a/src/main/java/org/qortal/crypto/TrustlessSSLSocketFactory.java +++ b/src/main/java/org/qortal/crypto/TrustlessSSLSocketFactory.java @@ -1,11 +1,10 @@ package org.qortal.crypto; -import java.security.cert.X509Certificate; - import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import java.security.cert.X509Certificate; public abstract class TrustlessSSLSocketFactory { diff --git a/src/main/java/org/qortal/data/account/AccountBalanceData.java b/src/main/java/org/qortal/data/account/AccountBalanceData.java index 94c03ab4..37408baf 100644 --- a/src/main/java/org/qortal/data/account/AccountBalanceData.java +++ b/src/main/java/org/qortal/data/account/AccountBalanceData.java @@ -1,12 +1,12 @@ package org.qortal.data.account; +import org.qortal.utils.Amounts; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.utils.Amounts; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class AccountBalanceData { diff --git a/src/main/java/org/qortal/data/account/AccountData.java b/src/main/java/org/qortal/data/account/AccountData.java index 868d1bc1..eb998a08 100644 --- a/src/main/java/org/qortal/data/account/AccountData.java +++ b/src/main/java/org/qortal/data/account/AccountData.java @@ -1,10 +1,10 @@ package org.qortal.data.account; +import org.qortal.group.Group; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import org.qortal.group.Group; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class AccountData { diff --git a/src/main/java/org/qortal/data/account/MintingAccountData.java b/src/main/java/org/qortal/data/account/MintingAccountData.java index 63c6c723..26bc4e27 100644 --- a/src/main/java/org/qortal/data/account/MintingAccountData.java +++ b/src/main/java/org/qortal/data/account/MintingAccountData.java @@ -1,16 +1,15 @@ package org.qortal.data.account; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.json.JSONObject; +import org.qortal.crypto.Crypto; +import org.qortal.utils.Base58; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.json.JSONObject; -import org.qortal.crypto.Crypto; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; -import org.qortal.utils.Base58; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class MintingAccountData { diff --git a/src/main/java/org/qortal/data/account/RewardShareData.java b/src/main/java/org/qortal/data/account/RewardShareData.java index ead1bbd9..b93fb945 100644 --- a/src/main/java/org/qortal/data/account/RewardShareData.java +++ b/src/main/java/org/qortal/data/account/RewardShareData.java @@ -1,16 +1,14 @@ package org.qortal.data.account; -import java.math.BigDecimal; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.utils.Base58; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import org.qortal.utils.Base58; - -import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryRelayInfo.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryRelayInfo.java index 17c1acac..80b4efcf 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryRelayInfo.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryRelayInfo.java @@ -1,6 +1,7 @@ package org.qortal.data.arbitrary; import org.qortal.network.Peer; + import java.util.Objects; public class ArbitraryRelayInfo { diff --git a/src/main/java/org/qortal/data/asset/AssetData.java b/src/main/java/org/qortal/data/asset/AssetData.java index 2477f751..8e944720 100644 --- a/src/main/java/org/qortal/data/asset/AssetData.java +++ b/src/main/java/org/qortal/data/asset/AssetData.java @@ -1,11 +1,11 @@ package org.qortal.data.asset; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class AssetData { diff --git a/src/main/java/org/qortal/data/asset/OrderData.java b/src/main/java/org/qortal/data/asset/OrderData.java index eb4e5c63..76fca4c6 100644 --- a/src/main/java/org/qortal/data/asset/OrderData.java +++ b/src/main/java/org/qortal/data/asset/OrderData.java @@ -1,15 +1,14 @@ package org.qortal.data.asset; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.crypto.Crypto; + import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.crypto.Crypto; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class OrderData implements Comparable { diff --git a/src/main/java/org/qortal/data/asset/RecentTradeData.java b/src/main/java/org/qortal/data/asset/RecentTradeData.java index 56a83180..37bd63ef 100644 --- a/src/main/java/org/qortal/data/asset/RecentTradeData.java +++ b/src/main/java/org/qortal/data/asset/RecentTradeData.java @@ -1,11 +1,10 @@ package org.qortal.data.asset; -import java.math.BigDecimal; +import io.swagger.v3.oas.annotations.media.Schema; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; - -import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/asset/TradeData.java b/src/main/java/org/qortal/data/asset/TradeData.java index af827f38..74ad2a62 100644 --- a/src/main/java/org/qortal/data/asset/TradeData.java +++ b/src/main/java/org/qortal/data/asset/TradeData.java @@ -1,5 +1,8 @@ package org.qortal.data.asset; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; + import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -7,9 +10,6 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class TradeData { diff --git a/src/main/java/org/qortal/data/block/BlockArchiveData.java b/src/main/java/org/qortal/data/block/BlockArchiveData.java index c9db4032..27898a52 100644 --- a/src/main/java/org/qortal/data/block/BlockArchiveData.java +++ b/src/main/java/org/qortal/data/block/BlockArchiveData.java @@ -1,7 +1,5 @@ package org.qortal.data.block; -import org.qortal.block.Block; - public class BlockArchiveData { // Properties diff --git a/src/main/java/org/qortal/data/block/BlockData.java b/src/main/java/org/qortal/data/block/BlockData.java index 763bca45..ffae8751 100644 --- a/src/main/java/org/qortal/data/block/BlockData.java +++ b/src/main/java/org/qortal/data/block/BlockData.java @@ -1,18 +1,16 @@ package org.qortal.data.block; import com.google.common.primitives.Bytes; - -import java.io.Serializable; +import org.qortal.block.BlockChain; +import org.qortal.crypto.Crypto; +import org.qortal.settings.Settings; +import org.qortal.utils.NTP; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import org.qortal.block.BlockChain; -import org.qortal.settings.Settings; -import org.qortal.crypto.Crypto; -import org.qortal.utils.NTP; +import java.io.Serializable; // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/chat/ActiveChats.java b/src/main/java/org/qortal/data/chat/ActiveChats.java index 248af82e..f24c2666 100644 --- a/src/main/java/org/qortal/data/chat/ActiveChats.java +++ b/src/main/java/org/qortal/data/chat/ActiveChats.java @@ -3,10 +3,9 @@ package org.qortal.data.chat; import org.bouncycastle.util.encoders.Base64; import org.qortal.utils.Base58; -import java.util.List; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import java.util.List; import static org.qortal.data.chat.ChatMessage.Encoding; diff --git a/src/main/java/org/qortal/data/crosschain/CrossChainTradeData.java b/src/main/java/org/qortal/data/crosschain/CrossChainTradeData.java index edc115b6..d3656107 100644 --- a/src/main/java/org/qortal/data/crosschain/CrossChainTradeData.java +++ b/src/main/java/org/qortal/data/crosschain/CrossChainTradeData.java @@ -1,13 +1,12 @@ package org.qortal.data.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.crosschain.AcctMode; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.crosschain.AcctMode; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class CrossChainTradeData { diff --git a/src/main/java/org/qortal/data/crosschain/TradeBotData.java b/src/main/java/org/qortal/data/crosschain/TradeBotData.java index 19481466..15b7c448 100644 --- a/src/main/java/org/qortal/data/crosschain/TradeBotData.java +++ b/src/main/java/org/qortal/data/crosschain/TradeBotData.java @@ -1,15 +1,14 @@ package org.qortal.data.crosschain; +import io.swagger.v3.oas.annotations.media.Schema; +import org.json.JSONObject; +import org.qortal.utils.Base58; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; -import org.json.JSONObject; - -import org.qortal.utils.Base58; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class TradeBotData { diff --git a/src/main/java/org/qortal/data/group/GroupAdminData.java b/src/main/java/org/qortal/data/group/GroupAdminData.java index b9fea54b..6a7f8776 100644 --- a/src/main/java/org/qortal/data/group/GroupAdminData.java +++ b/src/main/java/org/qortal/data/group/GroupAdminData.java @@ -1,11 +1,11 @@ package org.qortal.data.group; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class GroupAdminData { diff --git a/src/main/java/org/qortal/data/group/GroupBanData.java b/src/main/java/org/qortal/data/group/GroupBanData.java index 5e2abe52..e7f456dc 100644 --- a/src/main/java/org/qortal/data/group/GroupBanData.java +++ b/src/main/java/org/qortal/data/group/GroupBanData.java @@ -1,11 +1,11 @@ package org.qortal.data.group; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class GroupBanData { diff --git a/src/main/java/org/qortal/data/group/GroupData.java b/src/main/java/org/qortal/data/group/GroupData.java index ae9a0388..3ecca0ef 100644 --- a/src/main/java/org/qortal/data/group/GroupData.java +++ b/src/main/java/org/qortal/data/group/GroupData.java @@ -1,13 +1,12 @@ package org.qortal.data.group; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.group.Group.ApprovalThreshold; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.group.Group.ApprovalThreshold; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class GroupData { diff --git a/src/main/java/org/qortal/data/group/GroupInviteData.java b/src/main/java/org/qortal/data/group/GroupInviteData.java index 50c0a8c2..2b01a8dd 100644 --- a/src/main/java/org/qortal/data/group/GroupInviteData.java +++ b/src/main/java/org/qortal/data/group/GroupInviteData.java @@ -1,11 +1,11 @@ package org.qortal.data.group; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class GroupInviteData { diff --git a/src/main/java/org/qortal/data/group/GroupJoinRequestData.java b/src/main/java/org/qortal/data/group/GroupJoinRequestData.java index b084aa66..5338ba3d 100644 --- a/src/main/java/org/qortal/data/group/GroupJoinRequestData.java +++ b/src/main/java/org/qortal/data/group/GroupJoinRequestData.java @@ -1,11 +1,11 @@ package org.qortal.data.group; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class GroupJoinRequestData { diff --git a/src/main/java/org/qortal/data/group/GroupMemberData.java b/src/main/java/org/qortal/data/group/GroupMemberData.java index 87b1ae41..b82fe327 100644 --- a/src/main/java/org/qortal/data/group/GroupMemberData.java +++ b/src/main/java/org/qortal/data/group/GroupMemberData.java @@ -1,11 +1,11 @@ package org.qortal.data.group; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class GroupMemberData { diff --git a/src/main/java/org/qortal/data/naming/NameData.java b/src/main/java/org/qortal/data/naming/NameData.java index 83681712..16e490a2 100644 --- a/src/main/java/org/qortal/data/naming/NameData.java +++ b/src/main/java/org/qortal/data/naming/NameData.java @@ -1,12 +1,12 @@ package org.qortal.data.naming; +import io.swagger.v3.oas.annotations.media.Schema; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAX-RS @XmlAccessorType(XmlAccessType.FIELD) public class NameData { diff --git a/src/main/java/org/qortal/data/network/OnlineAccountData.java b/src/main/java/org/qortal/data/network/OnlineAccountData.java index a1e1b30f..8b763bd9 100644 --- a/src/main/java/org/qortal/data/network/OnlineAccountData.java +++ b/src/main/java/org/qortal/data/network/OnlineAccountData.java @@ -1,14 +1,13 @@ package org.qortal.data.network; -import java.util.Arrays; -import java.util.Objects; +import org.qortal.account.PublicKeyAccount; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; - -import org.qortal.account.PublicKeyAccount; +import java.util.Arrays; +import java.util.Objects; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/network/PeerData.java b/src/main/java/org/qortal/data/network/PeerData.java index 471685dd..0b776d6c 100644 --- a/src/main/java/org/qortal/data/network/PeerData.java +++ b/src/main/java/org/qortal/data/network/PeerData.java @@ -1,14 +1,13 @@ package org.qortal.data.network; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.network.PeerAddress; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.network.PeerAddress; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) public class PeerData { diff --git a/src/main/java/org/qortal/data/transaction/ATTransactionData.java b/src/main/java/org/qortal/data/transaction/ATTransactionData.java index 5d5d640b..9cd50055 100644 --- a/src/main/java/org/qortal/data/transaction/ATTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/ATTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.account.NullAccount; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.account.NullAccount; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/AccountFlagsTransactionData.java b/src/main/java/org/qortal/data/transaction/AccountFlagsTransactionData.java index f5f29e1b..75c8d29e 100644 --- a/src/main/java/org/qortal/data/transaction/AccountFlagsTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/AccountFlagsTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - +import io.swagger.v3.oas.annotations.media.Schema; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.account.NullAccount; import org.qortal.block.GenesisBlock; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/AccountLevelTransactionData.java b/src/main/java/org/qortal/data/transaction/AccountLevelTransactionData.java index 4b55e375..86de8677 100644 --- a/src/main/java/org/qortal/data/transaction/AccountLevelTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/AccountLevelTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - +import io.swagger.v3.oas.annotations.media.Schema; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.account.NullAccount; import org.qortal.block.GenesisBlock; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/AddGroupAdminTransactionData.java b/src/main/java/org/qortal/data/transaction/AddGroupAdminTransactionData.java index 3c2930b6..e77a6f6a 100644 --- a/src/main/java/org/qortal/data/transaction/AddGroupAdminTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/AddGroupAdminTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java b/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java index 3ab06ecc..6e55e280 100644 --- a/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java @@ -1,18 +1,16 @@ package org.qortal.data.transaction; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - +import io.swagger.v3.oas.annotations.media.Schema; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.arbitrary.misc.Service; import org.qortal.data.PaymentData; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.util.List; +import java.util.Map; import static java.util.Arrays.stream; import static java.util.stream.Collectors.toMap; diff --git a/src/main/java/org/qortal/data/transaction/BuyNameTransactionData.java b/src/main/java/org/qortal/data/transaction/BuyNameTransactionData.java index 014e1f54..fffdc293 100644 --- a/src/main/java/org/qortal/data/transaction/BuyNameTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/BuyNameTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/CancelAssetOrderTransactionData.java b/src/main/java/org/qortal/data/transaction/CancelAssetOrderTransactionData.java index 5582d5a5..9688162f 100644 --- a/src/main/java/org/qortal/data/transaction/CancelAssetOrderTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CancelAssetOrderTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; -import org.qortal.transaction.Transaction; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/CancelGroupBanTransactionData.java b/src/main/java/org/qortal/data/transaction/CancelGroupBanTransactionData.java index 20af8321..d4cbeee4 100644 --- a/src/main/java/org/qortal/data/transaction/CancelGroupBanTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CancelGroupBanTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/CancelGroupInviteTransactionData.java b/src/main/java/org/qortal/data/transaction/CancelGroupInviteTransactionData.java index 3b3405c5..f30130ea 100644 --- a/src/main/java/org/qortal/data/transaction/CancelGroupInviteTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CancelGroupInviteTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/CancelSellNameTransactionData.java b/src/main/java/org/qortal/data/transaction/CancelSellNameTransactionData.java index 14677daf..602db975 100644 --- a/src/main/java/org/qortal/data/transaction/CancelSellNameTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CancelSellNameTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/ChatTransactionData.java b/src/main/java/org/qortal/data/transaction/ChatTransactionData.java index 5a6adf7f..aaa5e9b8 100644 --- a/src/main/java/org/qortal/data/transaction/ChatTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/ChatTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/CreateAssetOrderTransactionData.java b/src/main/java/org/qortal/data/transaction/CreateAssetOrderTransactionData.java index 6b048541..00379976 100644 --- a/src/main/java/org/qortal/data/transaction/CreateAssetOrderTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CreateAssetOrderTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/CreateGroupTransactionData.java b/src/main/java/org/qortal/data/transaction/CreateGroupTransactionData.java index 2471bb2f..8f770668 100644 --- a/src/main/java/org/qortal/data/transaction/CreateGroupTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CreateGroupTransactionData.java @@ -1,19 +1,18 @@ package org.qortal.data.transaction; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlTransient; - +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.block.GenesisBlock; import org.qortal.group.Group.ApprovalThreshold; import org.qortal.transaction.Transaction.TransactionType; import org.qortal.utils.Unicode; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlTransient; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/CreatePollTransactionData.java b/src/main/java/org/qortal/data/transaction/CreatePollTransactionData.java index 8b904aa0..1a04d0b8 100644 --- a/src/main/java/org/qortal/data/transaction/CreatePollTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/CreatePollTransactionData.java @@ -1,17 +1,15 @@ package org.qortal.data.transaction; -import java.util.List; - -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - +import io.swagger.v3.oas.annotations.media.Schema; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.data.voting.PollOptionData; import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.util.List; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/DeployAtTransactionData.java b/src/main/java/org/qortal/data/transaction/DeployAtTransactionData.java index fed69cd5..72c1fee0 100644 --- a/src/main/java/org/qortal/data/transaction/DeployAtTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/DeployAtTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/GenesisTransactionData.java b/src/main/java/org/qortal/data/transaction/GenesisTransactionData.java index e425f136..7d3b4a52 100644 --- a/src/main/java/org/qortal/data/transaction/GenesisTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/GenesisTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - +import io.swagger.v3.oas.annotations.media.Schema; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.asset.Asset; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/GroupApprovalTransactionData.java b/src/main/java/org/qortal/data/transaction/GroupApprovalTransactionData.java index fbf764de..a44cdbd8 100644 --- a/src/main/java/org/qortal/data/transaction/GroupApprovalTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/GroupApprovalTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema( diff --git a/src/main/java/org/qortal/data/transaction/GroupBanTransactionData.java b/src/main/java/org/qortal/data/transaction/GroupBanTransactionData.java index 18b89f73..d4e5e148 100644 --- a/src/main/java/org/qortal/data/transaction/GroupBanTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/GroupBanTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema( diff --git a/src/main/java/org/qortal/data/transaction/GroupInviteTransactionData.java b/src/main/java/org/qortal/data/transaction/GroupInviteTransactionData.java index bc1b515e..0428e2b0 100644 --- a/src/main/java/org/qortal/data/transaction/GroupInviteTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/GroupInviteTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/GroupKickTransactionData.java b/src/main/java/org/qortal/data/transaction/GroupKickTransactionData.java index aba68a15..36a4ed66 100644 --- a/src/main/java/org/qortal/data/transaction/GroupKickTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/GroupKickTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema( diff --git a/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java b/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java index b24a9634..c4101e48 100644 --- a/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java @@ -1,19 +1,18 @@ package org.qortal.data.transaction; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlTransient; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; import org.qortal.account.NullAccount; import org.qortal.block.GenesisBlock; import org.qortal.transaction.Transaction.TransactionType; import org.qortal.utils.Unicode; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/JoinGroupTransactionData.java b/src/main/java/org/qortal/data/transaction/JoinGroupTransactionData.java index b64324ca..103d8ec5 100644 --- a/src/main/java/org/qortal/data/transaction/JoinGroupTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/JoinGroupTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/LeaveGroupTransactionData.java b/src/main/java/org/qortal/data/transaction/LeaveGroupTransactionData.java index 46c6742d..5946a0ad 100644 --- a/src/main/java/org/qortal/data/transaction/LeaveGroupTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/LeaveGroupTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/MessageTransactionData.java b/src/main/java/org/qortal/data/transaction/MessageTransactionData.java index a61dbca6..446967d5 100644 --- a/src/main/java/org/qortal/data/transaction/MessageTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/MessageTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/MultiPaymentTransactionData.java b/src/main/java/org/qortal/data/transaction/MultiPaymentTransactionData.java index 027116f5..c7d31f27 100644 --- a/src/main/java/org/qortal/data/transaction/MultiPaymentTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/MultiPaymentTransactionData.java @@ -1,16 +1,14 @@ package org.qortal.data.transaction; -import java.util.List; - -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - +import io.swagger.v3.oas.annotations.media.Schema; import org.qortal.data.PaymentData; import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.util.List; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/data/transaction/PaymentTransactionData.java b/src/main/java/org/qortal/data/transaction/PaymentTransactionData.java index 94d8ab45..b760bf6c 100644 --- a/src/main/java/org/qortal/data/transaction/PaymentTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/PaymentTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema( allOf = { TransactionData.class } ) diff --git a/src/main/java/org/qortal/data/transaction/PresenceTransactionData.java b/src/main/java/org/qortal/data/transaction/PresenceTransactionData.java index 001bd5b4..d3957a0d 100644 --- a/src/main/java/org/qortal/data/transaction/PresenceTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/PresenceTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.transaction.PresenceTransaction.PresenceType; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import org.qortal.transaction.PresenceTransaction.PresenceType; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/PublicizeTransactionData.java b/src/main/java/org/qortal/data/transaction/PublicizeTransactionData.java index cdb9129d..73c49941 100644 --- a/src/main/java/org/qortal/data/transaction/PublicizeTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/PublicizeTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/RegisterNameTransactionData.java b/src/main/java/org/qortal/data/transaction/RegisterNameTransactionData.java index c2b06fd2..39e84e3f 100644 --- a/src/main/java/org/qortal/data/transaction/RegisterNameTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/RegisterNameTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.transaction.Transaction.TransactionType; +import org.qortal.utils.Unicode; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.transaction.Transaction.TransactionType; -import org.qortal.utils.Unicode; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/RemoveGroupAdminTransactionData.java b/src/main/java/org/qortal/data/transaction/RemoveGroupAdminTransactionData.java index 4501488d..b9c1470a 100644 --- a/src/main/java/org/qortal/data/transaction/RemoveGroupAdminTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/RemoveGroupAdminTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/RewardShareTransactionData.java b/src/main/java/org/qortal/data/transaction/RewardShareTransactionData.java index 5513d605..04d2b112 100644 --- a/src/main/java/org/qortal/data/transaction/RewardShareTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/RewardShareTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = {TransactionData.class}) diff --git a/src/main/java/org/qortal/data/transaction/SellNameTransactionData.java b/src/main/java/org/qortal/data/transaction/SellNameTransactionData.java index eb74ecde..d8501428 100644 --- a/src/main/java/org/qortal/data/transaction/SellNameTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/SellNameTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/SetGroupTransactionData.java b/src/main/java/org/qortal/data/transaction/SetGroupTransactionData.java index f971bb08..b3346756 100644 --- a/src/main/java/org/qortal/data/transaction/SetGroupTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/SetGroupTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema( diff --git a/src/main/java/org/qortal/data/transaction/TransactionData.java b/src/main/java/org/qortal/data/transaction/TransactionData.java index 21628bb9..467eafa6 100644 --- a/src/main/java/org/qortal/data/transaction/TransactionData.java +++ b/src/main/java/org/qortal/data/transaction/TransactionData.java @@ -1,15 +1,7 @@ package org.qortal.data.transaction; -import java.math.BigInteger; -import java.util.Arrays; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlSeeAlso; -import javax.xml.bind.annotation.XmlTransient; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode; import org.qortal.crypto.Crypto; import org.qortal.data.voting.PollData; @@ -17,8 +9,10 @@ import org.qortal.data.voting.VoteOnPollData; import org.qortal.transaction.Transaction.ApprovalStatus; import org.qortal.transaction.Transaction.TransactionType; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import javax.xml.bind.annotation.*; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.math.BigInteger; +import java.util.Arrays; /* * If you encounter an error like: diff --git a/src/main/java/org/qortal/data/transaction/TransferAssetTransactionData.java b/src/main/java/org/qortal/data/transaction/TransferAssetTransactionData.java index e1036aeb..78a7f278 100644 --- a/src/main/java/org/qortal/data/transaction/TransferAssetTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/TransferAssetTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.AccessMode; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/TransferPrivsTransactionData.java b/src/main/java/org/qortal/data/transaction/TransferPrivsTransactionData.java index bd2ea5bb..238a1f23 100644 --- a/src/main/java/org/qortal/data/transaction/TransferPrivsTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/TransferPrivsTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/UpdateAssetTransactionData.java b/src/main/java/org/qortal/data/transaction/UpdateAssetTransactionData.java index 70c3a969..17ae55f2 100644 --- a/src/main/java/org/qortal/data/transaction/UpdateAssetTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/UpdateAssetTransactionData.java @@ -1,14 +1,13 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/UpdateGroupTransactionData.java b/src/main/java/org/qortal/data/transaction/UpdateGroupTransactionData.java index 871a8339..a24f912d 100644 --- a/src/main/java/org/qortal/data/transaction/UpdateGroupTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/UpdateGroupTransactionData.java @@ -1,16 +1,15 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.group.Group.ApprovalThreshold; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.group.Group.ApprovalThreshold; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema( allOf = { TransactionData.class } ) diff --git a/src/main/java/org/qortal/data/transaction/UpdateNameTransactionData.java b/src/main/java/org/qortal/data/transaction/UpdateNameTransactionData.java index 1fda16a5..2c959612 100644 --- a/src/main/java/org/qortal/data/transaction/UpdateNameTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/UpdateNameTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.qortal.transaction.Transaction.TransactionType; +import org.qortal.utils.Unicode; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.qortal.transaction.Transaction.TransactionType; -import org.qortal.utils.Unicode; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/data/transaction/VoteOnPollTransactionData.java b/src/main/java/org/qortal/data/transaction/VoteOnPollTransactionData.java index a23d5e2b..ab233d2e 100644 --- a/src/main/java/org/qortal/data/transaction/VoteOnPollTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/VoteOnPollTransactionData.java @@ -1,15 +1,14 @@ package org.qortal.data.transaction; +import io.swagger.v3.oas.annotations.media.Schema; +import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; +import org.qortal.transaction.Transaction.TransactionType; + import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlTransient; -import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; -import org.qortal.transaction.Transaction.TransactionType; - -import io.swagger.v3.oas.annotations.media.Schema; - // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) @Schema(allOf = { TransactionData.class }) diff --git a/src/main/java/org/qortal/event/EventBus.java b/src/main/java/org/qortal/event/EventBus.java index 6114c2c6..5656708c 100644 --- a/src/main/java/org/qortal/event/EventBus.java +++ b/src/main/java/org/qortal/event/EventBus.java @@ -1,11 +1,11 @@ package org.qortal.event; -import java.util.ArrayList; -import java.util.List; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.ArrayList; +import java.util.List; + public enum EventBus { INSTANCE; diff --git a/src/main/java/org/qortal/globalization/BIP39WordList.java b/src/main/java/org/qortal/globalization/BIP39WordList.java index 3f1c7a11..8203c46d 100644 --- a/src/main/java/org/qortal/globalization/BIP39WordList.java +++ b/src/main/java/org/qortal/globalization/BIP39WordList.java @@ -1,5 +1,8 @@ package org.qortal.globalization; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -10,9 +13,6 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - /** Providing multi-language BIP39 word lists, downloaded from https://github.com/bitcoin/bips/tree/master/bip-0039 */ public enum BIP39WordList { INSTANCE; diff --git a/src/main/java/org/qortal/globalization/Translator.java b/src/main/java/org/qortal/globalization/Translator.java index 6481dde7..6f1ffa3f 100644 --- a/src/main/java/org/qortal/globalization/Translator.java +++ b/src/main/java/org/qortal/globalization/Translator.java @@ -1,17 +1,11 @@ package org.qortal.globalization; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.MissingFormatArgumentException; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.util.Set; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.settings.Settings; +import java.util.*; + public enum Translator { INSTANCE; diff --git a/src/main/java/org/qortal/group/Group.java b/src/main/java/org/qortal/group/Group.java index 465743a9..59e32545 100644 --- a/src/main/java/org/qortal/group/Group.java +++ b/src/main/java/org/qortal/group/Group.java @@ -1,37 +1,21 @@ package org.qortal.group; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -import java.util.Arrays; -import java.util.Map; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.controller.Controller; import org.qortal.crypto.Crypto; -import org.qortal.data.group.GroupAdminData; -import org.qortal.data.group.GroupBanData; -import org.qortal.data.group.GroupData; -import org.qortal.data.group.GroupInviteData; -import org.qortal.data.group.GroupJoinRequestData; -import org.qortal.data.group.GroupMemberData; -import org.qortal.data.transaction.AddGroupAdminTransactionData; -import org.qortal.data.transaction.CancelGroupBanTransactionData; -import org.qortal.data.transaction.CancelGroupInviteTransactionData; -import org.qortal.data.transaction.CreateGroupTransactionData; -import org.qortal.data.transaction.GroupBanTransactionData; -import org.qortal.data.transaction.GroupInviteTransactionData; -import org.qortal.data.transaction.GroupKickTransactionData; -import org.qortal.data.transaction.JoinGroupTransactionData; -import org.qortal.data.transaction.LeaveGroupTransactionData; -import org.qortal.data.transaction.RemoveGroupAdminTransactionData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.data.transaction.UpdateGroupTransactionData; +import org.qortal.data.group.*; +import org.qortal.data.transaction.*; import org.qortal.repository.DataException; import org.qortal.repository.GroupRepository; import org.qortal.repository.Repository; +import java.util.Arrays; +import java.util.Map; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; + public class Group { /** Group-admin quora threshold for approving transactions */ diff --git a/src/main/java/org/qortal/gui/Gui.java b/src/main/java/org/qortal/gui/Gui.java index 4944db52..5d7d4533 100644 --- a/src/main/java/org/qortal/gui/Gui.java +++ b/src/main/java/org/qortal/gui/Gui.java @@ -1,19 +1,16 @@ package org.qortal.gui; -import java.awt.GraphicsEnvironment; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.imageio.ImageIO; +import javax.swing.*; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.util.ServiceConfigurationError; -import javax.imageio.ImageIO; -import javax.swing.JOptionPane; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - public class Gui { private static final Logger LOGGER = LogManager.getLogger(Gui.class); diff --git a/src/main/java/org/qortal/gui/SplashFrame.java b/src/main/java/org/qortal/gui/SplashFrame.java index c4ea51d0..de2e2d34 100644 --- a/src/main/java/org/qortal/gui/SplashFrame.java +++ b/src/main/java/org/qortal/gui/SplashFrame.java @@ -1,17 +1,16 @@ package org.qortal.gui; -import java.awt.*; -import java.util.ArrayList; -import java.util.List; -import java.awt.image.BufferedImage; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.controller.Controller; +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + public class SplashFrame { protected static final Logger LOGGER = LogManager.getLogger(SplashFrame.class); diff --git a/src/main/java/org/qortal/gui/SysTray.java b/src/main/java/org/qortal/gui/SysTray.java index 4d02658d..abd433f3 100644 --- a/src/main/java/org/qortal/gui/SysTray.java +++ b/src/main/java/org/qortal/gui/SysTray.java @@ -1,9 +1,17 @@ package org.qortal.gui; -import java.awt.AWTError; -import java.awt.AWTException; -import java.awt.SystemTray; -import java.awt.TrayIcon; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.controller.Controller; +import org.qortal.globalization.Translator; +import org.qortal.settings.Settings; +import org.qortal.utils.RandomizeList; +import org.qortal.utils.URLViewer; + +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; @@ -21,22 +29,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.swing.JDialog; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPopupMenu; -import javax.swing.SwingWorker; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.qortal.controller.Controller; -import org.qortal.globalization.Translator; -import org.qortal.settings.Settings; -import org.qortal.utils.RandomizeList; -import org.qortal.utils.URLViewer; - public class SysTray { protected static final Logger LOGGER = LogManager.getLogger(SysTray.class); diff --git a/src/main/java/org/qortal/naming/Name.java b/src/main/java/org/qortal/naming/Name.java index 1751cca8..704200dc 100644 --- a/src/main/java/org/qortal/naming/Name.java +++ b/src/main/java/org/qortal/naming/Name.java @@ -5,12 +5,7 @@ import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; import org.qortal.data.naming.NameData; -import org.qortal.data.transaction.BuyNameTransactionData; -import org.qortal.data.transaction.CancelSellNameTransactionData; -import org.qortal.data.transaction.RegisterNameTransactionData; -import org.qortal.data.transaction.SellNameTransactionData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.data.transaction.UpdateNameTransactionData; +import org.qortal.data.transaction.*; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.transaction.Transaction.TransactionType; diff --git a/src/main/java/org/qortal/network/Handshake.java b/src/main/java/org/qortal/network/Handshake.java index 341f4e21..221e5e74 100644 --- a/src/main/java/org/qortal/network/Handshake.java +++ b/src/main/java/org/qortal/network/Handshake.java @@ -1,25 +1,20 @@ package org.qortal.network; -import java.util.Arrays; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.regex.Matcher; - +import com.google.common.primitives.Bytes; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.controller.Controller; import org.qortal.crypto.Crypto; import org.qortal.crypto.MemoryPoW; -import org.qortal.network.message.ChallengeMessage; -import org.qortal.network.message.HelloMessage; -import org.qortal.network.message.Message; -import org.qortal.network.message.MessageType; +import org.qortal.network.message.*; import org.qortal.settings.Settings; -import org.qortal.network.message.ResponseMessage; import org.qortal.utils.DaemonThreadFactory; import org.qortal.utils.NTP; -import com.google.common.primitives.Bytes; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.regex.Matcher; public enum Handshake { STARTED(null) { diff --git a/src/main/java/org/qortal/network/Peer.java b/src/main/java/org/qortal/network/Peer.java index 4c05d5b9..821f368c 100644 --- a/src/main/java/org/qortal/network/Peer.java +++ b/src/main/java/org/qortal/network/Peer.java @@ -27,7 +27,6 @@ import java.nio.channels.SocketChannel; import java.security.SecureRandom; import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/src/main/java/org/qortal/network/PeerAddress.java b/src/main/java/org/qortal/network/PeerAddress.java index 332ff484..66426093 100644 --- a/src/main/java/org/qortal/network/PeerAddress.java +++ b/src/main/java/org/qortal/network/PeerAddress.java @@ -1,18 +1,12 @@ package org.qortal.network; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import org.qortal.settings.Settings; - import com.google.common.net.HostAndPort; import com.google.common.net.InetAddresses; +import org.qortal.settings.Settings; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.net.*; /** * Convenience class for encapsulating/parsing/rendering/converting peer addresses diff --git a/src/main/java/org/qortal/network/message/ArbitraryDataMessage.java b/src/main/java/org/qortal/network/message/ArbitraryDataMessage.java index 142e35cc..8a5eb636 100644 --- a/src/main/java/org/qortal/network/message/ArbitraryDataMessage.java +++ b/src/main/java/org/qortal/network/message/ArbitraryDataMessage.java @@ -1,14 +1,13 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.transform.Transformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; -import org.qortal.transform.Transformer; - -import com.google.common.primitives.Ints; - public class ArbitraryDataMessage extends Message { private byte[] signature; diff --git a/src/main/java/org/qortal/network/message/BlockMessage.java b/src/main/java/org/qortal/network/message/BlockMessage.java index 0a8a23de..83b6d89e 100644 --- a/src/main/java/org/qortal/network/message/BlockMessage.java +++ b/src/main/java/org/qortal/network/message/BlockMessage.java @@ -1,8 +1,5 @@ package org.qortal.network.message; -import java.nio.ByteBuffer; -import java.util.List; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.data.at.ATStateData; @@ -11,7 +8,9 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.transform.TransformationException; import org.qortal.transform.block.BlockTransformation; import org.qortal.transform.block.BlockTransformer; -import org.qortal.utils.Triple; + +import java.nio.ByteBuffer; +import java.util.List; public class BlockMessage extends Message { diff --git a/src/main/java/org/qortal/network/message/BlockSummariesMessage.java b/src/main/java/org/qortal/network/message/BlockSummariesMessage.java index 513e30ae..f00c0a36 100644 --- a/src/main/java/org/qortal/network/message/BlockSummariesMessage.java +++ b/src/main/java/org/qortal/network/message/BlockSummariesMessage.java @@ -1,5 +1,10 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.data.block.BlockSummaryData; +import org.qortal.transform.Transformer; +import org.qortal.transform.block.BlockTransformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.BufferUnderflowException; @@ -7,12 +12,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import org.qortal.data.block.BlockSummaryData; -import org.qortal.transform.Transformer; -import org.qortal.transform.block.BlockTransformer; - -import com.google.common.primitives.Ints; - public class BlockSummariesMessage extends Message { private static final int BLOCK_SUMMARY_LENGTH = BlockTransformer.BLOCK_SIGNATURE_LENGTH + Transformer.INT_LENGTH + Transformer.PUBLIC_KEY_LENGTH + Transformer.INT_LENGTH; diff --git a/src/main/java/org/qortal/network/message/CachedBlockMessage.java b/src/main/java/org/qortal/network/message/CachedBlockMessage.java index 48e9ef36..e140f6fc 100644 --- a/src/main/java/org/qortal/network/message/CachedBlockMessage.java +++ b/src/main/java/org/qortal/network/message/CachedBlockMessage.java @@ -1,14 +1,13 @@ package org.qortal.network.message; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; import org.qortal.block.Block; import org.qortal.transform.TransformationException; import org.qortal.transform.block.BlockTransformer; -import com.google.common.primitives.Ints; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; // This is an OUTGOING-only Message which more readily lends itself to being cached public class CachedBlockMessage extends Message implements Cloneable { diff --git a/src/main/java/org/qortal/network/message/ChallengeMessage.java b/src/main/java/org/qortal/network/message/ChallengeMessage.java index bb5b2ae9..21a02baa 100644 --- a/src/main/java/org/qortal/network/message/ChallengeMessage.java +++ b/src/main/java/org/qortal/network/message/ChallengeMessage.java @@ -1,11 +1,11 @@ package org.qortal.network.message; +import org.qortal.transform.Transformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import org.qortal.transform.Transformer; - public class ChallengeMessage extends Message { public static final int CHALLENGE_LENGTH = 32; diff --git a/src/main/java/org/qortal/network/message/GetArbitraryDataMessage.java b/src/main/java/org/qortal/network/message/GetArbitraryDataMessage.java index bf604fe7..273d5532 100644 --- a/src/main/java/org/qortal/network/message/GetArbitraryDataMessage.java +++ b/src/main/java/org/qortal/network/message/GetArbitraryDataMessage.java @@ -1,10 +1,10 @@ package org.qortal.network.message; +import org.qortal.transform.Transformer; + import java.nio.ByteBuffer; import java.util.Arrays; -import org.qortal.transform.Transformer; - public class GetArbitraryDataMessage extends Message { private byte[] signature; diff --git a/src/main/java/org/qortal/network/message/GetBlockMessage.java b/src/main/java/org/qortal/network/message/GetBlockMessage.java index d39dcca0..1cf5da4e 100644 --- a/src/main/java/org/qortal/network/message/GetBlockMessage.java +++ b/src/main/java/org/qortal/network/message/GetBlockMessage.java @@ -1,10 +1,10 @@ package org.qortal.network.message; +import org.qortal.transform.block.BlockTransformer; + import java.nio.ByteBuffer; import java.util.Arrays; -import org.qortal.transform.block.BlockTransformer; - public class GetBlockMessage extends Message { private byte[] signature; diff --git a/src/main/java/org/qortal/network/message/GetBlockSummariesMessage.java b/src/main/java/org/qortal/network/message/GetBlockSummariesMessage.java index 70f0d5c5..f1867e3d 100644 --- a/src/main/java/org/qortal/network/message/GetBlockSummariesMessage.java +++ b/src/main/java/org/qortal/network/message/GetBlockSummariesMessage.java @@ -1,13 +1,12 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.transform.block.BlockTransformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import org.qortal.transform.block.BlockTransformer; - -import com.google.common.primitives.Ints; - public class GetBlockSummariesMessage extends Message { private byte[] parentSignature; diff --git a/src/main/java/org/qortal/network/message/GetOnlineAccountsV3Message.java b/src/main/java/org/qortal/network/message/GetOnlineAccountsV3Message.java index 66c7c47a..e1359023 100644 --- a/src/main/java/org/qortal/network/message/GetOnlineAccountsV3Message.java +++ b/src/main/java/org/qortal/network/message/GetOnlineAccountsV3Message.java @@ -6,7 +6,9 @@ import org.qortal.transform.Transformer; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; /** * For requesting online accounts info from remote peer, given our list of online accounts. diff --git a/src/main/java/org/qortal/network/message/GetSignaturesV2Message.java b/src/main/java/org/qortal/network/message/GetSignaturesV2Message.java index 0f88ba7d..01500dd9 100644 --- a/src/main/java/org/qortal/network/message/GetSignaturesV2Message.java +++ b/src/main/java/org/qortal/network/message/GetSignaturesV2Message.java @@ -1,13 +1,12 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.transform.block.BlockTransformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import org.qortal.transform.block.BlockTransformer; - -import com.google.common.primitives.Ints; - public class GetSignaturesV2Message extends Message { private byte[] parentSignature; diff --git a/src/main/java/org/qortal/network/message/GetTransactionMessage.java b/src/main/java/org/qortal/network/message/GetTransactionMessage.java index fe0c750f..149f7bff 100644 --- a/src/main/java/org/qortal/network/message/GetTransactionMessage.java +++ b/src/main/java/org/qortal/network/message/GetTransactionMessage.java @@ -1,10 +1,10 @@ package org.qortal.network.message; +import org.qortal.transform.Transformer; + import java.nio.ByteBuffer; import java.util.Arrays; -import org.qortal.transform.Transformer; - public class GetTransactionMessage extends Message { private byte[] signature; diff --git a/src/main/java/org/qortal/network/message/GoodbyeMessage.java b/src/main/java/org/qortal/network/message/GoodbyeMessage.java index 74130be2..dd6e13ee 100644 --- a/src/main/java/org/qortal/network/message/GoodbyeMessage.java +++ b/src/main/java/org/qortal/network/message/GoodbyeMessage.java @@ -1,12 +1,12 @@ package org.qortal.network.message; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; +import com.google.common.primitives.Ints; import java.nio.ByteBuffer; import java.util.Map; -import com.google.common.primitives.Ints; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; public class GoodbyeMessage extends Message { diff --git a/src/main/java/org/qortal/network/message/HeightV2Message.java b/src/main/java/org/qortal/network/message/HeightV2Message.java index 0e775a84..6626b430 100644 --- a/src/main/java/org/qortal/network/message/HeightV2Message.java +++ b/src/main/java/org/qortal/network/message/HeightV2Message.java @@ -1,15 +1,14 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import org.qortal.transform.Transformer; +import org.qortal.transform.block.BlockTransformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import org.qortal.transform.Transformer; -import org.qortal.transform.block.BlockTransformer; - -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; - public class HeightV2Message extends Message { private int height; diff --git a/src/main/java/org/qortal/network/message/HelloMessage.java b/src/main/java/org/qortal/network/message/HelloMessage.java index 30b7d9be..bb2d0eef 100644 --- a/src/main/java/org/qortal/network/message/HelloMessage.java +++ b/src/main/java/org/qortal/network/message/HelloMessage.java @@ -1,14 +1,13 @@ package org.qortal.network.message; +import com.google.common.primitives.Longs; +import org.qortal.transform.TransformationException; +import org.qortal.utils.Serialization; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import org.qortal.transform.TransformationException; -import org.qortal.utils.Serialization; - -import com.google.common.primitives.Longs; - public class HelloMessage extends Message { private long timestamp; diff --git a/src/main/java/org/qortal/network/message/Message.java b/src/main/java/org/qortal/network/message/Message.java index d8467d90..65262321 100644 --- a/src/main/java/org/qortal/network/message/Message.java +++ b/src/main/java/org/qortal/network/message/Message.java @@ -1,10 +1,9 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; import org.qortal.crypto.Crypto; import org.qortal.network.Network; -import com.google.common.primitives.Ints; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.BufferUnderflowException; diff --git a/src/main/java/org/qortal/network/message/PeersV2Message.java b/src/main/java/org/qortal/network/message/PeersV2Message.java index e844246f..bd240131 100644 --- a/src/main/java/org/qortal/network/message/PeersV2Message.java +++ b/src/main/java/org/qortal/network/message/PeersV2Message.java @@ -1,5 +1,9 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.network.PeerAddress; +import org.qortal.settings.Settings; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; @@ -7,11 +11,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import org.qortal.network.PeerAddress; -import org.qortal.settings.Settings; - -import com.google.common.primitives.Ints; - // NOTE: this message supports hostnames, literal IP addresses (IPv4 and IPv6) with port numbers public class PeersV2Message extends Message { diff --git a/src/main/java/org/qortal/network/message/ResponseMessage.java b/src/main/java/org/qortal/network/message/ResponseMessage.java index 292fe697..11e8a3d0 100644 --- a/src/main/java/org/qortal/network/message/ResponseMessage.java +++ b/src/main/java/org/qortal/network/message/ResponseMessage.java @@ -1,11 +1,11 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import com.google.common.primitives.Ints; - public class ResponseMessage extends Message { public static final int DATA_LENGTH = 32; diff --git a/src/main/java/org/qortal/network/message/SignaturesMessage.java b/src/main/java/org/qortal/network/message/SignaturesMessage.java index c0b44fcd..029cf74d 100644 --- a/src/main/java/org/qortal/network/message/SignaturesMessage.java +++ b/src/main/java/org/qortal/network/message/SignaturesMessage.java @@ -1,5 +1,8 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.transform.block.BlockTransformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.BufferUnderflowException; @@ -7,10 +10,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import org.qortal.transform.block.BlockTransformer; - -import com.google.common.primitives.Ints; - public class SignaturesMessage extends Message { private List signatures; diff --git a/src/main/java/org/qortal/network/message/TransactionMessage.java b/src/main/java/org/qortal/network/message/TransactionMessage.java index 51db6cf9..7ef4825a 100644 --- a/src/main/java/org/qortal/network/message/TransactionMessage.java +++ b/src/main/java/org/qortal/network/message/TransactionMessage.java @@ -1,11 +1,11 @@ package org.qortal.network.message; -import java.nio.ByteBuffer; - import org.qortal.data.transaction.TransactionData; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.TransactionTransformer; +import java.nio.ByteBuffer; + public class TransactionMessage extends Message { private TransactionData transactionData; diff --git a/src/main/java/org/qortal/network/message/TransactionSignaturesMessage.java b/src/main/java/org/qortal/network/message/TransactionSignaturesMessage.java index 395d3f00..0c56b416 100644 --- a/src/main/java/org/qortal/network/message/TransactionSignaturesMessage.java +++ b/src/main/java/org/qortal/network/message/TransactionSignaturesMessage.java @@ -1,5 +1,8 @@ package org.qortal.network.message; +import com.google.common.primitives.Ints; +import org.qortal.transform.Transformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.BufferUnderflowException; @@ -7,10 +10,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import org.qortal.transform.Transformer; - -import com.google.common.primitives.Ints; - public class TransactionSignaturesMessage extends Message { private List signatures; diff --git a/src/main/java/org/qortal/network/task/BroadcastTask.java b/src/main/java/org/qortal/network/task/BroadcastTask.java index 5714ebf6..c0617250 100644 --- a/src/main/java/org/qortal/network/task/BroadcastTask.java +++ b/src/main/java/org/qortal/network/task/BroadcastTask.java @@ -1,9 +1,6 @@ package org.qortal.network.task; import org.qortal.controller.Controller; -import org.qortal.network.Network; -import org.qortal.network.Peer; -import org.qortal.network.message.Message; import org.qortal.utils.ExecuteProduceConsume.Task; public class BroadcastTask implements Task { diff --git a/src/main/java/org/qortal/network/task/ChannelReadTask.java b/src/main/java/org/qortal/network/task/ChannelReadTask.java index edd4e8c0..ea7576c5 100644 --- a/src/main/java/org/qortal/network/task/ChannelReadTask.java +++ b/src/main/java/org/qortal/network/task/ChannelReadTask.java @@ -2,7 +2,6 @@ package org.qortal.network.task; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - import org.qortal.network.Network; import org.qortal.network.Peer; import org.qortal.utils.ExecuteProduceConsume.Task; diff --git a/src/main/java/org/qortal/network/task/PeerConnectTask.java b/src/main/java/org/qortal/network/task/PeerConnectTask.java index 759cabce..7eec4e6b 100644 --- a/src/main/java/org/qortal/network/task/PeerConnectTask.java +++ b/src/main/java/org/qortal/network/task/PeerConnectTask.java @@ -4,11 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.network.Network; import org.qortal.network.Peer; -import org.qortal.network.message.Message; -import org.qortal.network.message.MessageType; -import org.qortal.network.message.PingMessage; import org.qortal.utils.ExecuteProduceConsume.Task; -import org.qortal.utils.NTP; public class PeerConnectTask implements Task { private static final Logger LOGGER = LogManager.getLogger(PeerConnectTask.class); diff --git a/src/main/java/org/qortal/payment/Payment.java b/src/main/java/org/qortal/payment/Payment.java index 8b6070ee..f9bc5826 100644 --- a/src/main/java/org/qortal/payment/Payment.java +++ b/src/main/java/org/qortal/payment/Payment.java @@ -1,12 +1,5 @@ package org.qortal.payment; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; @@ -20,6 +13,9 @@ import org.qortal.repository.Repository; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.utils.Amounts; +import java.util.*; +import java.util.Map.Entry; + public class Payment { // Properties diff --git a/src/main/java/org/qortal/repository/ATRepository.java b/src/main/java/org/qortal/repository/ATRepository.java index 93da924c..455ba393 100644 --- a/src/main/java/org/qortal/repository/ATRepository.java +++ b/src/main/java/org/qortal/repository/ATRepository.java @@ -1,14 +1,12 @@ package org.qortal.repository; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; -import java.util.Set; - import org.qortal.data.at.ATData; import org.qortal.data.at.ATStateData; import org.qortal.utils.ByteArray; +import java.util.List; +import java.util.Set; + public interface ATRepository { // CIYAM AutomatedTransactions diff --git a/src/main/java/org/qortal/repository/AccountRepository.java b/src/main/java/org/qortal/repository/AccountRepository.java index 1175337c..bdad187b 100644 --- a/src/main/java/org/qortal/repository/AccountRepository.java +++ b/src/main/java/org/qortal/repository/AccountRepository.java @@ -1,10 +1,10 @@ package org.qortal.repository; +import org.qortal.data.account.*; + import java.util.List; import java.util.Set; -import org.qortal.data.account.*; - public interface AccountRepository { // General account diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index c586871f..175f1daf 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -6,7 +6,7 @@ import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.ArbitraryTransactionData.*; +import org.qortal.data.transaction.ArbitraryTransactionData.Method; import java.util.List; diff --git a/src/main/java/org/qortal/repository/AssetRepository.java b/src/main/java/org/qortal/repository/AssetRepository.java index fb516880..4dbc90fe 100644 --- a/src/main/java/org/qortal/repository/AssetRepository.java +++ b/src/main/java/org/qortal/repository/AssetRepository.java @@ -1,12 +1,12 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.asset.AssetData; import org.qortal.data.asset.OrderData; import org.qortal.data.asset.RecentTradeData; import org.qortal.data.asset.TradeData; +import java.util.List; + public interface AssetRepository { // Assets diff --git a/src/main/java/org/qortal/repository/BlockArchiveReader.java b/src/main/java/org/qortal/repository/BlockArchiveReader.java index 1f04bced..7b2e098a 100644 --- a/src/main/java/org/qortal/repository/BlockArchiveReader.java +++ b/src/main/java/org/qortal/repository/BlockArchiveReader.java @@ -10,14 +10,14 @@ import org.qortal.transform.block.BlockTransformation; import org.qortal.transform.block.BlockTransformer; import org.qortal.utils.Triple; -import static org.qortal.transform.Transformer.INT_LENGTH; - import java.io.*; import java.nio.ByteBuffer; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import static org.qortal.transform.Transformer.INT_LENGTH; + public class BlockArchiveReader { private static BlockArchiveReader instance; diff --git a/src/main/java/org/qortal/repository/BlockRepository.java b/src/main/java/org/qortal/repository/BlockRepository.java index 76891c36..429e34cb 100644 --- a/src/main/java/org/qortal/repository/BlockRepository.java +++ b/src/main/java/org/qortal/repository/BlockRepository.java @@ -1,13 +1,13 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.api.model.BlockSignerSummary; import org.qortal.data.block.BlockData; import org.qortal.data.block.BlockSummaryData; import org.qortal.data.block.BlockTransactionData; import org.qortal.data.transaction.TransactionData; +import java.util.List; + public interface BlockRepository { /** diff --git a/src/main/java/org/qortal/repository/ChatRepository.java b/src/main/java/org/qortal/repository/ChatRepository.java index 7443fb51..d046fe6b 100644 --- a/src/main/java/org/qortal/repository/ChatRepository.java +++ b/src/main/java/org/qortal/repository/ChatRepository.java @@ -1,11 +1,11 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.chat.ActiveChats; import org.qortal.data.chat.ChatMessage; import org.qortal.data.transaction.ChatTransactionData; +import java.util.List; + import static org.qortal.data.chat.ChatMessage.Encoding; public interface ChatRepository { diff --git a/src/main/java/org/qortal/repository/CrossChainRepository.java b/src/main/java/org/qortal/repository/CrossChainRepository.java index 70ebdbf9..405fdfb5 100644 --- a/src/main/java/org/qortal/repository/CrossChainRepository.java +++ b/src/main/java/org/qortal/repository/CrossChainRepository.java @@ -1,9 +1,9 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.crosschain.TradeBotData; +import java.util.List; + public interface CrossChainRepository { public TradeBotData getTradeBotData(byte[] tradePrivateKey) throws DataException; diff --git a/src/main/java/org/qortal/repository/GroupRepository.java b/src/main/java/org/qortal/repository/GroupRepository.java index 94c97992..49427b02 100644 --- a/src/main/java/org/qortal/repository/GroupRepository.java +++ b/src/main/java/org/qortal/repository/GroupRepository.java @@ -1,13 +1,8 @@ package org.qortal.repository; -import java.util.List; +import org.qortal.data.group.*; -import org.qortal.data.group.GroupAdminData; -import org.qortal.data.group.GroupBanData; -import org.qortal.data.group.GroupData; -import org.qortal.data.group.GroupInviteData; -import org.qortal.data.group.GroupJoinRequestData; -import org.qortal.data.group.GroupMemberData; +import java.util.List; public interface GroupRepository { diff --git a/src/main/java/org/qortal/repository/MessageRepository.java b/src/main/java/org/qortal/repository/MessageRepository.java index db74f0e6..da43cf7e 100644 --- a/src/main/java/org/qortal/repository/MessageRepository.java +++ b/src/main/java/org/qortal/repository/MessageRepository.java @@ -1,9 +1,9 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.transaction.MessageTransactionData; +import java.util.List; + public interface MessageRepository { /** diff --git a/src/main/java/org/qortal/repository/NameRepository.java b/src/main/java/org/qortal/repository/NameRepository.java index 52a43a18..c49d5d18 100644 --- a/src/main/java/org/qortal/repository/NameRepository.java +++ b/src/main/java/org/qortal/repository/NameRepository.java @@ -1,9 +1,9 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.naming.NameData; +import java.util.List; + public interface NameRepository { public NameData fromName(String name) throws DataException; diff --git a/src/main/java/org/qortal/repository/NetworkRepository.java b/src/main/java/org/qortal/repository/NetworkRepository.java index e7a5126d..a6f1775a 100644 --- a/src/main/java/org/qortal/repository/NetworkRepository.java +++ b/src/main/java/org/qortal/repository/NetworkRepository.java @@ -1,10 +1,10 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.network.PeerData; import org.qortal.network.PeerAddress; +import java.util.List; + public interface NetworkRepository { public List getAllPeers() throws DataException; diff --git a/src/main/java/org/qortal/repository/TransactionRepository.java b/src/main/java/org/qortal/repository/TransactionRepository.java index 41986cad..e007586e 100644 --- a/src/main/java/org/qortal/repository/TransactionRepository.java +++ b/src/main/java/org/qortal/repository/TransactionRepository.java @@ -1,9 +1,5 @@ package org.qortal.repository; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; - import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; import org.qortal.arbitrary.misc.Service; import org.qortal.data.group.GroupApprovalData; @@ -12,6 +8,10 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.TransferAssetTransactionData; import org.qortal.transaction.Transaction.TransactionType; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; + public interface TransactionRepository { // Fetching transactions / transaction height diff --git a/src/main/java/org/qortal/repository/VotingRepository.java b/src/main/java/org/qortal/repository/VotingRepository.java index b0e2954c..d5ce1585 100644 --- a/src/main/java/org/qortal/repository/VotingRepository.java +++ b/src/main/java/org/qortal/repository/VotingRepository.java @@ -1,10 +1,10 @@ package org.qortal.repository; -import java.util.List; - import org.qortal.data.voting.PollData; import org.qortal.data.voting.VoteOnPollData; +import java.util.List; + public interface VotingRepository { // Polls diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBATRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBATRepository.java index 33817309..80fc62dc 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBATRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBATRepository.java @@ -1,11 +1,6 @@ package org.qortal.repository.hsqldb; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - +import com.google.common.primitives.Longs; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.controller.Controller; @@ -15,7 +10,11 @@ import org.qortal.repository.ATRepository; import org.qortal.repository.DataException; import org.qortal.utils.ByteArray; -import com.google.common.primitives.Longs; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; public class HSQLDBATRepository implements ATRepository { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java index cb188502..7aef66ce 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java @@ -1,6 +1,9 @@ package org.qortal.repository.hsqldb; -import static org.qortal.utils.Amounts.prettyAmount; +import org.qortal.asset.Asset; +import org.qortal.data.account.*; +import org.qortal.repository.AccountRepository; +import org.qortal.repository.DataException; import java.sql.ResultSet; import java.sql.SQLException; @@ -9,10 +12,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import org.qortal.asset.Asset; -import org.qortal.data.account.*; -import org.qortal.repository.AccountRepository; -import org.qortal.repository.DataException; +import static org.qortal.utils.Amounts.prettyAmount; public class HSQLDBAccountRepository implements AccountRepository { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 66829d92..eaa7be2a 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -3,6 +3,7 @@ package org.qortal.repository.hsqldb; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.api.SearchMode; +import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; @@ -10,12 +11,13 @@ import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.ArbitraryTransactionData.*; +import org.qortal.data.transaction.ArbitraryTransactionData.Compression; +import org.qortal.data.transaction.ArbitraryTransactionData.DataType; +import org.qortal.data.transaction.ArbitraryTransactionData.Method; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.ArbitraryRepository; import org.qortal.repository.DataException; -import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.transaction.ArbitraryTransaction; import org.qortal.transaction.Transaction.ApprovalStatus; import org.qortal.utils.Base58; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java index 6610a4f3..6e68cda8 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java @@ -1,11 +1,5 @@ package org.qortal.repository.hsqldb; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import org.qortal.data.asset.AssetData; import org.qortal.data.asset.OrderData; import org.qortal.data.asset.RecentTradeData; @@ -13,6 +7,12 @@ import org.qortal.data.asset.TradeData; import org.qortal.repository.AssetRepository; import org.qortal.repository.DataException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + public class HSQLDBAssetRepository implements AssetRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java index f38d549c..f592a79d 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java @@ -1,21 +1,20 @@ package org.qortal.repository.hsqldb; +import org.qortal.api.model.BlockSignerSummary; +import org.qortal.data.block.BlockData; +import org.qortal.data.block.BlockSummaryData; +import org.qortal.data.block.BlockTransactionData; +import org.qortal.data.transaction.TransactionData; +import org.qortal.repository.BlockRepository; +import org.qortal.repository.DataException; +import org.qortal.repository.TransactionRepository; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.qortal.api.model.BlockSignerSummary; -import org.qortal.data.block.BlockData; -import org.qortal.data.block.BlockSummaryData; -import org.qortal.data.block.BlockTransactionData; -import org.qortal.data.block.BlockArchiveData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.repository.BlockRepository; -import org.qortal.repository.DataException; -import org.qortal.repository.TransactionRepository; - public class HSQLDBBlockRepository implements BlockRepository { private static final String BLOCK_DB_COLUMNS = "version, reference, transaction_count, total_fees, " diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBChatRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBChatRepository.java index 9e310e78..6bc4fa49 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBChatRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBChatRepository.java @@ -1,10 +1,5 @@ package org.qortal.repository.hsqldb; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - import org.qortal.data.chat.ActiveChats; import org.qortal.data.chat.ActiveChats.DirectChat; import org.qortal.data.chat.ActiveChats.GroupChat; @@ -14,6 +9,11 @@ import org.qortal.repository.ChatRepository; import org.qortal.repository.DataException; import org.qortal.transaction.Transaction.TransactionType; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + import static org.qortal.data.chat.ChatMessage.Encoding; public class HSQLDBChatRepository implements ChatRepository { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBCrossChainRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBCrossChainRepository.java index 29f2994c..6305a468 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBCrossChainRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBCrossChainRepository.java @@ -1,15 +1,15 @@ package org.qortal.repository.hsqldb; +import org.qortal.data.crosschain.TradeBotData; +import org.qortal.repository.CrossChainRepository; +import org.qortal.repository.DataException; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.qortal.data.crosschain.TradeBotData; -import org.qortal.repository.CrossChainRepository; -import org.qortal.repository.DataException; - public class HSQLDBCrossChainRepository implements CrossChainRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index 2a11f199..829f7aab 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -1,5 +1,11 @@ package org.qortal.repository.hsqldb; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.controller.Controller; +import org.qortal.controller.tradebot.BitcoinACCTv1TradeBot; +import org.qortal.gui.SplashFrame; + import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -7,12 +13,6 @@ import java.sql.Statement; import java.util.Arrays; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.qortal.controller.Controller; -import org.qortal.controller.tradebot.BitcoinACCTv1TradeBot; -import org.qortal.gui.SplashFrame; - public class HSQLDBDatabaseUpdates { private static final Logger LOGGER = LogManager.getLogger(HSQLDBDatabaseUpdates.class); diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBGroupRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBGroupRepository.java index b1cd40a0..9c7521fc 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBGroupRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBGroupRepository.java @@ -1,20 +1,15 @@ package org.qortal.repository.hsqldb; +import org.qortal.data.group.*; +import org.qortal.group.Group.ApprovalThreshold; +import org.qortal.repository.DataException; +import org.qortal.repository.GroupRepository; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import org.qortal.data.group.GroupAdminData; -import org.qortal.data.group.GroupBanData; -import org.qortal.data.group.GroupData; -import org.qortal.data.group.GroupInviteData; -import org.qortal.data.group.GroupJoinRequestData; -import org.qortal.data.group.GroupMemberData; -import org.qortal.group.Group.ApprovalThreshold; -import org.qortal.repository.DataException; -import org.qortal.repository.GroupRepository; - public class HSQLDBGroupRepository implements GroupRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBMessageRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBMessageRepository.java index f31c5cd8..7a0e9677 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBMessageRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBMessageRepository.java @@ -1,16 +1,16 @@ package org.qortal.repository.hsqldb; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - import org.qortal.data.transaction.MessageTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.MessageRepository; import org.qortal.transaction.Transaction.TransactionType; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + public class HSQLDBMessageRepository implements MessageRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBNameRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBNameRepository.java index 2fefcf8b..06e41663 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBNameRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBNameRepository.java @@ -1,14 +1,14 @@ package org.qortal.repository.hsqldb; +import org.qortal.data.naming.NameData; +import org.qortal.repository.DataException; +import org.qortal.repository.NameRepository; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import org.qortal.data.naming.NameData; -import org.qortal.repository.DataException; -import org.qortal.repository.NameRepository; - public class HSQLDBNameRepository implements NameRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBNetworkRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBNetworkRepository.java index 9f865160..cc9ad068 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBNetworkRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBNetworkRepository.java @@ -1,15 +1,15 @@ package org.qortal.repository.hsqldb; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - import org.qortal.data.network.PeerData; import org.qortal.network.PeerAddress; import org.qortal.repository.DataException; import org.qortal.repository.NetworkRepository; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + public class HSQLDBNetworkRepository implements NetworkRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepository.java index 6ec30e20..4a41ed68 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepository.java @@ -1,26 +1,5 @@ package org.qortal.repository.hsqldb; -import java.awt.TrayIcon.MessageType; -import java.io.File; -import java.io.IOException; -import java.math.BigDecimal; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import java.util.*; -import java.util.concurrent.TimeoutException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.crypto.Crypto; @@ -30,6 +9,21 @@ import org.qortal.repository.*; import org.qortal.repository.hsqldb.transaction.HSQLDBTransactionRepository; import org.qortal.settings.Settings; +import java.awt.TrayIcon.MessageType; +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.*; +import java.util.*; +import java.util.concurrent.TimeoutException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + public class HSQLDBRepository implements Repository { private static final Logger LOGGER = LogManager.getLogger(HSQLDBRepository.class); diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepositoryFactory.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepositoryFactory.java index 64f6be8c..fdaf41a2 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepositoryFactory.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBRepositoryFactory.java @@ -1,11 +1,5 @@ package org.qortal.repository.hsqldb; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hsqldb.HsqlException; @@ -16,6 +10,12 @@ import org.qortal.repository.Repository; import org.qortal.repository.RepositoryFactory; import org.qortal.settings.Settings; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + public class HSQLDBRepositoryFactory implements RepositoryFactory { private static final Logger LOGGER = LogManager.getLogger(HSQLDBRepositoryFactory.class); diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBVotingRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBVotingRepository.java index cc33426b..9bae8ec5 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBVotingRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBVotingRepository.java @@ -1,16 +1,16 @@ package org.qortal.repository.hsqldb; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - import org.qortal.data.voting.PollData; import org.qortal.data.voting.PollOptionData; import org.qortal.data.voting.VoteOnPollData; import org.qortal.repository.DataException; import org.qortal.repository.VotingRepository; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + public class HSQLDBVotingRepository implements VotingRepository { protected HSQLDBRepository repository; diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java index 9d9b8800..f6c6c82a 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.AccountFlagsTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBAccountFlagsTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBAccountFlagsTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountLevelTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountLevelTransactionRepository.java index c4aa37de..3f2b3247 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountLevelTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAccountLevelTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.AccountLevelTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBAccountLevelTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBAccountLevelTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java index 686308c1..56116da8 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.AddGroupAdminTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBAddGroupAdminTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java index 57b75a29..c9737520 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java @@ -1,19 +1,18 @@ package org.qortal.repository.hsqldb.transaction; +import org.qortal.data.PaymentData; +import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.data.transaction.ArbitraryTransactionData.DataType; +import org.qortal.data.transaction.BaseTransactionData; +import org.qortal.data.transaction.TransactionData; +import org.qortal.repository.DataException; +import org.qortal.repository.hsqldb.HSQLDBRepository; +import org.qortal.repository.hsqldb.HSQLDBSaver; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.qortal.arbitrary.misc.Service; -import org.qortal.data.PaymentData; -import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.BaseTransactionData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.data.transaction.ArbitraryTransactionData.DataType; -import org.qortal.repository.DataException; -import org.qortal.repository.hsqldb.HSQLDBRepository; -import org.qortal.repository.hsqldb.HSQLDBSaver; - public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBArbitraryTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java index a816ec60..3771a0f1 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.ATTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBAtTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java index 8ae4ffa2..724d93dd 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.BuyNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBBuyNameTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java index d49e83ba..1adb9db3 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelAssetOrderTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBCancelAssetOrderTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCancelAssetOrderTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java index 76524b05..b94df99f 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelGroupBanTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCancelGroupBanTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java index d61fa79b..cc17c18c 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelGroupInviteTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCancelGroupInviteTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java index fc8e0bb3..925b18cc 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelSellNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCancelSellNameTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBChatTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBChatTransactionRepository.java index 79e798a9..aea22442 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBChatTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBChatTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.ChatTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBChatTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBChatTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java index 7cea87bb..0609c82f 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CreateAssetOrderTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCreateAssetOrderTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java index 583b9fa6..73698aa4 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CreateGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,6 +8,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCreateGroupTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java index 28163ab9..e2675ac1 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java @@ -1,10 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CreatePollTransactionData; import org.qortal.data.transaction.TransactionData; @@ -13,6 +8,11 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBCreatePollTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java index 6c3b60c2..e5695483 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.DeployAtTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBDeployAtTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java index d0a65df0..1f4ac7f5 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GenesisTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBGenesisTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBGenesisTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java index c8afed3d..0f8953a3 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupApprovalTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBGroupApprovalTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBGroupApprovalTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java index ae3fef43..386e1425 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupBanTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBGroupBanTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java index 64ec5c64..97279c0e 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupInviteTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBGroupInviteTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java index 9dd3c98d..d84f3ad5 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupKickTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBGroupKickTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java index 2386ef95..37ed9a3a 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.IssueAssetTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBIssueAssetTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java index 7f9ce13d..b46fe7b6 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.JoinGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBJoinGroupTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java index c5aa3b00..cca83f88 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.LeaveGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBLeaveGroupTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java index 567075e3..515d36a8 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.MessageTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBMessageTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java index 69cd9c49..1b889248 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java @@ -1,9 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - import org.qortal.data.PaymentData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.MultiPaymentTransactionData; @@ -12,6 +8,10 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + public class HSQLDBMultiPaymentTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBMultiPaymentTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java index a4942e3f..d9c660ef 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.PaymentTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBPaymentTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBPaymentTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPresenceTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPresenceTransactionRepository.java index 309ffcad..c72c2ae4 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPresenceTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPresenceTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.PresenceTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,6 +8,9 @@ import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; import org.qortal.transaction.PresenceTransaction.PresenceType; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBPresenceTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBPresenceTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPublicizeTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPublicizeTransactionRepository.java index d67c61b4..53af733f 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPublicizeTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBPublicizeTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.PublicizeTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBPublicizeTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBPublicizeTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java index 82da794f..5b81ad72 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.RegisterNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBRegisterNameTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java index 09b6892d..5a440b22 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.RemoveGroupAdminTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBRemoveGroupAdminTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRewardShareTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRewardShareTransactionRepository.java index 81a567ea..7437fd51 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRewardShareTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBRewardShareTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.RewardShareTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBRewardShareTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBRewardShareTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java index f5fa3681..ae4a07dd 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.SellNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBSellNameTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java index f3be4c04..a76361a7 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.SetGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBSetGroupTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBSetGroupTransactionRepository(HSQLDBRepository repository) { 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 60b4e803..5b41a85d 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransactionRepository.java @@ -1,14 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import static org.qortal.transaction.Transaction.TransactionType.*; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; @@ -28,6 +19,15 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.utils.Base58; import org.qortal.utils.Unicode; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +import static org.qortal.transaction.Transaction.TransactionType.*; + public class HSQLDBTransactionRepository implements TransactionRepository { private static final Logger LOGGER = LogManager.getLogger(HSQLDBTransactionRepository.class); diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java index 5c0a23d0..95db5163 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.TransferAssetTransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBTransferAssetTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBTransferAssetTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferPrivsTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferPrivsTransactionRepository.java index ae2ab9bb..832af73c 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferPrivsTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBTransferPrivsTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.TransferPrivsTransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBTransferPrivsTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBTransferPrivsTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java index 8e0b1975..9d56f280 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.UpdateAssetTransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBUpdateAssetTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBUpdateAssetTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java index e2c2e72a..ae584171 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.UpdateGroupTransactionData; @@ -11,6 +8,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBUpdateGroupTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java index 447ab5c6..f39412f0 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.UpdateNameTransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBUpdateNameTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java index 0d260904..8ef6397d 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java @@ -1,8 +1,5 @@ package org.qortal.repository.hsqldb.transaction; -import java.sql.ResultSet; -import java.sql.SQLException; - import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.VoteOnPollTransactionData; @@ -10,6 +7,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.repository.hsqldb.HSQLDBSaver; +import java.sql.ResultSet; +import java.sql.SQLException; + public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepository { public HSQLDBVoteOnPollTransactionRepository(HSQLDBRepository repository) { diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index babef614..fc8ba4ce 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -1,12 +1,20 @@ package org.qortal.settings; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Paths; -import java.util.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.eclipse.persistence.exceptions.XMLMarshalException; +import org.eclipse.persistence.jaxb.JAXBContextFactory; +import org.eclipse.persistence.jaxb.UnmarshallerProperties; +import org.qortal.block.BlockChain; +import org.qortal.controller.arbitrary.ArbitraryDataStorageManager.StoragePolicy; +import org.qortal.crosschain.Bitcoin.BitcoinNet; +import org.qortal.crosschain.Digibyte.DigibyteNet; +import org.qortal.crosschain.Dogecoin.DogecoinNet; +import org.qortal.crosschain.Litecoin.LitecoinNet; +import org.qortal.crosschain.PirateChain.PirateChainNet; +import org.qortal.crosschain.Ravencoin.RavencoinNet; +import org.qortal.network.message.MessageType; +import org.qortal.utils.EnumUtils; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; @@ -15,22 +23,9 @@ import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.transform.stream.StreamSource; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.eclipse.persistence.exceptions.XMLMarshalException; -import org.eclipse.persistence.jaxb.JAXBContextFactory; -import org.eclipse.persistence.jaxb.UnmarshallerProperties; -import org.qortal.block.BlockChain; -import org.qortal.controller.arbitrary.ArbitraryDataStorageManager.*; -import org.qortal.crosschain.Bitcoin.BitcoinNet; -import org.qortal.crosschain.Litecoin.LitecoinNet; -import org.qortal.crosschain.Dogecoin.DogecoinNet; -import org.qortal.crosschain.Digibyte.DigibyteNet; -import org.qortal.crosschain.Ravencoin.RavencoinNet; -import org.qortal.crosschain.PirateChain.PirateChainNet; -import org.qortal.network.message.MessageType; -import org.qortal.utils.EnumUtils; +import java.io.*; +import java.nio.file.Paths; +import java.util.*; // All properties to be converted to JSON via JAXB @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/transaction/AccountFlagsTransaction.java b/src/main/java/org/qortal/transaction/AccountFlagsTransaction.java index 4362b1a9..47500f9a 100644 --- a/src/main/java/org/qortal/transaction/AccountFlagsTransaction.java +++ b/src/main/java/org/qortal/transaction/AccountFlagsTransaction.java @@ -1,14 +1,14 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.data.transaction.AccountFlagsTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class AccountFlagsTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/AccountLevelTransaction.java b/src/main/java/org/qortal/transaction/AccountLevelTransaction.java index 18324c34..833e63ad 100644 --- a/src/main/java/org/qortal/transaction/AccountLevelTransaction.java +++ b/src/main/java/org/qortal/transaction/AccountLevelTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.block.BlockChain; import org.qortal.data.transaction.AccountLevelTransactionData; @@ -10,6 +7,9 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class AccountLevelTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/AddGroupAdminTransaction.java b/src/main/java/org/qortal/transaction/AddGroupAdminTransaction.java index f38638c5..7ee0e785 100644 --- a/src/main/java/org/qortal/transaction/AddGroupAdminTransaction.java +++ b/src/main/java/org/qortal/transaction/AddGroupAdminTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -13,6 +9,10 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + public class AddGroupAdminTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 86a1f0e2..1a9f888b 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -1,18 +1,13 @@ package org.qortal.transaction; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; +import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.block.BlockChain; -import org.qortal.controller.arbitrary.ArbitraryDataCacheManager; import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; import org.qortal.crypto.Crypto; @@ -27,7 +22,6 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.payment.Payment; import org.qortal.repository.DataException; import org.qortal.repository.Repository; -import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.repository.RepositoryManager; import org.qortal.transform.TransformationException; import org.qortal.transform.Transformer; @@ -36,6 +30,11 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.NTP; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + public class ArbitraryTransaction extends Transaction { private static final Logger LOGGER = LogManager.getLogger(ArbitraryTransaction.class); diff --git a/src/main/java/org/qortal/transaction/AtTransaction.java b/src/main/java/org/qortal/transaction/AtTransaction.java index b07f006b..398ac6c0 100644 --- a/src/main/java/org/qortal/transaction/AtTransaction.java +++ b/src/main/java/org/qortal/transaction/AtTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Arrays; -import java.util.List; - +import com.google.common.primitives.Bytes; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.block.BlockChain; @@ -17,7 +15,8 @@ import org.qortal.transform.Transformer; import org.qortal.transform.transaction.AtTransactionTransformer; import org.qortal.utils.Amounts; -import com.google.common.primitives.Bytes; +import java.util.Arrays; +import java.util.List; public class AtTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/BuyNameTransaction.java b/src/main/java/org/qortal/transaction/BuyNameTransaction.java index fe6d8d34..72c15f69 100644 --- a/src/main/java/org/qortal/transaction/BuyNameTransaction.java +++ b/src/main/java/org/qortal/transaction/BuyNameTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.block.BlockChain; @@ -16,7 +14,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class BuyNameTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/CancelAssetOrderTransaction.java b/src/main/java/org/qortal/transaction/CancelAssetOrderTransaction.java index 955f62f4..946b8ab1 100644 --- a/src/main/java/org/qortal/transaction/CancelAssetOrderTransaction.java +++ b/src/main/java/org/qortal/transaction/CancelAssetOrderTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.asset.Order; @@ -14,6 +10,10 @@ import org.qortal.repository.AssetRepository; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + public class CancelAssetOrderTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/CancelGroupBanTransaction.java b/src/main/java/org/qortal/transaction/CancelGroupBanTransaction.java index 08d9cb3e..a9577bc5 100644 --- a/src/main/java/org/qortal/transaction/CancelGroupBanTransaction.java +++ b/src/main/java/org/qortal/transaction/CancelGroupBanTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -13,6 +10,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class CancelGroupBanTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/CancelGroupInviteTransaction.java b/src/main/java/org/qortal/transaction/CancelGroupInviteTransaction.java index 800f2444..d4306bbe 100644 --- a/src/main/java/org/qortal/transaction/CancelGroupInviteTransaction.java +++ b/src/main/java/org/qortal/transaction/CancelGroupInviteTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -13,6 +10,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class CancelGroupInviteTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/CancelSellNameTransaction.java b/src/main/java/org/qortal/transaction/CancelSellNameTransaction.java index 876f0aed..aa0e6a6f 100644 --- a/src/main/java/org/qortal/transaction/CancelSellNameTransaction.java +++ b/src/main/java/org/qortal/transaction/CancelSellNameTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; @@ -14,7 +12,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class CancelSellNameTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/ChatTransaction.java b/src/main/java/org/qortal/transaction/ChatTransaction.java index 3d968461..3004b5b9 100644 --- a/src/main/java/org/qortal/transaction/ChatTransaction.java +++ b/src/main/java/org/qortal/transaction/ChatTransaction.java @@ -1,21 +1,14 @@ package org.qortal.transaction; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; -import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; import org.qortal.crypto.Crypto; import org.qortal.crypto.MemoryPoW; import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ChatTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.group.Group; -import org.qortal.list.ResourceListManager; import org.qortal.repository.DataException; import org.qortal.repository.GroupRepository; import org.qortal.repository.Repository; @@ -26,6 +19,11 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.ListUtils; import org.qortal.utils.NTP; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; + public class ChatTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java b/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java index 24e57a4e..20c17562 100644 --- a/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java +++ b/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.asset.Order; @@ -16,6 +12,10 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Amounts; +import java.math.BigInteger; +import java.util.Collections; +import java.util.List; + public class CreateAssetOrderTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/CreateGroupTransaction.java b/src/main/java/org/qortal/transaction/CreateGroupTransaction.java index 6f4a3634..d01de4a9 100644 --- a/src/main/java/org/qortal/transaction/CreateGroupTransaction.java +++ b/src/main/java/org/qortal/transaction/CreateGroupTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.transaction.CreateGroupTransactionData; @@ -12,7 +10,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class CreateGroupTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/CreatePollTransaction.java b/src/main/java/org/qortal/transaction/CreatePollTransaction.java index a56322a7..e2e4c470 100644 --- a/src/main/java/org/qortal/transaction/CreatePollTransaction.java +++ b/src/main/java/org/qortal/transaction/CreatePollTransaction.java @@ -1,9 +1,6 @@ package org.qortal.transaction; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -15,7 +12,9 @@ import org.qortal.repository.Repository; import org.qortal.utils.Unicode; import org.qortal.voting.Poll; -import com.google.common.base.Utf8; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class CreatePollTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/DeployAtTransaction.java b/src/main/java/org/qortal/transaction/DeployAtTransaction.java index f3024b57..775119ad 100644 --- a/src/main/java/org/qortal/transaction/DeployAtTransaction.java +++ b/src/main/java/org/qortal/transaction/DeployAtTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.ciyam.at.MachineState; import org.ciyam.at.Timestamp; import org.qortal.account.Account; @@ -18,10 +16,11 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.transform.TransformationException; -import org.qortal.utils.Amounts; import org.qortal.transform.transaction.TransactionTransformer; +import org.qortal.utils.Amounts; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class DeployAtTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/GenesisTransaction.java b/src/main/java/org/qortal/transaction/GenesisTransaction.java index 74a84a7d..48372dc9 100644 --- a/src/main/java/org/qortal/transaction/GenesisTransaction.java +++ b/src/main/java/org/qortal/transaction/GenesisTransaction.java @@ -1,9 +1,6 @@ package org.qortal.transaction; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - +import com.google.common.primitives.Bytes; import org.qortal.account.Account; import org.qortal.account.PrivateKeyAccount; import org.qortal.crypto.Crypto; @@ -14,7 +11,9 @@ import org.qortal.repository.Repository; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.TransactionTransformer; -import com.google.common.primitives.Bytes; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; public class GenesisTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/GroupApprovalTransaction.java b/src/main/java/org/qortal/transaction/GroupApprovalTransaction.java index 1c8bb709..a88ad3bf 100644 --- a/src/main/java/org/qortal/transaction/GroupApprovalTransaction.java +++ b/src/main/java/org/qortal/transaction/GroupApprovalTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.transaction.GroupApprovalTransactionData; @@ -10,6 +7,9 @@ import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class GroupApprovalTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/GroupBanTransaction.java b/src/main/java/org/qortal/transaction/GroupBanTransaction.java index c9a6c307..27c00d5c 100644 --- a/src/main/java/org/qortal/transaction/GroupBanTransaction.java +++ b/src/main/java/org/qortal/transaction/GroupBanTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -13,6 +10,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class GroupBanTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/GroupInviteTransaction.java b/src/main/java/org/qortal/transaction/GroupInviteTransaction.java index fa5e7b85..e58d1b9c 100644 --- a/src/main/java/org/qortal/transaction/GroupInviteTransaction.java +++ b/src/main/java/org/qortal/transaction/GroupInviteTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -12,6 +9,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class GroupInviteTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/GroupKickTransaction.java b/src/main/java/org/qortal/transaction/GroupKickTransaction.java index 84de3a59..d67f3d15 100644 --- a/src/main/java/org/qortal/transaction/GroupKickTransaction.java +++ b/src/main/java/org/qortal/transaction/GroupKickTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; @@ -15,6 +12,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.GroupRepository; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class GroupKickTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/IssueAssetTransaction.java b/src/main/java/org/qortal/transaction/IssueAssetTransaction.java index 52428963..0ba41f27 100644 --- a/src/main/java/org/qortal/transaction/IssueAssetTransaction.java +++ b/src/main/java/org/qortal/transaction/IssueAssetTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.transaction.IssueAssetTransactionData; @@ -12,7 +10,8 @@ import org.qortal.repository.Repository; import org.qortal.utils.Amounts; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class IssueAssetTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/JoinGroupTransaction.java b/src/main/java/org/qortal/transaction/JoinGroupTransaction.java index 3061a3fb..56cb4d3c 100644 --- a/src/main/java/org/qortal/transaction/JoinGroupTransaction.java +++ b/src/main/java/org/qortal/transaction/JoinGroupTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.transaction.JoinGroupTransactionData; @@ -11,6 +8,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class JoinGroupTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/LeaveGroupTransaction.java b/src/main/java/org/qortal/transaction/LeaveGroupTransaction.java index 1e8f8c6c..2af3ba1a 100644 --- a/src/main/java/org/qortal/transaction/LeaveGroupTransaction.java +++ b/src/main/java/org/qortal/transaction/LeaveGroupTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.group.GroupData; @@ -12,6 +9,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class LeaveGroupTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/MessageTransaction.java b/src/main/java/org/qortal/transaction/MessageTransaction.java index b61c3d11..4ecf8e7f 100644 --- a/src/main/java/org/qortal/transaction/MessageTransaction.java +++ b/src/main/java/org/qortal/transaction/MessageTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; -import java.util.Random; - import org.qortal.account.Account; import org.qortal.account.PrivateKeyAccount; import org.qortal.account.PublicKeyAccount; @@ -27,6 +23,10 @@ import org.qortal.transform.transaction.MessageTransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.NTP; +import java.util.Collections; +import java.util.List; +import java.util.Random; + public class MessageTransaction extends Transaction { // Useful constants diff --git a/src/main/java/org/qortal/transaction/MultiPaymentTransaction.java b/src/main/java/org/qortal/transaction/MultiPaymentTransaction.java index 34cd0147..2c7c1175 100644 --- a/src/main/java/org/qortal/transaction/MultiPaymentTransaction.java +++ b/src/main/java/org/qortal/transaction/MultiPaymentTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.List; -import java.util.stream.Collectors; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.PaymentData; @@ -12,6 +9,9 @@ import org.qortal.payment.Payment; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.List; +import java.util.stream.Collectors; + public class MultiPaymentTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/PaymentTransaction.java b/src/main/java/org/qortal/transaction/PaymentTransaction.java index 4869db76..518939c2 100644 --- a/src/main/java/org/qortal/transaction/PaymentTransaction.java +++ b/src/main/java/org/qortal/transaction/PaymentTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.PaymentData; @@ -12,6 +9,9 @@ import org.qortal.payment.Payment; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class PaymentTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/PresenceTransaction.java b/src/main/java/org/qortal/transaction/PresenceTransaction.java index 56a9f633..9ac31b58 100644 --- a/src/main/java/org/qortal/transaction/PresenceTransaction.java +++ b/src/main/java/org/qortal/transaction/PresenceTransaction.java @@ -1,14 +1,6 @@ package org.qortal.transaction; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - +import com.google.common.primitives.Longs; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; @@ -31,7 +23,14 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.ByteArray; -import com.google.common.primitives.Longs; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; public class PresenceTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/PublicizeTransaction.java b/src/main/java/org/qortal/transaction/PublicizeTransaction.java index 44f93e6e..161eb11a 100644 --- a/src/main/java/org/qortal/transaction/PublicizeTransaction.java +++ b/src/main/java/org/qortal/transaction/PublicizeTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; @@ -19,6 +16,9 @@ import org.qortal.transform.transaction.PublicizeTransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.NTP; +import java.util.Collections; +import java.util.List; + public class PublicizeTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/RegisterNameTransaction.java b/src/main/java/org/qortal/transaction/RegisterNameTransaction.java index 19f1da5a..79976199 100644 --- a/src/main/java/org/qortal/transaction/RegisterNameTransaction.java +++ b/src/main/java/org/qortal/transaction/RegisterNameTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.block.BlockChain; @@ -15,7 +13,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class RegisterNameTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/RemoveGroupAdminTransaction.java b/src/main/java/org/qortal/transaction/RemoveGroupAdminTransaction.java index 043b5423..77dd8160 100644 --- a/src/main/java/org/qortal/transaction/RemoveGroupAdminTransaction.java +++ b/src/main/java/org/qortal/transaction/RemoveGroupAdminTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -14,6 +10,10 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + public class RemoveGroupAdminTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/RewardShareTransaction.java b/src/main/java/org/qortal/transaction/RewardShareTransaction.java index d4d2434c..ab66dec6 100644 --- a/src/main/java/org/qortal/transaction/RewardShareTransaction.java +++ b/src/main/java/org/qortal/transaction/RewardShareTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; @@ -16,6 +12,10 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.transform.Transformer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + public class RewardShareTransaction extends Transaction { public static final int MAX_SHARE = 100 * 100; // unscaled diff --git a/src/main/java/org/qortal/transaction/SellNameTransaction.java b/src/main/java/org/qortal/transaction/SellNameTransaction.java index c2ab2eb9..b2fd1484 100644 --- a/src/main/java/org/qortal/transaction/SellNameTransaction.java +++ b/src/main/java/org/qortal/transaction/SellNameTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; @@ -14,7 +12,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class SellNameTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/SetGroupTransaction.java b/src/main/java/org/qortal/transaction/SetGroupTransaction.java index 48248b69..dcd2363f 100644 --- a/src/main/java/org/qortal/transaction/SetGroupTransaction.java +++ b/src/main/java/org/qortal/transaction/SetGroupTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.data.transaction.SetGroupTransactionData; @@ -11,6 +8,9 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class SetGroupTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/Transaction.java b/src/main/java/org/qortal/transaction/Transaction.java index e0ed1f82..61b78ade 100644 --- a/src/main/java/org/qortal/transaction/Transaction.java +++ b/src/main/java/org/qortal/transaction/Transaction.java @@ -1,10 +1,5 @@ package org.qortal.transaction; -import java.math.BigInteger; -import java.util.*; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Predicate; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; @@ -30,11 +25,15 @@ import org.qortal.transform.Transformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.NTP; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Predicate; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; public abstract class Transaction { diff --git a/src/main/java/org/qortal/transaction/TransferAssetTransaction.java b/src/main/java/org/qortal/transaction/TransferAssetTransaction.java index 79d485a5..50c6f24a 100644 --- a/src/main/java/org/qortal/transaction/TransferAssetTransaction.java +++ b/src/main/java/org/qortal/transaction/TransferAssetTransaction.java @@ -1,8 +1,5 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - import org.qortal.account.Account; import org.qortal.data.PaymentData; import org.qortal.data.transaction.TransactionData; @@ -11,6 +8,9 @@ import org.qortal.payment.Payment; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Collections; +import java.util.List; + public class TransferAssetTransaction extends Transaction { // Properties diff --git a/src/main/java/org/qortal/transaction/TransferPrivsTransaction.java b/src/main/java/org/qortal/transaction/TransferPrivsTransaction.java index 97e67160..de3038d8 100644 --- a/src/main/java/org/qortal/transaction/TransferPrivsTransaction.java +++ b/src/main/java/org/qortal/transaction/TransferPrivsTransaction.java @@ -1,9 +1,5 @@ package org.qortal.transaction; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; @@ -17,6 +13,10 @@ import org.qortal.repository.AccountRepository; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + public class TransferPrivsTransaction extends Transaction { private static final Logger LOGGER = LogManager.getLogger(TransferPrivsTransaction.class); diff --git a/src/main/java/org/qortal/transaction/UpdateAssetTransaction.java b/src/main/java/org/qortal/transaction/UpdateAssetTransaction.java index 16e5641d..45d2c832 100644 --- a/src/main/java/org/qortal/transaction/UpdateAssetTransaction.java +++ b/src/main/java/org/qortal/transaction/UpdateAssetTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; @@ -13,7 +11,8 @@ import org.qortal.data.transaction.UpdateAssetTransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class UpdateAssetTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/UpdateGroupTransaction.java b/src/main/java/org/qortal/transaction/UpdateGroupTransaction.java index 27580430..a2546c69 100644 --- a/src/main/java/org/qortal/transaction/UpdateGroupTransaction.java +++ b/src/main/java/org/qortal/transaction/UpdateGroupTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.crypto.Crypto; @@ -13,7 +11,8 @@ import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class UpdateGroupTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/UpdateNameTransaction.java b/src/main/java/org/qortal/transaction/UpdateNameTransaction.java index 8d578c85..8d42207c 100644 --- a/src/main/java/org/qortal/transaction/UpdateNameTransaction.java +++ b/src/main/java/org/qortal/transaction/UpdateNameTransaction.java @@ -1,9 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - +import com.google.common.base.Utf8; import org.qortal.account.Account; import org.qortal.asset.Asset; import org.qortal.controller.repository.NamesDatabaseIntegrityCheck; @@ -16,7 +13,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Unicode; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; +import java.util.Objects; public class UpdateNameTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transaction/VoteOnPollTransaction.java b/src/main/java/org/qortal/transaction/VoteOnPollTransaction.java index 89eec184..4335ec76 100644 --- a/src/main/java/org/qortal/transaction/VoteOnPollTransaction.java +++ b/src/main/java/org/qortal/transaction/VoteOnPollTransaction.java @@ -1,8 +1,6 @@ package org.qortal.transaction; -import java.util.Collections; -import java.util.List; - +import com.google.common.base.Utf8; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; @@ -18,7 +16,8 @@ import org.qortal.repository.VotingRepository; import org.qortal.utils.Unicode; import org.qortal.voting.Poll; -import com.google.common.base.Utf8; +import java.util.Collections; +import java.util.List; public class VoteOnPollTransaction extends Transaction { diff --git a/src/main/java/org/qortal/transform/PaymentTransformer.java b/src/main/java/org/qortal/transform/PaymentTransformer.java index 56aa7ad1..34f0b030 100644 --- a/src/main/java/org/qortal/transform/PaymentTransformer.java +++ b/src/main/java/org/qortal/transform/PaymentTransformer.java @@ -1,14 +1,13 @@ package org.qortal.transform; +import com.google.common.primitives.Longs; +import org.qortal.data.PaymentData; +import org.qortal.utils.Serialization; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import org.qortal.data.PaymentData; -import org.qortal.utils.Serialization; - -import com.google.common.primitives.Longs; - public class PaymentTransformer extends Transformer { // Property lengths diff --git a/src/main/java/org/qortal/transform/block/BlockTransformer.java b/src/main/java/org/qortal/transform/block/BlockTransformer.java index 15445327..fee585ca 100644 --- a/src/main/java/org/qortal/transform/block/BlockTransformer.java +++ b/src/main/java/org/qortal/transform/block/BlockTransformer.java @@ -1,13 +1,8 @@ package org.qortal.transform.block; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import io.druid.extendedset.intset.ConciseSet; import org.qortal.block.Block; import org.qortal.block.BlockChain; import org.qortal.crypto.Crypto; @@ -23,10 +18,13 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; - -import io.druid.extendedset.intset.ConciseSet; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class BlockTransformer extends Transformer { diff --git a/src/main/java/org/qortal/transform/transaction/AccountFlagsTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/AccountFlagsTransactionTransformer.java index 7fe1cb61..966cdb25 100644 --- a/src/main/java/org/qortal/transform/transaction/AccountFlagsTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/AccountFlagsTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.AccountFlagsTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class AccountFlagsTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/AccountLevelTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/AccountLevelTransactionTransformer.java index 7572ebf7..ae9f15a5 100644 --- a/src/main/java/org/qortal/transform/transaction/AccountLevelTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/AccountLevelTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.AccountLevelTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class AccountLevelTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/AddGroupAdminTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/AddGroupAdminTransactionTransformer.java index 62e011af..5b4ece3e 100644 --- a/src/main/java/org/qortal/transform/transaction/AddGroupAdminTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/AddGroupAdminTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.AddGroupAdminTransactionData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class AddGroupAdminTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java index 1ae80e1f..8b47b5b8 100644 --- a/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java @@ -1,18 +1,14 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.crypto.Crypto; import org.qortal.data.PaymentData; import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.data.transaction.ArbitraryTransactionData.DataType; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; -import org.qortal.data.transaction.ArbitraryTransactionData.DataType; import org.qortal.naming.Name; import org.qortal.transaction.ArbitraryTransaction; import org.qortal.transaction.Transaction; @@ -21,8 +17,11 @@ import org.qortal.transform.PaymentTransformer; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; public class ArbitraryTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/AtTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/AtTransactionTransformer.java index bb1381b2..a441a693 100644 --- a/src/main/java/org/qortal/transform/transaction/AtTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/AtTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.account.NullAccount; import org.qortal.data.transaction.ATTransactionData; import org.qortal.data.transaction.BaseTransactionData; @@ -13,8 +11,9 @@ import org.qortal.transaction.Transaction; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class AtTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/BuyNameTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/BuyNameTransactionTransformer.java index 2a00b615..8dff8a25 100644 --- a/src/main/java/org/qortal/transform/transaction/BuyNameTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/BuyNameTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.BuyNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class BuyNameTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CancelAssetOrderTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CancelAssetOrderTransactionTransformer.java index d65a3f37..b38977e9 100644 --- a/src/main/java/org/qortal/transform/transaction/CancelAssetOrderTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CancelAssetOrderTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelAssetOrderTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class CancelAssetOrderTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CancelGroupBanTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CancelGroupBanTransactionTransformer.java index 1444c890..2dcbd7cb 100644 --- a/src/main/java/org/qortal/transform/transaction/CancelGroupBanTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CancelGroupBanTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelGroupBanTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class CancelGroupBanTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CancelGroupInviteTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CancelGroupInviteTransactionTransformer.java index 7cacbaa0..a8a01b54 100644 --- a/src/main/java/org/qortal/transform/transaction/CancelGroupInviteTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CancelGroupInviteTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelGroupInviteTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class CancelGroupInviteTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CancelSellNameTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CancelSellNameTransactionTransformer.java index c91a78a4..1dc13d55 100644 --- a/src/main/java/org/qortal/transform/transaction/CancelSellNameTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CancelSellNameTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CancelSellNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class CancelSellNameTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/ChatTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/ChatTransactionTransformer.java index b966ed2b..0730dad4 100644 --- a/src/main/java/org/qortal/transform/transaction/ChatTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/ChatTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.block.BlockChain; import org.qortal.crypto.Crypto; import org.qortal.data.transaction.BaseTransactionData; @@ -14,8 +12,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class ChatTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CreateAssetOrderTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CreateAssetOrderTransactionTransformer.java index 29363332..dc711594 100644 --- a/src/main/java/org/qortal/transform/transaction/CreateAssetOrderTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CreateAssetOrderTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CreateAssetOrderTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class CreateAssetOrderTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CreateGroupTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CreateGroupTransactionTransformer.java index 29afba9d..0edc89b8 100644 --- a/src/main/java/org/qortal/transform/transaction/CreateGroupTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CreateGroupTransactionTransformer.java @@ -1,9 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CreateGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -13,9 +12,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class CreateGroupTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/CreatePollTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/CreatePollTransactionTransformer.java index 442693df..0a8a1712 100644 --- a/src/main/java/org/qortal/transform/transaction/CreatePollTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/CreatePollTransactionTransformer.java @@ -1,11 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.CreatePollTransactionData; import org.qortal.data.transaction.TransactionData; @@ -15,9 +12,11 @@ import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; import org.qortal.voting.Poll; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; public class CreatePollTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/DeployAtTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/DeployAtTransactionTransformer.java index 4a201338..8b14d74b 100644 --- a/src/main/java/org/qortal/transform/transaction/DeployAtTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/DeployAtTransactionTransformer.java @@ -1,9 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.DeployAtTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,9 +11,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class DeployAtTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/GenesisTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/GenesisTransactionTransformer.java index 41348b79..99ded558 100644 --- a/src/main/java/org/qortal/transform/transaction/GenesisTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/GenesisTransactionTransformer.java @@ -1,16 +1,15 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.GenesisTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class GenesisTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/GroupApprovalTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/GroupApprovalTransactionTransformer.java index 227e291a..cee62bc1 100644 --- a/src/main/java/org/qortal/transform/transaction/GroupApprovalTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/GroupApprovalTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupApprovalTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class GroupApprovalTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/GroupBanTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/GroupBanTransactionTransformer.java index 9454390b..8ff681a6 100644 --- a/src/main/java/org/qortal/transform/transaction/GroupBanTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/GroupBanTransactionTransformer.java @@ -1,9 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupBanTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,9 +11,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class GroupBanTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/GroupInviteTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/GroupInviteTransactionTransformer.java index 93d2c895..bb8961a5 100644 --- a/src/main/java/org/qortal/transform/transaction/GroupInviteTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/GroupInviteTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupInviteTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class GroupInviteTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/GroupKickTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/GroupKickTransactionTransformer.java index 0e5ac2f2..3a6fe68c 100644 --- a/src/main/java/org/qortal/transform/transaction/GroupKickTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/GroupKickTransactionTransformer.java @@ -1,9 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.GroupKickTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,9 +11,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class GroupKickTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java index 59cbd6bc..8c1f7d02 100644 --- a/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.asset.Asset; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.IssueAssetTransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class IssueAssetTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/JoinGroupTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/JoinGroupTransactionTransformer.java index a4f33e48..a20acf53 100644 --- a/src/main/java/org/qortal/transform/transaction/JoinGroupTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/JoinGroupTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.JoinGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class JoinGroupTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/LeaveGroupTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/LeaveGroupTransactionTransformer.java index ee42ffeb..d1d6152e 100644 --- a/src/main/java/org/qortal/transform/transaction/LeaveGroupTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/LeaveGroupTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.LeaveGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class LeaveGroupTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/MessageTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/MessageTransactionTransformer.java index dccd7ba9..dcbe8a7f 100644 --- a/src/main/java/org/qortal/transform/transaction/MessageTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/MessageTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.MessageTransactionData; import org.qortal.data.transaction.TransactionData; @@ -13,8 +11,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class MessageTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/MultiPaymentTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/MultiPaymentTransactionTransformer.java index 1f77243f..ff969b02 100644 --- a/src/main/java/org/qortal/transform/transaction/MultiPaymentTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/MultiPaymentTransactionTransformer.java @@ -1,11 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.PaymentData; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.MultiPaymentTransactionData; @@ -15,8 +11,11 @@ import org.qortal.transform.PaymentTransformer; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; public class MultiPaymentTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/PaymentTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/PaymentTransactionTransformer.java index af194470..d9b5488c 100644 --- a/src/main/java/org/qortal/transform/transaction/PaymentTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/PaymentTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.PaymentTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class PaymentTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/PresenceTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/PresenceTransactionTransformer.java index bf69d102..f9fae7a7 100644 --- a/src/main/java/org/qortal/transform/transaction/PresenceTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/PresenceTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.PresenceTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class PresenceTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/PublicizeTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/PublicizeTransactionTransformer.java index 6413db24..e778169b 100644 --- a/src/main/java/org/qortal/transform/transaction/PublicizeTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/PublicizeTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.PublicizeTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class PublicizeTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/RegisterNameTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/RegisterNameTransactionTransformer.java index 54f86f35..29625b9d 100644 --- a/src/main/java/org/qortal/transform/transaction/RegisterNameTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/RegisterNameTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.RegisterNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class RegisterNameTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/RemoveGroupAdminTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/RemoveGroupAdminTransactionTransformer.java index 58a8d07d..635623da 100644 --- a/src/main/java/org/qortal/transform/transaction/RemoveGroupAdminTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/RemoveGroupAdminTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.RemoveGroupAdminTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class RemoveGroupAdminTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/RewardShareTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/RewardShareTransactionTransformer.java index 3611e07e..dfc0b90c 100644 --- a/src/main/java/org/qortal/transform/transaction/RewardShareTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/RewardShareTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.RewardShareTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class RewardShareTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/SellNameTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/SellNameTransactionTransformer.java index 3fded96e..b0ba3f3e 100644 --- a/src/main/java/org/qortal/transform/transaction/SellNameTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/SellNameTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.SellNameTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class SellNameTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/SetGroupTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/SetGroupTransactionTransformer.java index 586e084a..62ea78a3 100644 --- a/src/main/java/org/qortal/transform/transaction/SetGroupTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/SetGroupTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.SetGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,8 +9,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class SetGroupTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/TransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/TransactionTransformer.java index ae029eaf..293f89fd 100644 --- a/src/main/java/org/qortal/transform/transaction/TransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/TransactionTransformer.java @@ -1,5 +1,20 @@ package org.qortal.transform.transaction; +import com.google.common.hash.HashCode; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.account.PrivateKeyAccount; +import org.qortal.data.transaction.TransactionData; +import org.qortal.transaction.Transaction; +import org.qortal.transaction.Transaction.TransactionType; +import org.qortal.transform.TransformationException; +import org.qortal.transform.Transformer; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Field; @@ -11,23 +26,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.qortal.account.PrivateKeyAccount; -import org.qortal.data.transaction.TransactionData; -import org.qortal.transaction.Transaction; -import org.qortal.transaction.Transaction.TransactionType; -import org.qortal.transform.TransformationException; -import org.qortal.transform.Transformer; - -import com.google.common.hash.HashCode; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; - public abstract class TransactionTransformer extends Transformer { private static final Logger LOGGER = LogManager.getLogger(TransactionTransformer.class); diff --git a/src/main/java/org/qortal/transform/transaction/TransferAssetTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/TransferAssetTransactionTransformer.java index 1f124289..0b408ca6 100644 --- a/src/main/java/org/qortal/transform/transaction/TransferAssetTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/TransferAssetTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.TransferAssetTransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class TransferAssetTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/TransferPrivsTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/TransferPrivsTransactionTransformer.java index 59c3dd2a..7663f36f 100644 --- a/src/main/java/org/qortal/transform/transaction/TransferPrivsTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/TransferPrivsTransactionTransformer.java @@ -1,9 +1,6 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.TransferPrivsTransactionData; @@ -11,7 +8,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class TransferPrivsTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/UpdateAssetTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/UpdateAssetTransactionTransformer.java index ba27d939..829545f4 100644 --- a/src/main/java/org/qortal/transform/transaction/UpdateAssetTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/UpdateAssetTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.asset.Asset; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class UpdateAssetTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/UpdateGroupTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/UpdateGroupTransactionTransformer.java index 673694c3..67c20f74 100644 --- a/src/main/java/org/qortal/transform/transaction/UpdateGroupTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/UpdateGroupTransactionTransformer.java @@ -1,9 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.UpdateGroupTransactionData; @@ -13,9 +12,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class UpdateGroupTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/UpdateNameTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/UpdateNameTransactionTransformer.java index 6e3aa06b..8a5152d7 100644 --- a/src/main/java/org/qortal/transform/transaction/UpdateNameTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/UpdateNameTransactionTransformer.java @@ -1,9 +1,7 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.UpdateNameTransactionData; @@ -12,8 +10,9 @@ import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; -import com.google.common.base.Utf8; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class UpdateNameTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/transform/transaction/VoteOnPollTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/VoteOnPollTransactionTransformer.java index 10045e3f..7315b775 100644 --- a/src/main/java/org/qortal/transform/transaction/VoteOnPollTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/VoteOnPollTransactionTransformer.java @@ -1,9 +1,8 @@ package org.qortal.transform.transaction; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - +import com.google.common.base.Utf8; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.VoteOnPollTransactionData; @@ -12,9 +11,9 @@ import org.qortal.transform.TransformationException; import org.qortal.utils.Serialization; import org.qortal.voting.Poll; -import com.google.common.base.Utf8; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; public class VoteOnPollTransactionTransformer extends TransactionTransformer { diff --git a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java index 65f3436c..2d3a2358 100644 --- a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java +++ b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java @@ -3,9 +3,11 @@ package org.qortal.utils; import org.apache.commons.lang3.ArrayUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.qortal.arbitrary.*; +import org.qortal.arbitrary.ArbitraryDataFile; +import org.qortal.arbitrary.ArbitraryDataFileChunk; +import org.qortal.arbitrary.ArbitraryDataReader; +import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.misc.Service; -import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; diff --git a/src/main/java/org/qortal/utils/BlockArchiveUtils.java b/src/main/java/org/qortal/utils/BlockArchiveUtils.java index f9ca0d0d..33482fc6 100644 --- a/src/main/java/org/qortal/utils/BlockArchiveUtils.java +++ b/src/main/java/org/qortal/utils/BlockArchiveUtils.java @@ -3,8 +3,6 @@ package org.qortal.utils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.data.at.ATStateData; -import org.qortal.data.block.BlockData; -import org.qortal.data.transaction.TransactionData; import org.qortal.repository.BlockArchiveReader; import org.qortal.repository.DataException; import org.qortal.repository.Repository; diff --git a/src/main/java/org/qortal/utils/ExecuteProduceConsume.java b/src/main/java/org/qortal/utils/ExecuteProduceConsume.java index 223d0e93..58e1af05 100644 --- a/src/main/java/org/qortal/utils/ExecuteProduceConsume.java +++ b/src/main/java/org/qortal/utils/ExecuteProduceConsume.java @@ -1,16 +1,15 @@ package org.qortal.utils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - public abstract class ExecuteProduceConsume implements Runnable { @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/qortal/utils/LoggingUtils.java b/src/main/java/org/qortal/utils/LoggingUtils.java index eeb2a7c0..b3b272b0 100644 --- a/src/main/java/org/qortal/utils/LoggingUtils.java +++ b/src/main/java/org/qortal/utils/LoggingUtils.java @@ -1,7 +1,6 @@ package org.qortal.utils; import org.apache.commons.io.FileUtils; -import org.apache.logging.log4j.LogManager; import java.io.IOException; import java.nio.file.Files; diff --git a/src/main/java/org/qortal/utils/NTP.java b/src/main/java/org/qortal/utils/NTP.java index 779db41b..e5c0d35f 100644 --- a/src/main/java/org/qortal/utils/NTP.java +++ b/src/main/java/org/qortal/utils/NTP.java @@ -1,18 +1,5 @@ package org.qortal.utils; -import java.io.IOException; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.CompletionService; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; - import org.apache.commons.net.ntp.NTPUDPClient; import org.apache.commons.net.ntp.NtpV3Packet; import org.apache.commons.net.ntp.TimeInfo; @@ -20,6 +7,15 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.*; +import java.util.stream.Collectors; + public class NTP implements Runnable { private static final Logger LOGGER = LogManager.getLogger(NTP.class); diff --git a/src/main/java/org/qortal/utils/Serialization.java b/src/main/java/org/qortal/utils/Serialization.java index 26888477..a95698c6 100644 --- a/src/main/java/org/qortal/utils/Serialization.java +++ b/src/main/java/org/qortal/utils/Serialization.java @@ -1,5 +1,9 @@ package org.qortal.utils; +import com.google.common.primitives.Ints; +import org.qortal.transform.TransformationException; +import org.qortal.transform.Transformer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -9,11 +13,6 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import org.qortal.transform.TransformationException; -import org.qortal.transform.Transformer; - -import com.google.common.primitives.Ints; - public class Serialization { /** diff --git a/src/main/java/org/qortal/utils/SevenZ.java b/src/main/java/org/qortal/utils/SevenZ.java index 5126b292..1432dc0d 100644 --- a/src/main/java/org/qortal/utils/SevenZ.java +++ b/src/main/java/org/qortal/utils/SevenZ.java @@ -11,7 +11,10 @@ import org.apache.commons.compress.archivers.sevenz.SevenZFile; import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; import org.qortal.gui.SplashFrame; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; public class SevenZ { diff --git a/src/main/java/org/qortal/utils/StringLongMapXmlAdapter.java b/src/main/java/org/qortal/utils/StringLongMapXmlAdapter.java index 00625462..2ddf5823 100644 --- a/src/main/java/org/qortal/utils/StringLongMapXmlAdapter.java +++ b/src/main/java/org/qortal/utils/StringLongMapXmlAdapter.java @@ -1,17 +1,16 @@ package org.qortal.utils; +import org.eclipse.persistence.oxm.annotations.XmlVariableNode; + +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.XmlAdapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import javax.xml.bind.annotation.XmlTransient; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.XmlAdapter; - -import org.eclipse.persistence.oxm.annotations.XmlVariableNode; - public class StringLongMapXmlAdapter extends XmlAdapter> { public static class StringLongMap { diff --git a/src/main/java/org/qortal/utils/URLViewer.java b/src/main/java/org/qortal/utils/URLViewer.java index e03e6141..7d512bd2 100644 --- a/src/main/java/org/qortal/utils/URLViewer.java +++ b/src/main/java/org/qortal/utils/URLViewer.java @@ -1,13 +1,13 @@ package org.qortal.utils; -import java.awt.Desktop; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.awt.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + public class URLViewer { private static final Logger LOGGER = LogManager.getLogger(URLViewer.class); diff --git a/src/main/java/org/qortal/utils/Unicode.java b/src/main/java/org/qortal/utils/Unicode.java index c9484d82..c3e282ce 100644 --- a/src/main/java/org/qortal/utils/Unicode.java +++ b/src/main/java/org/qortal/utils/Unicode.java @@ -1,28 +1,16 @@ package org.qortal.utils; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UncheckedIOException; -import java.text.Normalizer; -import java.text.Normalizer.Form; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.TreeMap; - import com.google.common.base.CharMatcher; - import com.ibm.icu.text.CaseMap; import com.ibm.icu.text.Normalizer2; import com.ibm.icu.text.UnicodeSet; import net.codebox.homoglyph.HomoglyphBuilder; +import java.io.*; +import java.text.Normalizer; +import java.text.Normalizer.Form; +import java.util.*; + public abstract class Unicode { public static final String NO_BREAK_SPACE = "\u00a0"; diff --git a/src/test/java/org/qortal/test/AccountBalanceTests.java b/src/test/java/org/qortal/test/AccountBalanceTests.java index cd2822ac..13884b2d 100644 --- a/src/test/java/org/qortal/test/AccountBalanceTests.java +++ b/src/test/java/org/qortal/test/AccountBalanceTests.java @@ -1,14 +1,5 @@ package org.qortal.test; -import static org.junit.Assert.*; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,14 +8,24 @@ import org.qortal.account.PublicKeyAccount; import org.qortal.asset.Asset; import org.qortal.data.account.AccountBalanceData; import org.qortal.data.account.AccountData; +import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; -import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.test.common.BlockUtils; import org.qortal.test.common.Common; import org.qortal.test.common.TestAccount; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class AccountBalanceTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/AccountRefCacheTests.java b/src/test/java/org/qortal/test/AccountRefCacheTests.java index c7305dd9..ad0cfa7b 100644 --- a/src/test/java/org/qortal/test/AccountRefCacheTests.java +++ b/src/test/java/org/qortal/test/AccountRefCacheTests.java @@ -1,10 +1,5 @@ package org.qortal.test; -import static org.junit.Assert.*; - -import java.util.Arrays; -import java.util.Random; - import org.junit.Before; import org.junit.Test; import org.qortal.account.Account; @@ -21,6 +16,11 @@ import org.qortal.test.common.TestAccount; import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; +import java.util.Arrays; +import java.util.Random; + +import static org.junit.Assert.*; + public class AccountRefCacheTests extends Common { private static final Random RANDOM = new Random(); diff --git a/src/test/java/org/qortal/test/AmountsTests.java b/src/test/java/org/qortal/test/AmountsTests.java index 90159466..82a2d7ad 100644 --- a/src/test/java/org/qortal/test/AmountsTests.java +++ b/src/test/java/org/qortal/test/AmountsTests.java @@ -1,10 +1,10 @@ package org.qortal.test; -import static org.junit.Assert.*; - import org.junit.Test; import org.qortal.utils.Amounts; +import static org.junit.Assert.assertEquals; + public class AmountsTests { @Test diff --git a/src/test/java/org/qortal/test/BlockTests.java b/src/test/java/org/qortal/test/BlockTests.java index 53b216ec..e0e2244d 100644 --- a/src/test/java/org/qortal/test/BlockTests.java +++ b/src/test/java/org/qortal/test/BlockTests.java @@ -1,18 +1,11 @@ package org.qortal.test; -import java.util.Arrays; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Collectors; - import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.block.Block; import org.qortal.block.GenesisBlock; -import org.qortal.data.at.ATStateData; import org.qortal.data.block.BlockData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; @@ -28,7 +21,12 @@ import org.qortal.transform.block.BlockTransformation; import org.qortal.transform.block.BlockTransformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; -import org.qortal.utils.Triple; + +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; import static org.junit.Assert.*; diff --git a/src/test/java/org/qortal/test/ByteArrayTests.java b/src/test/java/org/qortal/test/ByteArrayTests.java index f954a367..4beb2858 100644 --- a/src/test/java/org/qortal/test/ByteArrayTests.java +++ b/src/test/java/org/qortal/test/ByteArrayTests.java @@ -1,19 +1,13 @@ package org.qortal.test; -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.TreeMap; - import org.junit.Before; import org.junit.Test; import org.qortal.utils.ByteArray; +import java.util.*; + +import static org.junit.Assert.*; + public class ByteArrayTests { private static List testValues; diff --git a/src/test/java/org/qortal/test/ChainWeightTests.java b/src/test/java/org/qortal/test/ChainWeightTests.java index e53c4c8e..d2a147b7 100644 --- a/src/test/java/org/qortal/test/ChainWeightTests.java +++ b/src/test/java/org/qortal/test/ChainWeightTests.java @@ -1,14 +1,8 @@ package org.qortal.test; -import static org.junit.Assert.*; - -import java.math.BigInteger; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; import org.qortal.account.Account; import org.qortal.block.Block; import org.qortal.block.BlockChain; @@ -21,9 +15,15 @@ import org.qortal.test.common.TestAccount; import org.qortal.transform.Transformer; import org.qortal.transform.block.BlockTransformer; import org.qortal.utils.NTP; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; + +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.junit.Assert.*; public class ChainWeightTests extends Common { diff --git a/src/test/java/org/qortal/test/CryptoTests.java b/src/test/java/org/qortal/test/CryptoTests.java index 2cc73182..75422ee7 100644 --- a/src/test/java/org/qortal/test/CryptoTests.java +++ b/src/test/java/org/qortal/test/CryptoTests.java @@ -1,16 +1,24 @@ package org.qortal.test; +import com.google.common.hash.HashCode; +import org.bouncycastle.crypto.agreement.X25519Agreement; +import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; +import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; +import org.bouncycastle.crypto.params.X25519PublicKeyParameters; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.block.BlockChain; import org.qortal.crypto.AES; -import org.qortal.crypto.Qortal25519Extras; import org.qortal.crypto.Crypto; +import org.qortal.crypto.Qortal25519Extras; import org.qortal.test.common.Common; import org.qortal.utils.Base58; -import static org.junit.Assert.*; - +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -25,18 +33,7 @@ import java.security.SecureRandom; import java.util.Arrays; import java.util.Random; -import org.bouncycastle.crypto.agreement.X25519Agreement; -import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; -import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; -import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; -import org.bouncycastle.crypto.params.X25519PublicKeyParameters; - -import com.google.common.hash.HashCode; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; +import static org.junit.Assert.*; public class CryptoTests extends Common { diff --git a/src/test/java/org/qortal/test/EPCTests.java b/src/test/java/org/qortal/test/EPCTests.java index 1a41b75d..b90be16d 100644 --- a/src/test/java/org/qortal/test/EPCTests.java +++ b/src/test/java/org/qortal/test/EPCTests.java @@ -1,5 +1,9 @@ package org.qortal.test; +import org.junit.Test; +import org.qortal.utils.ExecuteProduceConsume; +import org.qortal.utils.ExecuteProduceConsume.StatsSnapshot; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -9,10 +13,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.junit.Test; -import org.qortal.utils.ExecuteProduceConsume; -import org.qortal.utils.ExecuteProduceConsume.StatsSnapshot; - import static org.junit.Assert.fail; public class EPCTests { diff --git a/src/test/java/org/qortal/test/GuiTests.java b/src/test/java/org/qortal/test/GuiTests.java index 0754d33b..016518f3 100644 --- a/src/test/java/org/qortal/test/GuiTests.java +++ b/src/test/java/org/qortal/test/GuiTests.java @@ -1,12 +1,12 @@ package org.qortal.test; -import java.awt.TrayIcon.MessageType; - import org.junit.Ignore; import org.junit.Test; import org.qortal.gui.SplashFrame; import org.qortal.gui.SysTray; +import java.awt.TrayIcon.MessageType; + @Ignore public class GuiTests { diff --git a/src/test/java/org/qortal/test/MemoryPoWTests.java b/src/test/java/org/qortal/test/MemoryPoWTests.java index 3b0045e5..f642c781 100644 --- a/src/test/java/org/qortal/test/MemoryPoWTests.java +++ b/src/test/java/org/qortal/test/MemoryPoWTests.java @@ -6,10 +6,10 @@ import org.qortal.crypto.MemoryPoW; import org.qortal.repository.DataException; import org.qortal.test.common.Common; -import static org.junit.Assert.*; - import java.util.Random; +import static org.junit.Assert.*; + @Ignore public class MemoryPoWTests { diff --git a/src/test/java/org/qortal/test/MessageTests.java b/src/test/java/org/qortal/test/MessageTests.java index c76c715e..216f61bf 100644 --- a/src/test/java/org/qortal/test/MessageTests.java +++ b/src/test/java/org/qortal/test/MessageTests.java @@ -27,11 +27,11 @@ import org.qortal.transform.transaction.MessageTransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.NTP; -import static org.junit.Assert.*; - import java.util.List; import java.util.Random; +import static org.junit.Assert.*; + public class MessageTests extends Common { private static final int version = 4; diff --git a/src/test/java/org/qortal/test/RepositoryTests.java b/src/test/java/org/qortal/test/RepositoryTests.java index 30cbaea5..0d07be4b 100644 --- a/src/test/java/org/qortal/test/RepositoryTests.java +++ b/src/test/java/org/qortal/test/RepositoryTests.java @@ -1,5 +1,7 @@ package org.qortal.test; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.junit.Before; import org.junit.Test; import org.qortal.account.Account; @@ -17,8 +19,6 @@ import org.qortal.repository.hsqldb.HSQLDBRepository; import org.qortal.test.common.BlockUtils; import org.qortal.test.common.Common; -import static org.junit.Assert.*; - import java.lang.reflect.Field; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,8 +29,7 @@ import java.util.List; import java.util.Random; import java.util.concurrent.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import static org.junit.Assert.*; public class RepositoryTests extends Common { diff --git a/src/test/java/org/qortal/test/SchnorrTests.java b/src/test/java/org/qortal/test/SchnorrTests.java index e0d1f1c9..666e4860 100644 --- a/src/test/java/org/qortal/test/SchnorrTests.java +++ b/src/test/java/org/qortal/test/SchnorrTests.java @@ -12,9 +12,8 @@ import org.qortal.test.common.AccountUtils; import org.qortal.transform.Transformer; import java.math.BigInteger; -import java.security.SecureRandom; import java.security.Security; -import java.util.*; +import java.util.List; import java.util.stream.Collectors; import static org.junit.Assert.*; diff --git a/src/test/java/org/qortal/test/SelfSponsorshipAlgoV1Tests.java b/src/test/java/org/qortal/test/SelfSponsorshipAlgoV1Tests.java index 397a1bbe..5c038de2 100644 --- a/src/test/java/org/qortal/test/SelfSponsorshipAlgoV1Tests.java +++ b/src/test/java/org/qortal/test/SelfSponsorshipAlgoV1Tests.java @@ -15,17 +15,23 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.settings.Settings; -import org.qortal.test.common.*; +import org.qortal.test.common.AccountUtils; +import org.qortal.test.common.BlockUtils; +import org.qortal.test.common.Common; +import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.Transaction; import org.qortal.transaction.TransferPrivsTransaction; import org.qortal.utils.NTP; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; import static org.junit.Assert.*; import static org.qortal.test.common.AccountUtils.fee; -import static org.qortal.transaction.Transaction.ValidationResult.*; +import static org.qortal.transaction.Transaction.ValidationResult.ACCOUNT_NOT_TRANSFERABLE; +import static org.qortal.transaction.Transaction.ValidationResult.OK; public class SelfSponsorshipAlgoV1Tests extends Common { diff --git a/src/test/java/org/qortal/test/TransactionSearchTests.java b/src/test/java/org/qortal/test/TransactionSearchTests.java index 8cc75646..ba7b4781 100644 --- a/src/test/java/org/qortal/test/TransactionSearchTests.java +++ b/src/test/java/org/qortal/test/TransactionSearchTests.java @@ -1,9 +1,5 @@ package org.qortal.test; -import static org.junit.Assert.*; - -import java.util.List; - import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; @@ -15,6 +11,10 @@ import org.qortal.test.common.BlockUtils; import org.qortal.test.common.Common; import org.qortal.transaction.Transaction.TransactionType; +import java.util.List; + +import static org.junit.Assert.assertEquals; + public class TransactionSearchTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/TransferPrivsTests.java b/src/test/java/org/qortal/test/TransferPrivsTests.java index 3ed3ad16..86a0e743 100644 --- a/src/test/java/org/qortal/test/TransferPrivsTests.java +++ b/src/test/java/org/qortal/test/TransferPrivsTests.java @@ -17,20 +17,16 @@ import org.qortal.data.transaction.TransferPrivsTransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; -import org.qortal.test.common.AccountUtils; -import org.qortal.test.common.BlockUtils; -import org.qortal.test.common.Common; -import org.qortal.test.common.TestAccount; -import org.qortal.test.common.TransactionUtils; +import org.qortal.test.common.*; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transform.Transformer; import org.qortal.utils.Amounts; -import static org.junit.Assert.*; - import java.util.List; import java.util.Random; +import static org.junit.Assert.*; + @Ignore(value = "Doesn't work, to be fixed later") public class TransferPrivsTests extends Common { diff --git a/src/test/java/org/qortal/test/UnicodeTests.java b/src/test/java/org/qortal/test/UnicodeTests.java index f84b13d5..724154f4 100644 --- a/src/test/java/org/qortal/test/UnicodeTests.java +++ b/src/test/java/org/qortal/test/UnicodeTests.java @@ -1,11 +1,12 @@ package org.qortal.test; -import static org.junit.Assert.*; -import static org.qortal.utils.Unicode.*; - import org.junit.Test; import org.qortal.utils.Unicode; +import static org.junit.Assert.*; +import static org.qortal.utils.Unicode.NO_BREAK_SPACE; +import static org.qortal.utils.Unicode.ZERO_WIDTH_SPACE; + public class UnicodeTests { @Test diff --git a/src/test/java/org/qortal/test/api/AddressesApiTests.java b/src/test/java/org/qortal/test/api/AddressesApiTests.java index 1510f63f..319a9a52 100644 --- a/src/test/java/org/qortal/test/api/AddressesApiTests.java +++ b/src/test/java/org/qortal/test/api/AddressesApiTests.java @@ -1,15 +1,15 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - -import java.util.Collections; - import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.qortal.api.resource.AddressesResource; import org.qortal.test.common.ApiCommon; +import java.util.Collections; + +import static org.junit.Assert.assertNotNull; + public class AddressesApiTests extends ApiCommon { private AddressesResource addressesResource; diff --git a/src/test/java/org/qortal/test/api/AdminApiTests.java b/src/test/java/org/qortal/test/api/AdminApiTests.java index 01f2ebc9..6da52380 100644 --- a/src/test/java/org/qortal/test/api/AdminApiTests.java +++ b/src/test/java/org/qortal/test/api/AdminApiTests.java @@ -1,7 +1,5 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Before; import org.junit.Test; @@ -11,6 +9,8 @@ import org.qortal.settings.Settings; import org.qortal.test.common.ApiCommon; import org.qortal.test.common.Common; +import static org.junit.Assert.assertNotNull; + public class AdminApiTests extends ApiCommon { private AdminResource adminResource; diff --git a/src/test/java/org/qortal/test/api/ArbitraryApiTests.java b/src/test/java/org/qortal/test/api/ArbitraryApiTests.java index e4f27db6..d4ad8926 100644 --- a/src/test/java/org/qortal/test/api/ArbitraryApiTests.java +++ b/src/test/java/org/qortal/test/api/ArbitraryApiTests.java @@ -1,7 +1,5 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - import org.junit.Before; import org.junit.Test; import org.qortal.api.resource.ArbitraryResource; @@ -9,6 +7,8 @@ import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; import org.qortal.arbitrary.misc.Service; import org.qortal.test.common.ApiCommon; +import static org.junit.Assert.assertNotNull; + public class ArbitraryApiTests extends ApiCommon { private ArbitraryResource arbitraryResource; diff --git a/src/test/java/org/qortal/test/api/AssetsApiTests.java b/src/test/java/org/qortal/test/api/AssetsApiTests.java index d678c1ce..2e88b816 100644 --- a/src/test/java/org/qortal/test/api/AssetsApiTests.java +++ b/src/test/java/org/qortal/test/api/AssetsApiTests.java @@ -1,24 +1,25 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.junit.Before; import org.junit.Test; import org.qortal.api.ApiError; import org.qortal.api.ApiException; import org.qortal.api.resource.AssetsResource; import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; -import org.qortal.repository.Repository; -import org.qortal.repository.RepositoryManager; import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; import org.qortal.test.common.ApiCommon; import org.qortal.test.common.AssetUtils; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + public class AssetsApiTests extends ApiCommon { private static final String FAKE_ORDER_ID_BASE58 = "C3CPq7c8PY"; diff --git a/src/test/java/org/qortal/test/api/BlockApiTests.java b/src/test/java/org/qortal/test/api/BlockApiTests.java index 23e7b007..8366bacd 100644 --- a/src/test/java/org/qortal/test/api/BlockApiTests.java +++ b/src/test/java/org/qortal/test/api/BlockApiTests.java @@ -1,11 +1,5 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -21,6 +15,12 @@ import org.qortal.test.common.BlockUtils; import org.qortal.test.common.Common; import org.qortal.utils.Base58; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertNotNull; + public class BlockApiTests extends ApiCommon { private BlocksResource blocksResource; diff --git a/src/test/java/org/qortal/test/api/GroupApiTests.java b/src/test/java/org/qortal/test/api/GroupApiTests.java index cd288906..a5b8edd7 100644 --- a/src/test/java/org/qortal/test/api/GroupApiTests.java +++ b/src/test/java/org/qortal/test/api/GroupApiTests.java @@ -1,12 +1,12 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - import org.junit.Before; import org.junit.Test; import org.qortal.api.resource.GroupsResource; import org.qortal.test.common.ApiCommon; +import static org.junit.Assert.assertNotNull; + public class GroupApiTests extends ApiCommon { private GroupsResource groupsResource; diff --git a/src/test/java/org/qortal/test/api/NamesApiTests.java b/src/test/java/org/qortal/test/api/NamesApiTests.java index effdfea4..49fb44a7 100644 --- a/src/test/java/org/qortal/test/api/NamesApiTests.java +++ b/src/test/java/org/qortal/test/api/NamesApiTests.java @@ -1,7 +1,5 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; @@ -17,7 +15,8 @@ import org.qortal.test.common.Common; import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.RegisterNameTransaction; -import org.qortal.utils.NTP; + +import static org.junit.Assert.assertNotNull; public class NamesApiTests extends ApiCommon { diff --git a/src/test/java/org/qortal/test/api/TransactionsApiTests.java b/src/test/java/org/qortal/test/api/TransactionsApiTests.java index 102cac34..ac98ec23 100644 --- a/src/test/java/org/qortal/test/api/TransactionsApiTests.java +++ b/src/test/java/org/qortal/test/api/TransactionsApiTests.java @@ -1,10 +1,5 @@ package org.qortal.test.api; -import static org.junit.Assert.*; - -import java.util.Arrays; -import java.util.List; - import org.junit.Before; import org.junit.Test; import org.qortal.api.resource.TransactionsResource; @@ -12,6 +7,11 @@ import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; import org.qortal.test.common.ApiCommon; import org.qortal.transaction.Transaction.TransactionType; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertNotNull; + public class TransactionsApiTests extends ApiCommon { private TransactionsResource transactionsResource; diff --git a/src/test/java/org/qortal/test/apps/BuildCheckpoints.java b/src/test/java/org/qortal/test/apps/BuildCheckpoints.java index 48cc570c..5500c848 100644 --- a/src/test/java/org/qortal/test/apps/BuildCheckpoints.java +++ b/src/test/java/org/qortal/test/apps/BuildCheckpoints.java @@ -1,25 +1,16 @@ package org.qortal.test.apps; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; +import org.bitcoinj.core.*; +import org.bitcoinj.params.RegTestParams; +import org.bitcoinj.store.BlockStore; +import org.bitcoinj.store.MemoryBlockStore; + +import java.io.*; import java.net.InetAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.TreeMap; -import org.bitcoinj.core.BlockChain; -import org.bitcoinj.core.CheckpointManager; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.PeerAddress; -import org.bitcoinj.core.PeerGroup; -import org.bitcoinj.core.StoredBlock; -import org.bitcoinj.params.RegTestParams; -import org.bitcoinj.store.BlockStore; -import org.bitcoinj.store.MemoryBlockStore; - public class BuildCheckpoints { private static final TreeMap checkpoints = new TreeMap<>(); diff --git a/src/test/java/org/qortal/test/apps/CheckTranslations.java b/src/test/java/org/qortal/test/apps/CheckTranslations.java index b8008c78..bf239611 100644 --- a/src/test/java/org/qortal/test/apps/CheckTranslations.java +++ b/src/test/java/org/qortal/test/apps/CheckTranslations.java @@ -1,15 +1,15 @@ package org.qortal.test.apps; +import org.qortal.api.ApiError; +import org.qortal.globalization.Translator; +import org.qortal.transaction.Transaction.ValidationResult; + import java.util.Arrays; import java.util.Collections; import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; -import org.qortal.api.ApiError; -import org.qortal.globalization.Translator; -import org.qortal.transaction.Transaction.ValidationResult; - public class CheckTranslations { private static final String[] SUPPORTED_LANGS = new String[] { "en", "de", "zh", "ru" }; diff --git a/src/test/java/org/qortal/test/apps/DecodeOnlineAccounts.java b/src/test/java/org/qortal/test/apps/DecodeOnlineAccounts.java index 9242c422..891a7b97 100644 --- a/src/test/java/org/qortal/test/apps/DecodeOnlineAccounts.java +++ b/src/test/java/org/qortal/test/apps/DecodeOnlineAccounts.java @@ -1,8 +1,6 @@ package org.qortal.test.apps; -import java.math.BigDecimal; -import java.security.Security; - +import io.druid.extendedset.intset.ConciseSet; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; import org.qortal.block.BlockChain; @@ -19,7 +17,8 @@ import org.qortal.transform.block.BlockTransformer; import org.qortal.utils.Base58; import org.roaringbitmap.IntIterator; -import io.druid.extendedset.intset.ConciseSet; +import java.math.BigDecimal; +import java.security.Security; public class DecodeOnlineAccounts { diff --git a/src/test/java/org/qortal/test/apps/MemoryPoWTest.java b/src/test/java/org/qortal/test/apps/MemoryPoWTest.java index 81ab4843..520676bf 100644 --- a/src/test/java/org/qortal/test/apps/MemoryPoWTest.java +++ b/src/test/java/org/qortal/test/apps/MemoryPoWTest.java @@ -1,9 +1,9 @@ package org.qortal.test.apps; -import java.util.Random; - import org.qortal.crypto.MemoryPoW; +import java.util.Random; + public class MemoryPoWTest { public static void main(String[] args) { diff --git a/src/test/java/org/qortal/test/apps/NTPTests.java b/src/test/java/org/qortal/test/apps/NTPTests.java index 1dc25b00..df23fd88 100644 --- a/src/test/java/org/qortal/test/apps/NTPTests.java +++ b/src/test/java/org/qortal/test/apps/NTPTests.java @@ -1,17 +1,17 @@ package org.qortal.test.apps; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.LoggerConfig; -import org.apache.logging.log4j.core.LoggerContext; import org.qortal.utils.NTP; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class NTPTests { private static final List CC_TLDS = Arrays.asList("oceania", "europe", "cn", "asia", "africa"); diff --git a/src/test/java/org/qortal/test/apps/ProxyTest.java b/src/test/java/org/qortal/test/apps/ProxyTest.java index 7ddd9ea8..c3b3e105 100644 --- a/src/test/java/org/qortal/test/apps/ProxyTest.java +++ b/src/test/java/org/qortal/test/apps/ProxyTest.java @@ -1,22 +1,13 @@ package org.qortal.test.apps; +import javax.net.ssl.*; import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.URL; +import java.net.*; import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SNIHostName; -import javax.net.ssl.SNIServerName; -import javax.net.ssl.SSLParameters; -import javax.net.ssl.SSLSocket; - public class ProxyTest { private static final Pattern proxyUrlPattern = Pattern.compile("(https://)([^@:/]+)@([0-9.]{7,15})(/.*)"); diff --git a/src/test/java/org/qortal/test/apps/RewardShareKeys.java b/src/test/java/org/qortal/test/apps/RewardShareKeys.java index 5ba1aab4..366bbbb8 100644 --- a/src/test/java/org/qortal/test/apps/RewardShareKeys.java +++ b/src/test/java/org/qortal/test/apps/RewardShareKeys.java @@ -1,7 +1,5 @@ package org.qortal.test.apps; -import java.security.Security; - import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; import org.qortal.account.PrivateKeyAccount; @@ -9,6 +7,8 @@ import org.qortal.account.PublicKeyAccount; import org.qortal.crypto.Crypto; import org.qortal.utils.Base58; +import java.security.Security; + public class RewardShareKeys { private static void usage() { diff --git a/src/test/java/org/qortal/test/apps/SettingsTests.java b/src/test/java/org/qortal/test/apps/SettingsTests.java index 30ead476..9c236e5f 100644 --- a/src/test/java/org/qortal/test/apps/SettingsTests.java +++ b/src/test/java/org/qortal/test/apps/SettingsTests.java @@ -1,20 +1,19 @@ package org.qortal.test.apps; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import javax.xml.transform.stream.StreamSource; - import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.UnmarshallerProperties; import org.qortal.block.BlockChain; import org.qortal.data.transaction.TransactionData; import org.qortal.settings.Settings; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.stream.StreamSource; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + public class SettingsTests { public static void main(String[] args) throws JAXBException, IOException { diff --git a/src/test/java/org/qortal/test/apps/SyncReport.java b/src/test/java/org/qortal/test/apps/SyncReport.java index 323b2ed9..402ae118 100644 --- a/src/test/java/org/qortal/test/apps/SyncReport.java +++ b/src/test/java/org/qortal/test/apps/SyncReport.java @@ -8,12 +8,7 @@ import java.nio.file.Paths; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Scanner; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; diff --git a/src/test/java/org/qortal/test/apps/VanityGen.java b/src/test/java/org/qortal/test/apps/VanityGen.java index 2c22ea0b..43e1c749 100644 --- a/src/test/java/org/qortal/test/apps/VanityGen.java +++ b/src/test/java/org/qortal/test/apps/VanityGen.java @@ -1,18 +1,17 @@ package org.qortal.test.apps; -import java.security.SecureRandom; -import java.security.Security; -import java.util.Random; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - +import com.google.common.primitives.Bytes; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; import org.qortal.account.PrivateKeyAccount; import org.qortal.crypto.Crypto; import org.qortal.utils.Base58; -import com.google.common.primitives.Bytes; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class VanityGen { diff --git a/src/test/java/org/qortal/test/apps/brokenmd160.java b/src/test/java/org/qortal/test/apps/brokenmd160.java index d83969ff..ae0e8a7d 100644 --- a/src/test/java/org/qortal/test/apps/brokenmd160.java +++ b/src/test/java/org/qortal/test/apps/brokenmd160.java @@ -1,7 +1,7 @@ package org.qortal.test.apps; -import org.qortal.crypto.BrokenMD160; import com.google.common.hash.HashCode; +import org.qortal.crypto.BrokenMD160; @SuppressWarnings("deprecation") public class brokenmd160 { diff --git a/src/test/java/org/qortal/test/apps/orphan.java b/src/test/java/org/qortal/test/apps/orphan.java index f847f98d..7acb4a7f 100644 --- a/src/test/java/org/qortal/test/apps/orphan.java +++ b/src/test/java/org/qortal/test/apps/orphan.java @@ -1,5 +1,4 @@ package org.qortal.test.apps; -import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.qortal.block.BlockChain; @@ -10,6 +9,8 @@ import org.qortal.repository.RepositoryManager; import org.qortal.repository.hsqldb.HSQLDBRepositoryFactory; import org.qortal.settings.Settings; +import java.security.Security; + public class orphan { public static void main(String[] args) { diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataDigestTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataDigestTests.java index 8ef04b27..fdc1f541 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataDigestTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataDigestTests.java @@ -13,7 +13,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.UUID; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class ArbitraryDataDigestTests extends Common { diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataFileTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataFileTests.java index d2ee61c6..ac633717 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataFileTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataFileTests.java @@ -2,8 +2,8 @@ package org.qortal.test.arbitrary; import org.junit.Before; import org.junit.Test; -import org.qortal.repository.DataException; import org.qortal.arbitrary.ArbitraryDataFile; +import org.qortal.repository.DataException; import org.qortal.test.common.Common; import java.util.Random; diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataStoragePolicyTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataStoragePolicyTests.java index 49e645cf..1d8f23b3 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataStoragePolicyTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataStoragePolicyTests.java @@ -23,7 +23,6 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.RegisterNameTransaction; import org.qortal.utils.Base58; -import org.qortal.utils.NTP; import java.io.IOException; import java.nio.file.Path; diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java index cfc656e1..11f559bf 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java @@ -6,14 +6,14 @@ import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.arbitrary.ArbitraryDataDigest; import org.qortal.arbitrary.ArbitraryDataFile; -import org.qortal.arbitrary.ArbitraryDataFile.*; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.ArbitraryDataReader; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch; import org.qortal.arbitrary.misc.Service; import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.crypto.Crypto; -import org.qortal.data.transaction.ArbitraryTransactionData.*; +import org.qortal.data.transaction.ArbitraryTransactionData.Method; import org.qortal.data.transaction.RegisterNameTransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -25,7 +25,6 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.RegisterNameTransaction; import org.qortal.utils.Base58; -import org.qortal.utils.NTP; import java.io.IOException; import java.nio.file.Files; diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryEncryptionTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryEncryptionTests.java index 2e4dc133..632ff51a 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryEncryptionTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryEncryptionTests.java @@ -2,12 +2,10 @@ package org.qortal.test.arbitrary; import org.junit.Before; import org.junit.Test; -import org.qortal.arbitrary.ArbitraryDataDigest; import org.qortal.crypto.AES; import org.qortal.crypto.Crypto; import org.qortal.repository.DataException; import org.qortal.test.common.Common; -import org.qortal.utils.ZipUtils; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionMetadataTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionMetadataTests.java index 9ac73166..cd3893af 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionMetadataTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionMetadataTests.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.arbitrary.ArbitraryDataDigest; import org.qortal.arbitrary.ArbitraryDataFile; -import org.qortal.arbitrary.ArbitraryDataFile.*; +import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.ArbitraryDataReader; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.misc.Category; diff --git a/src/test/java/org/qortal/test/assets/CancellingTests.java b/src/test/java/org/qortal/test/assets/CancellingTests.java index 0d998cb5..4cd61cbc 100644 --- a/src/test/java/org/qortal/test/assets/CancellingTests.java +++ b/src/test/java/org/qortal/test/assets/CancellingTests.java @@ -1,9 +1,5 @@ package org.qortal.test.assets; -import static org.junit.Assert.*; - -import java.util.Map; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,6 +13,10 @@ import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.utils.Amounts; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + public class CancellingTests extends Common { /* diff --git a/src/test/java/org/qortal/test/assets/GranularityTests.java b/src/test/java/org/qortal/test/assets/GranularityTests.java index 9288f3a3..0a4b5164 100644 --- a/src/test/java/org/qortal/test/assets/GranularityTests.java +++ b/src/test/java/org/qortal/test/assets/GranularityTests.java @@ -1,9 +1,5 @@ package org.qortal.test.assets; -import static org.junit.Assert.assertEquals; - -import java.math.BigDecimal; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -12,6 +8,10 @@ import org.qortal.repository.DataException; import org.qortal.test.common.Common; import org.qortal.utils.Amounts; +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; + /** Check granularity adjustment values. */ public class GranularityTests extends Common { diff --git a/src/test/java/org/qortal/test/assets/MiscTests.java b/src/test/java/org/qortal/test/assets/MiscTests.java index c676f94f..f6c7b20c 100644 --- a/src/test/java/org/qortal/test/assets/MiscTests.java +++ b/src/test/java/org/qortal/test/assets/MiscTests.java @@ -1,7 +1,5 @@ package org.qortal.test.assets; -import static org.junit.Assert.*; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -18,6 +16,9 @@ import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.utils.Amounts; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class MiscTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/assets/TradingTests.java b/src/test/java/org/qortal/test/assets/TradingTests.java index 2df34748..f71c39d0 100644 --- a/src/test/java/org/qortal/test/assets/TradingTests.java +++ b/src/test/java/org/qortal/test/assets/TradingTests.java @@ -12,10 +12,10 @@ import org.qortal.test.common.AssetUtils; import org.qortal.test.common.Common; import org.qortal.utils.Amounts; -import static org.junit.Assert.assertEquals; - import java.util.Map; +import static org.junit.Assert.assertEquals; + public class TradingTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/at/AtRepositoryTests.java b/src/test/java/org/qortal/test/at/AtRepositoryTests.java index 8441731f..5472fdb8 100644 --- a/src/test/java/org/qortal/test/at/AtRepositoryTests.java +++ b/src/test/java/org/qortal/test/at/AtRepositoryTests.java @@ -1,9 +1,5 @@ package org.qortal.test.at; -import static org.junit.Assert.*; - -import java.util.List; - import org.ciyam.at.MachineState; import org.junit.Before; import org.junit.Test; @@ -18,6 +14,10 @@ import org.qortal.test.common.BlockUtils; import org.qortal.test.common.Common; import org.qortal.transaction.DeployAtTransaction; +import java.util.List; + +import static org.junit.Assert.*; + public class AtRepositoryTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/at/GetMessageLengthTests.java b/src/test/java/org/qortal/test/at/GetMessageLengthTests.java index e7a7bcc4..0ab007ba 100644 --- a/src/test/java/org/qortal/test/at/GetMessageLengthTests.java +++ b/src/test/java/org/qortal/test/at/GetMessageLengthTests.java @@ -1,10 +1,5 @@ package org.qortal.test.at; -import static org.junit.Assert.*; - -import java.nio.ByteBuffer; -import java.util.Random; - import org.ciyam.at.CompilationException; import org.ciyam.at.FunctionCode; import org.ciyam.at.MachineState; @@ -31,6 +26,11 @@ import org.qortal.transaction.DeployAtTransaction; import org.qortal.transaction.MessageTransaction; import org.qortal.utils.BitTwiddling; +import java.nio.ByteBuffer; +import java.util.Random; + +import static org.junit.Assert.assertEquals; + public class GetMessageLengthTests extends Common { private static final Random RANDOM = new Random(); diff --git a/src/test/java/org/qortal/test/at/GetNextTransactionTests.java b/src/test/java/org/qortal/test/at/GetNextTransactionTests.java index c2eb9ede..a16c27eb 100644 --- a/src/test/java/org/qortal/test/at/GetNextTransactionTests.java +++ b/src/test/java/org/qortal/test/at/GetNextTransactionTests.java @@ -1,16 +1,6 @@ package org.qortal.test.at; -import static org.junit.Assert.*; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import org.ciyam.at.CompilationException; -import org.ciyam.at.FunctionCode; -import org.ciyam.at.MachineState; -import org.ciyam.at.OpCode; -import org.ciyam.at.Timestamp; +import org.ciyam.at.*; import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; @@ -34,6 +24,12 @@ import org.qortal.transaction.MessageTransaction; import org.qortal.transaction.Transaction; import org.qortal.utils.BitTwiddling; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; + public class GetNextTransactionTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/at/GetPartialMessageTests.java b/src/test/java/org/qortal/test/at/GetPartialMessageTests.java index 0f9b188a..8fc0697b 100644 --- a/src/test/java/org/qortal/test/at/GetPartialMessageTests.java +++ b/src/test/java/org/qortal/test/at/GetPartialMessageTests.java @@ -1,9 +1,5 @@ package org.qortal.test.at; -import static org.junit.Assert.*; - -import java.nio.ByteBuffer; - import org.ciyam.at.CompilationException; import org.ciyam.at.FunctionCode; import org.ciyam.at.MachineState; @@ -28,6 +24,10 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.transaction.DeployAtTransaction; import org.qortal.transaction.MessageTransaction; +import java.nio.ByteBuffer; + +import static org.junit.Assert.assertArrayEquals; + public class GetPartialMessageTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/at/SleepUntilMessageOrHeightTests.java b/src/test/java/org/qortal/test/at/SleepUntilMessageOrHeightTests.java index 7ac952d2..fb65fa03 100644 --- a/src/test/java/org/qortal/test/at/SleepUntilMessageOrHeightTests.java +++ b/src/test/java/org/qortal/test/at/SleepUntilMessageOrHeightTests.java @@ -1,16 +1,6 @@ package org.qortal.test.at; -import static org.junit.Assert.*; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import org.ciyam.at.CompilationException; -import org.ciyam.at.FunctionCode; -import org.ciyam.at.MachineState; -import org.ciyam.at.OpCode; -import org.ciyam.at.Timestamp; +import org.ciyam.at.*; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -37,6 +27,12 @@ import org.qortal.transaction.MessageTransaction; import org.qortal.transaction.Transaction; import org.qortal.utils.BitTwiddling; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; + public class SleepUntilMessageOrHeightTests extends Common { private static final byte[] messageData = new byte[] { 0x44 }; diff --git a/src/test/java/org/qortal/test/at/SleepUntilMessageTests.java b/src/test/java/org/qortal/test/at/SleepUntilMessageTests.java index 290f973a..3f8a95d6 100644 --- a/src/test/java/org/qortal/test/at/SleepUntilMessageTests.java +++ b/src/test/java/org/qortal/test/at/SleepUntilMessageTests.java @@ -1,16 +1,6 @@ package org.qortal.test.at; -import static org.junit.Assert.*; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import org.ciyam.at.CompilationException; -import org.ciyam.at.FunctionCode; -import org.ciyam.at.MachineState; -import org.ciyam.at.OpCode; -import org.ciyam.at.Timestamp; +import org.ciyam.at.*; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -37,6 +27,12 @@ import org.qortal.transaction.MessageTransaction; import org.qortal.transaction.Transaction; import org.qortal.utils.BitTwiddling; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; + public class SleepUntilMessageTests extends Common { private static final byte[] messageData = new byte[] { 0x44 }; diff --git a/src/test/java/org/qortal/test/common/AccountUtils.java b/src/test/java/org/qortal/test/common/AccountUtils.java index bdfd124b..e19cffff 100644 --- a/src/test/java/org/qortal/test/common/AccountUtils.java +++ b/src/test/java/org/qortal/test/common/AccountUtils.java @@ -1,11 +1,5 @@ package org.qortal.test.common; -import static org.junit.Assert.assertEquals; -import static org.qortal.crypto.Qortal25519Extras.signForAggregation; - -import java.security.SecureRandom; -import java.util.*; - import com.google.common.primitives.Longs; import org.qortal.account.PrivateKeyAccount; import org.qortal.crypto.Crypto; @@ -22,6 +16,12 @@ import org.qortal.transaction.Transaction; import org.qortal.transform.Transformer; import org.qortal.utils.Amounts; +import java.security.SecureRandom; +import java.util.*; + +import static org.junit.Assert.assertEquals; +import static org.qortal.crypto.Qortal25519Extras.signForAggregation; + public class AccountUtils { public static final int txGroupId = Group.NO_GROUP; diff --git a/src/test/java/org/qortal/test/common/ApiCommon.java b/src/test/java/org/qortal/test/common/ApiCommon.java index b5d02b24..1d1ca805 100644 --- a/src/test/java/org/qortal/test/common/ApiCommon.java +++ b/src/test/java/org/qortal/test/common/ApiCommon.java @@ -1,15 +1,16 @@ package org.qortal.test.common; -import static org.junit.Assert.*; - -import java.lang.reflect.Field; - import org.eclipse.jetty.server.Request; import org.junit.Before; import org.qortal.api.ApiError; import org.qortal.api.ApiException; import org.qortal.repository.DataException; +import java.lang.reflect.Field; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + public class ApiCommon extends Common { public static final long MAX_API_RESPONSE_PERIOD = 2_000L; // ms diff --git a/src/test/java/org/qortal/test/common/AssetUtils.java b/src/test/java/org/qortal/test/common/AssetUtils.java index 7118a79d..0b970dd5 100644 --- a/src/test/java/org/qortal/test/common/AssetUtils.java +++ b/src/test/java/org/qortal/test/common/AssetUtils.java @@ -1,19 +1,8 @@ package org.qortal.test.common; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.Base64; -import java.util.Base64.Encoder; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.asset.OrderData; -import org.qortal.data.transaction.BaseTransactionData; -import org.qortal.data.transaction.CancelAssetOrderTransactionData; -import org.qortal.data.transaction.CreateAssetOrderTransactionData; -import org.qortal.data.transaction.IssueAssetTransactionData; -import org.qortal.data.transaction.TransactionData; -import org.qortal.data.transaction.TransferAssetTransactionData; +import org.qortal.data.transaction.*; import org.qortal.group.Group; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -21,9 +10,14 @@ import org.qortal.repository.RepositoryManager; import org.qortal.transaction.Transaction; import org.qortal.utils.Amounts; +import java.util.Base64; +import java.util.Base64.Encoder; import java.util.Map; import java.util.Random; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + public class AssetUtils { public static final int txGroupId = Group.NO_GROUP; diff --git a/src/test/java/org/qortal/test/common/Common.java b/src/test/java/org/qortal/test/common/Common.java index bb6cc1cb..70dcaff9 100644 --- a/src/test/java/org/qortal/test/common/Common.java +++ b/src/test/java/org/qortal/test/common/Common.java @@ -1,24 +1,5 @@ package org.qortal.test.common; -import static org.junit.Assert.*; - -import java.io.IOException; -import java.math.BigDecimal; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.SecureRandom; -import java.security.Security; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -31,15 +12,29 @@ import org.qortal.block.BlockChain; import org.qortal.data.account.AccountBalanceData; import org.qortal.data.asset.AssetData; import org.qortal.data.group.GroupData; +import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryFactory; import org.qortal.repository.RepositoryManager; -import org.qortal.repository.AccountRepository.BalanceOrdering; import org.qortal.repository.hsqldb.HSQLDBRepositoryFactory; import org.qortal.settings.Settings; import org.qortal.utils.NTP; +import java.io.IOException; +import java.math.BigDecimal; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.security.Security; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.junit.Assert.*; + public class Common { static { diff --git a/src/test/java/org/qortal/test/common/FakePeer.java b/src/test/java/org/qortal/test/common/FakePeer.java index 13d9a15e..faabdc1f 100644 --- a/src/test/java/org/qortal/test/common/FakePeer.java +++ b/src/test/java/org/qortal/test/common/FakePeer.java @@ -1,5 +1,7 @@ package org.qortal.test.common; +import org.qortal.network.message.Message; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -7,8 +9,6 @@ import java.util.Random; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.qortal.network.message.Message; - public abstract class FakePeer implements Runnable { private static final long DEFAULT_BROADCAST_INTERVAL = 60 * 1000; diff --git a/src/test/java/org/qortal/test/common/GroupUtils.java b/src/test/java/org/qortal/test/common/GroupUtils.java index 19d229fd..cda7ad8e 100644 --- a/src/test/java/org/qortal/test/common/GroupUtils.java +++ b/src/test/java/org/qortal/test/common/GroupUtils.java @@ -1,11 +1,7 @@ package org.qortal.test.common; import org.qortal.account.PrivateKeyAccount; -import org.qortal.data.transaction.BaseTransactionData; -import org.qortal.data.transaction.CreateGroupTransactionData; -import org.qortal.data.transaction.GroupApprovalTransactionData; -import org.qortal.data.transaction.JoinGroupTransactionData; -import org.qortal.data.transaction.TransactionData; +import org.qortal.data.transaction.*; import org.qortal.group.Group; import org.qortal.group.Group.ApprovalThreshold; import org.qortal.repository.DataException; diff --git a/src/test/java/org/qortal/test/common/PeerMessage.java b/src/test/java/org/qortal/test/common/PeerMessage.java index 92f69621..3b1e3e75 100644 --- a/src/test/java/org/qortal/test/common/PeerMessage.java +++ b/src/test/java/org/qortal/test/common/PeerMessage.java @@ -1,7 +1,6 @@ package org.qortal.test.common; import org.qortal.network.message.Message; -import org.qortal.test.common.FakePeer; public class PeerMessage { public final FakePeer peer; diff --git a/src/test/java/org/qortal/test/common/TransactionUtils.java b/src/test/java/org/qortal/test/common/TransactionUtils.java index 4779aa3b..0159d35b 100644 --- a/src/test/java/org/qortal/test/common/TransactionUtils.java +++ b/src/test/java/org/qortal/test/common/TransactionUtils.java @@ -1,12 +1,5 @@ package org.qortal.test.common; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; @@ -16,6 +9,13 @@ import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transaction.Transaction.ValidationResult; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class TransactionUtils { /** Signs transaction using given account and attempts to import into unconfirmed pile, returning validation result. */ diff --git a/src/test/java/org/qortal/test/common/transaction/AccountLevelTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/AccountLevelTestTransaction.java index 6de63cf6..7fd51ec2 100644 --- a/src/test/java/org/qortal/test/common/transaction/AccountLevelTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/AccountLevelTestTransaction.java @@ -1,13 +1,13 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.AccountLevelTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Random; + public class AccountLevelTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java index 8688ed73..a2c81bf5 100644 --- a/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java @@ -1,19 +1,19 @@ package org.qortal.test.common.transaction; -import java.util.ArrayList; -import java.util.List; - import org.qortal.account.PrivateKeyAccount; import org.qortal.arbitrary.misc.Service; import org.qortal.asset.Asset; import org.qortal.data.PaymentData; import org.qortal.data.transaction.ArbitraryTransactionData; -import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.DataType; +import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Amounts; +import java.util.ArrayList; +import java.util.List; + public class ArbitraryTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/CancelAssetOrderTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/CancelAssetOrderTestTransaction.java index 026364dc..0634e617 100644 --- a/src/test/java/org/qortal/test/common/transaction/CancelAssetOrderTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/CancelAssetOrderTestTransaction.java @@ -1,13 +1,13 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.CancelAssetOrderTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Random; + public class CancelAssetOrderTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/CreateGroupTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/CreateGroupTestTransaction.java index a68c7aeb..f796473d 100644 --- a/src/test/java/org/qortal/test/common/transaction/CreateGroupTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/CreateGroupTestTransaction.java @@ -1,7 +1,5 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.CreateGroupTransactionData; import org.qortal.data.transaction.TransactionData; @@ -9,6 +7,8 @@ import org.qortal.group.Group.ApprovalThreshold; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Random; + public class CreateGroupTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/CreatePollTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/CreatePollTestTransaction.java index 789e8b2a..00fba97a 100644 --- a/src/test/java/org/qortal/test/common/transaction/CreatePollTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/CreatePollTestTransaction.java @@ -1,9 +1,5 @@ package org.qortal.test.common.transaction; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.CreatePollTransactionData; import org.qortal.data.transaction.TransactionData; @@ -11,6 +7,10 @@ import org.qortal.data.voting.PollOptionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + public class CreatePollTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/DeployAtTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/DeployAtTestTransaction.java index 3e523178..6034370a 100644 --- a/src/test/java/org/qortal/test/common/transaction/DeployAtTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/DeployAtTestTransaction.java @@ -1,7 +1,5 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.asset.Asset; import org.qortal.data.transaction.DeployAtTransactionData; @@ -10,6 +8,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Amounts; +import java.util.Random; + public class DeployAtTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/GroupApprovalTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/GroupApprovalTestTransaction.java index 3d52462c..4770c1f3 100644 --- a/src/test/java/org/qortal/test/common/transaction/GroupApprovalTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/GroupApprovalTestTransaction.java @@ -1,13 +1,13 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.GroupApprovalTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Random; + public class GroupApprovalTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java index fb04d2cf..21024467 100644 --- a/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java @@ -1,7 +1,5 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.IssueAssetTransactionData; import org.qortal.data.transaction.TransactionData; @@ -9,6 +7,8 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.test.common.AssetUtils; +import java.util.Random; + public class IssueAssetTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/MultiPaymentTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/MultiPaymentTestTransaction.java index a25924c2..ad884dd7 100644 --- a/src/test/java/org/qortal/test/common/transaction/MultiPaymentTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/MultiPaymentTestTransaction.java @@ -1,8 +1,5 @@ package org.qortal.test.common.transaction; -import java.util.ArrayList; -import java.util.List; - import org.qortal.account.PrivateKeyAccount; import org.qortal.asset.Asset; import org.qortal.data.PaymentData; @@ -12,6 +9,9 @@ import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.utils.Amounts; +import java.util.ArrayList; +import java.util.List; + public class MultiPaymentTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/common/transaction/TestTransaction.java b/src/test/java/org/qortal/test/common/transaction/TestTransaction.java index b580ecd3..0e9de3af 100644 --- a/src/test/java/org/qortal/test/common/transaction/TestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/TestTransaction.java @@ -1,13 +1,12 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.block.BlockChain; import org.qortal.data.transaction.BaseTransactionData; import org.qortal.group.Group; import org.qortal.repository.DataException; -import org.qortal.utils.NTP; + +import java.util.Random; public abstract class TestTransaction { diff --git a/src/test/java/org/qortal/test/common/transaction/VoteOnPollTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/VoteOnPollTestTransaction.java index b5217b33..8aa1ebde 100644 --- a/src/test/java/org/qortal/test/common/transaction/VoteOnPollTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/VoteOnPollTestTransaction.java @@ -1,13 +1,13 @@ package org.qortal.test.common.transaction; -import java.util.Random; - import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.VoteOnPollTransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; +import java.util.Random; + public class VoteOnPollTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { diff --git a/src/test/java/org/qortal/test/crosschain/ElectrumXTests.java b/src/test/java/org/qortal/test/crosschain/ElectrumXTests.java index b7e57cf3..c4c0acf1 100644 --- a/src/test/java/org/qortal/test/crosschain/ElectrumXTests.java +++ b/src/test/java/org/qortal/test/crosschain/ElectrumXTests.java @@ -1,28 +1,23 @@ package org.qortal.test.crosschain; -import static org.junit.Assert.*; - -import java.security.Security; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; - +import com.google.common.hash.HashCode; import org.bitcoinj.core.Address; import org.bitcoinj.params.TestNet3Params; import org.bitcoinj.script.ScriptBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; import org.junit.Test; -import org.qortal.crosschain.ForeignBlockchainException; -import org.qortal.crosschain.BitcoinyTransaction; -import org.qortal.crosschain.ElectrumX; -import org.qortal.crosschain.TransactionHash; -import org.qortal.crosschain.UnspentOutput; import org.qortal.crosschain.Bitcoin.BitcoinNet; +import org.qortal.crosschain.*; import org.qortal.crosschain.ElectrumX.Server.ConnectionType; import org.qortal.utils.BitTwiddling; -import com.google.common.hash.HashCode; +import java.security.Security; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.*; public class ElectrumXTests { diff --git a/src/test/java/org/qortal/test/crosschain/HtlcTests.java b/src/test/java/org/qortal/test/crosschain/HtlcTests.java index 3f3678f7..38f6bd0b 100644 --- a/src/test/java/org/qortal/test/crosschain/HtlcTests.java +++ b/src/test/java/org/qortal/test/crosschain/HtlcTests.java @@ -1,20 +1,19 @@ package org.qortal.test.crosschain; -import static org.junit.Assert.*; - +import com.google.common.primitives.Longs; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.qortal.crosschain.Bitcoin; +import org.qortal.crosschain.BitcoinyHTLC; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Litecoin; import org.qortal.crypto.Crypto; -import org.qortal.crosschain.BitcoinyHTLC; import org.qortal.repository.DataException; import org.qortal.test.common.Common; -import com.google.common.primitives.Longs; +import static org.junit.Assert.*; public class HtlcTests extends Common { diff --git a/src/test/java/org/qortal/test/crosschain/PirateChainTests.java b/src/test/java/org/qortal/test/crosschain/PirateChainTests.java index b212aea1..5fb7b205 100644 --- a/src/test/java/org/qortal/test/crosschain/PirateChainTests.java +++ b/src/test/java/org/qortal/test/crosschain/PirateChainTests.java @@ -1,6 +1,6 @@ package org.qortal.test.crosschain; -import cash.z.wallet.sdk.rpc.CompactFormats.*; +import cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock; import com.google.common.hash.HashCode; import com.google.common.primitives.Bytes; import org.junit.Ignore; diff --git a/src/test/java/org/qortal/test/crosschain/apps/BuildHTLC.java b/src/test/java/org/qortal/test/crosschain/apps/BuildHTLC.java index fa92fde7..f538d342 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/BuildHTLC.java +++ b/src/test/java/org/qortal/test/crosschain/apps/BuildHTLC.java @@ -1,19 +1,18 @@ package org.qortal.test.crosschain.apps; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; - +import com.google.common.hash.HashCode; import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.script.Script.ScriptType; -import org.qortal.crosschain.Litecoin; import org.qortal.crosschain.Bitcoin; import org.qortal.crosschain.Bitcoiny; import org.qortal.crosschain.BitcoinyHTLC; +import org.qortal.crosschain.Litecoin; -import com.google.common.hash.HashCode; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; public class BuildHTLC { diff --git a/src/test/java/org/qortal/test/crosschain/apps/CheckHTLC.java b/src/test/java/org/qortal/test/crosschain/apps/CheckHTLC.java index 8b1cc423..5d84a622 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/CheckHTLC.java +++ b/src/test/java/org/qortal/test/crosschain/apps/CheckHTLC.java @@ -1,9 +1,6 @@ package org.qortal.test.crosschain.apps; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; - +import com.google.common.hash.HashCode; import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.bitcoinj.core.LegacyAddress; @@ -11,11 +8,13 @@ import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.script.Script.ScriptType; import org.qortal.crosschain.Bitcoin; import org.qortal.crosschain.Bitcoiny; -import org.qortal.crosschain.Litecoin; import org.qortal.crosschain.BitcoinyHTLC; +import org.qortal.crosschain.Litecoin; import org.qortal.crypto.Crypto; -import com.google.common.hash.HashCode; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; public class CheckHTLC { diff --git a/src/test/java/org/qortal/test/crosschain/apps/Common.java b/src/test/java/org/qortal/test/crosschain/apps/Common.java index 78066fe7..dd3130b9 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/Common.java +++ b/src/test/java/org/qortal/test/crosschain/apps/Common.java @@ -1,12 +1,6 @@ package org.qortal.test.crosschain.apps; -import java.security.Security; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.Collections; -import java.util.List; - +import com.google.common.hash.HashCode; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionOutput; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -17,7 +11,12 @@ import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.settings.Settings; import org.qortal.utils.NTP; -import com.google.common.hash.HashCode; +import java.security.Security; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Collections; +import java.util.List; public abstract class Common { diff --git a/src/test/java/org/qortal/test/crosschain/apps/GetNextReceiveAddress.java b/src/test/java/org/qortal/test/crosschain/apps/GetNextReceiveAddress.java index ef22355b..a02b85bb 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/GetNextReceiveAddress.java +++ b/src/test/java/org/qortal/test/crosschain/apps/GetNextReceiveAddress.java @@ -1,7 +1,5 @@ package org.qortal.test.crosschain.apps; -import java.security.Security; - import org.bitcoinj.core.AddressFormatException; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; @@ -11,6 +9,8 @@ import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Litecoin; import org.qortal.settings.Settings; +import java.security.Security; + public class GetNextReceiveAddress { static { diff --git a/src/test/java/org/qortal/test/crosschain/apps/GetTransaction.java b/src/test/java/org/qortal/test/crosschain/apps/GetTransaction.java index 9d903a56..6e6ca26c 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/GetTransaction.java +++ b/src/test/java/org/qortal/test/crosschain/apps/GetTransaction.java @@ -1,8 +1,6 @@ package org.qortal.test.crosschain.apps; -import java.security.Security; -import java.util.List; - +import com.google.common.hash.HashCode; import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.TransactionOutput; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -13,7 +11,8 @@ import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Litecoin; import org.qortal.settings.Settings; -import com.google.common.hash.HashCode; +import java.security.Security; +import java.util.List; public class GetTransaction { diff --git a/src/test/java/org/qortal/test/crosschain/apps/GetWalletTransactions.java b/src/test/java/org/qortal/test/crosschain/apps/GetWalletTransactions.java index 2c1edc10..c1fbed1f 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/GetWalletTransactions.java +++ b/src/test/java/org/qortal/test/crosschain/apps/GetWalletTransactions.java @@ -1,16 +1,16 @@ package org.qortal.test.crosschain.apps; -import java.security.Security; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - import org.bitcoinj.core.AddressFormatException; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; import org.qortal.crosschain.*; import org.qortal.settings.Settings; +import java.security.Security; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + public class GetWalletTransactions { static { diff --git a/src/test/java/org/qortal/test/crosschain/apps/RedeemHTLC.java b/src/test/java/org/qortal/test/crosschain/apps/RedeemHTLC.java index d4f1bcf1..b982ca94 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/RedeemHTLC.java +++ b/src/test/java/org/qortal/test/crosschain/apps/RedeemHTLC.java @@ -1,23 +1,16 @@ package org.qortal.test.crosschain.apps; -import java.util.Arrays; -import java.util.List; - -import org.bitcoinj.core.Address; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.LegacyAddress; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; +import com.google.common.hash.HashCode; +import org.bitcoinj.core.*; import org.bitcoinj.script.Script.ScriptType; import org.qortal.crosschain.Bitcoin; import org.qortal.crosschain.Bitcoiny; -import org.qortal.crosschain.Litecoin; import org.qortal.crosschain.BitcoinyHTLC; +import org.qortal.crosschain.Litecoin; import org.qortal.crypto.Crypto; -import com.google.common.hash.HashCode; +import java.util.Arrays; +import java.util.List; public class RedeemHTLC { diff --git a/src/test/java/org/qortal/test/crosschain/apps/RefundHTLC.java b/src/test/java/org/qortal/test/crosschain/apps/RefundHTLC.java index 723185f0..09213aad 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/RefundHTLC.java +++ b/src/test/java/org/qortal/test/crosschain/apps/RefundHTLC.java @@ -1,23 +1,16 @@ package org.qortal.test.crosschain.apps; -import java.util.Arrays; -import java.util.List; - -import org.bitcoinj.core.Address; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.LegacyAddress; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; +import com.google.common.hash.HashCode; +import org.bitcoinj.core.*; import org.bitcoinj.script.Script.ScriptType; -import org.qortal.crosschain.Litecoin; import org.qortal.crosschain.Bitcoin; import org.qortal.crosschain.Bitcoiny; import org.qortal.crosschain.BitcoinyHTLC; +import org.qortal.crosschain.Litecoin; import org.qortal.crypto.Crypto; -import com.google.common.hash.HashCode; +import java.util.Arrays; +import java.util.List; public class RefundHTLC { diff --git a/src/test/java/org/qortal/test/crosschain/bitcoinv1/BitcoinACCTv1Tests.java b/src/test/java/org/qortal/test/crosschain/bitcoinv1/BitcoinACCTv1Tests.java index cc33eb43..fa9417b4 100644 --- a/src/test/java/org/qortal/test/crosschain/bitcoinv1/BitcoinACCTv1Tests.java +++ b/src/test/java/org/qortal/test/crosschain/bitcoinv1/BitcoinACCTv1Tests.java @@ -1,16 +1,13 @@ package org.qortal.test.crosschain.bitcoinv1; -import static org.junit.Assert.*; - -import java.util.function.Function; - +import com.google.common.hash.HashCode; import org.junit.Test; import org.qortal.account.Account; import org.qortal.account.PrivateKeyAccount; import org.qortal.asset.Asset; import org.qortal.crosschain.ACCT; -import org.qortal.crosschain.BitcoinACCTv1; import org.qortal.crosschain.AcctMode; +import org.qortal.crosschain.BitcoinACCTv1; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; import org.qortal.data.at.ATStateData; @@ -24,7 +21,10 @@ import org.qortal.test.crosschain.ACCTTests; import org.qortal.transaction.DeployAtTransaction; import org.qortal.transaction.MessageTransaction; -import com.google.common.hash.HashCode; +import java.util.function.Function; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; public class BitcoinACCTv1Tests extends ACCTTests { diff --git a/src/test/java/org/qortal/test/crosschain/bitcoinv1/DeployAT.java b/src/test/java/org/qortal/test/crosschain/bitcoinv1/DeployAT.java index f27f7a7b..ee18ae46 100644 --- a/src/test/java/org/qortal/test/crosschain/bitcoinv1/DeployAT.java +++ b/src/test/java/org/qortal/test/crosschain/bitcoinv1/DeployAT.java @@ -1,5 +1,6 @@ package org.qortal.test.crosschain.bitcoinv1; +import com.google.common.hash.HashCode; import org.bitcoinj.core.Address; import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.LegacyAddress; @@ -27,8 +28,6 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Amounts; import org.qortal.utils.Base58; -import com.google.common.hash.HashCode; - public class DeployAT { private static void usage(String error) { diff --git a/src/test/java/org/qortal/test/crosschain/litecoinv1/DeployAT.java b/src/test/java/org/qortal/test/crosschain/litecoinv1/DeployAT.java index 3a1f9208..99aeb365 100644 --- a/src/test/java/org/qortal/test/crosschain/litecoinv1/DeployAT.java +++ b/src/test/java/org/qortal/test/crosschain/litecoinv1/DeployAT.java @@ -1,7 +1,6 @@ package org.qortal.test.crosschain.litecoinv1; -import java.math.BigDecimal; - +import com.google.common.hash.HashCode; import org.bitcoinj.core.ECKey; import org.qortal.account.PrivateKeyAccount; import org.qortal.asset.Asset; @@ -22,7 +21,7 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Amounts; import org.qortal.utils.Base58; -import com.google.common.hash.HashCode; +import java.math.BigDecimal; public class DeployAT { diff --git a/src/test/java/org/qortal/test/crosschain/litecoinv1/LitecoinACCTv1Tests.java b/src/test/java/org/qortal/test/crosschain/litecoinv1/LitecoinACCTv1Tests.java index 91a450d0..e442067a 100644 --- a/src/test/java/org/qortal/test/crosschain/litecoinv1/LitecoinACCTv1Tests.java +++ b/src/test/java/org/qortal/test/crosschain/litecoinv1/LitecoinACCTv1Tests.java @@ -1,11 +1,10 @@ package org.qortal.test.crosschain.litecoinv1; +import com.google.common.hash.HashCode; import org.qortal.crosschain.ACCT; import org.qortal.crosschain.LitecoinACCTv1; import org.qortal.test.crosschain.ACCTTests; -import com.google.common.hash.HashCode; - public class LitecoinACCTv1Tests extends ACCTTests { public static final byte[] litecoinPublicKeyHash = HashCode.fromString("bb00bb11bb22bb33bb44bb55bb66bb77bb88bb99").asBytes(); diff --git a/src/test/java/org/qortal/test/crosschain/litecoinv1/SendRedeemMessage.java b/src/test/java/org/qortal/test/crosschain/litecoinv1/SendRedeemMessage.java index 20386d2a..fd6ad31a 100644 --- a/src/test/java/org/qortal/test/crosschain/litecoinv1/SendRedeemMessage.java +++ b/src/test/java/org/qortal/test/crosschain/litecoinv1/SendRedeemMessage.java @@ -1,5 +1,6 @@ package org.qortal.test.crosschain.litecoinv1; +import com.google.common.hash.HashCode; import org.qortal.account.PrivateKeyAccount; import org.qortal.controller.Controller; import org.qortal.crosschain.LitecoinACCTv1; @@ -16,8 +17,6 @@ import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; -import com.google.common.hash.HashCode; - public class SendRedeemMessage { private static void usage(String error) { diff --git a/src/test/java/org/qortal/test/crosschain/litecoinv1/SendTradeMessage.java b/src/test/java/org/qortal/test/crosschain/litecoinv1/SendTradeMessage.java index 83e9a20e..621ed955 100644 --- a/src/test/java/org/qortal/test/crosschain/litecoinv1/SendTradeMessage.java +++ b/src/test/java/org/qortal/test/crosschain/litecoinv1/SendTradeMessage.java @@ -1,5 +1,6 @@ package org.qortal.test.crosschain.litecoinv1; +import com.google.common.hash.HashCode; import org.qortal.account.PrivateKeyAccount; import org.qortal.controller.Controller; import org.qortal.crosschain.LitecoinACCTv1; @@ -17,8 +18,6 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.NTP; -import com.google.common.hash.HashCode; - public class SendTradeMessage { private static void usage(String error) { diff --git a/src/test/java/org/qortal/test/group/AdminTests.java b/src/test/java/org/qortal/test/group/AdminTests.java index 8cf83c29..db3e3400 100644 --- a/src/test/java/org/qortal/test/group/AdminTests.java +++ b/src/test/java/org/qortal/test/group/AdminTests.java @@ -1,17 +1,10 @@ package org.qortal.test.group; -import static org.junit.Assert.*; - import org.junit.After; import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; -import org.qortal.data.transaction.AddGroupAdminTransactionData; -import org.qortal.data.transaction.CancelGroupBanTransactionData; -import org.qortal.data.transaction.CreateGroupTransactionData; -import org.qortal.data.transaction.GroupBanTransactionData; -import org.qortal.data.transaction.GroupKickTransactionData; -import org.qortal.data.transaction.JoinGroupTransactionData; +import org.qortal.data.transaction.*; import org.qortal.group.Group.ApprovalThreshold; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -22,6 +15,8 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.Transaction.ValidationResult; +import static org.junit.Assert.*; + public class AdminTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/group/DevGroupAdminTests.java b/src/test/java/org/qortal/test/group/DevGroupAdminTests.java index 131359c6..41352323 100644 --- a/src/test/java/org/qortal/test/group/DevGroupAdminTests.java +++ b/src/test/java/org/qortal/test/group/DevGroupAdminTests.java @@ -5,8 +5,6 @@ import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.*; -import org.qortal.group.Group; -import org.qortal.group.Group.ApprovalThreshold; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; @@ -17,7 +15,6 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; -import org.qortal.utils.Base58; import static org.junit.Assert.*; diff --git a/src/test/java/org/qortal/test/group/GroupApprovalTests.java b/src/test/java/org/qortal/test/group/GroupApprovalTests.java index b8b870f5..3d76aa47 100644 --- a/src/test/java/org/qortal/test/group/GroupApprovalTests.java +++ b/src/test/java/org/qortal/test/group/GroupApprovalTests.java @@ -23,10 +23,10 @@ import org.qortal.transaction.Transaction.ApprovalStatus; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.utils.Amounts; -import static org.junit.Assert.*; - import java.util.Arrays; +import static org.junit.Assert.*; + public class GroupApprovalTests extends Common { private static final long amount = 5000L * Amounts.MULTIPLIER; diff --git a/src/test/java/org/qortal/test/group/GroupBlockDelayTests.java b/src/test/java/org/qortal/test/group/GroupBlockDelayTests.java index b4375fe0..95ddb246 100644 --- a/src/test/java/org/qortal/test/group/GroupBlockDelayTests.java +++ b/src/test/java/org/qortal/test/group/GroupBlockDelayTests.java @@ -1,7 +1,5 @@ package org.qortal.test.group; -import static org.junit.Assert.*; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -21,6 +19,9 @@ import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transaction.UpdateGroupTransaction; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + public class GroupBlockDelayTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/group/MiscTests.java b/src/test/java/org/qortal/test/group/MiscTests.java index 481f0b6d..0f32be5c 100644 --- a/src/test/java/org/qortal/test/group/MiscTests.java +++ b/src/test/java/org/qortal/test/group/MiscTests.java @@ -1,7 +1,5 @@ package org.qortal.test.group; -import static org.junit.Assert.*; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -20,6 +18,9 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.Transaction.ValidationResult; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + public class MiscTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/group/OwnerTests.java b/src/test/java/org/qortal/test/group/OwnerTests.java index d4e7494c..7b5af651 100644 --- a/src/test/java/org/qortal/test/group/OwnerTests.java +++ b/src/test/java/org/qortal/test/group/OwnerTests.java @@ -1,7 +1,5 @@ package org.qortal.test.group; -import static org.junit.Assert.*; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -20,6 +18,8 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.Transaction.ValidationResult; +import static org.junit.Assert.*; + public class OwnerTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/minting/BlocksMintedCountTests.java b/src/test/java/org/qortal/test/minting/BlocksMintedCountTests.java index f318a667..65a616b0 100644 --- a/src/test/java/org/qortal/test/minting/BlocksMintedCountTests.java +++ b/src/test/java/org/qortal/test/minting/BlocksMintedCountTests.java @@ -1,8 +1,5 @@ package org.qortal.test.minting; -import static org.junit.Assert.*; - - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -18,6 +15,9 @@ import org.qortal.test.common.BlockUtils; import org.qortal.test.common.Common; import org.qortal.test.common.TestAccount; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + public class BlocksMintedCountTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/minting/DisagreementTests.java b/src/test/java/org/qortal/test/minting/DisagreementTests.java index d32256b7..14e1c370 100644 --- a/src/test/java/org/qortal/test/minting/DisagreementTests.java +++ b/src/test/java/org/qortal/test/minting/DisagreementTests.java @@ -1,11 +1,6 @@ package org.qortal.test.minting; -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - +import io.druid.extendedset.intset.ConciseSet; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -25,7 +20,11 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.transform.block.BlockTransformer; import org.roaringbitmap.IntIterator; -import io.druid.extendedset.intset.ConciseSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; public class DisagreementTests extends Common { diff --git a/src/test/java/org/qortal/test/minting/RewardShareTests.java b/src/test/java/org/qortal/test/minting/RewardShareTests.java index b5ac5e59..2be6cb26 100644 --- a/src/test/java/org/qortal/test/minting/RewardShareTests.java +++ b/src/test/java/org/qortal/test/minting/RewardShareTests.java @@ -1,7 +1,5 @@ package org.qortal.test.minting; -import static org.junit.Assert.*; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -19,6 +17,8 @@ import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.utils.Base58; +import static org.junit.Assert.*; + public class RewardShareTests extends Common { private static final int CANCEL_SHARE_PERCENT = -1; diff --git a/src/test/java/org/qortal/test/minting/RewardTests.java b/src/test/java/org/qortal/test/minting/RewardTests.java index 1689db5b..5ba0b075 100644 --- a/src/test/java/org/qortal/test/minting/RewardTests.java +++ b/src/test/java/org/qortal/test/minting/RewardTests.java @@ -1,10 +1,5 @@ package org.qortal.test.minting; -import static org.junit.Assert.*; - -import java.math.BigInteger; -import java.util.*; - import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -28,6 +23,14 @@ import org.qortal.test.common.TestAccount; import org.qortal.utils.Amounts; import org.qortal.utils.Base58; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.*; + public class RewardTests extends Common { private static final Logger LOGGER = LogManager.getLogger(RewardTests.class); @Before diff --git a/src/test/java/org/qortal/test/naming/BuySellTests.java b/src/test/java/org/qortal/test/naming/BuySellTests.java index f0e97b94..a1c644fc 100644 --- a/src/test/java/org/qortal/test/naming/BuySellTests.java +++ b/src/test/java/org/qortal/test/naming/BuySellTests.java @@ -1,9 +1,5 @@ package org.qortal.test.naming; -import static org.junit.Assert.*; - -import java.util.Random; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -22,7 +18,10 @@ import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.RegisterNameTransaction; import org.qortal.utils.Amounts; -import org.qortal.utils.NTP; + +import java.util.Random; + +import static org.junit.Assert.*; public class BuySellTests extends Common { diff --git a/src/test/java/org/qortal/test/naming/MiscTests.java b/src/test/java/org/qortal/test/naming/MiscTests.java index 401b03b9..324cdf12 100644 --- a/src/test/java/org/qortal/test/naming/MiscTests.java +++ b/src/test/java/org/qortal/test/naming/MiscTests.java @@ -1,24 +1,24 @@ package org.qortal.test.naming; -import static org.junit.Assert.*; - -import java.util.Arrays; -import java.util.List; - import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.api.AmountTypeAdapter; import org.qortal.block.BlockChain; -import org.qortal.block.BlockChain.*; +import org.qortal.block.BlockChain.UnitFeesByTimestamp; import org.qortal.controller.BlockMinter; -import org.qortal.data.transaction.*; +import org.qortal.data.transaction.PaymentTransactionData; +import org.qortal.data.transaction.RegisterNameTransactionData; +import org.qortal.data.transaction.TransactionData; +import org.qortal.data.transaction.UpdateNameTransactionData; import org.qortal.naming.Name; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; -import org.qortal.test.common.*; +import org.qortal.test.common.BlockUtils; +import org.qortal.test.common.Common; +import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.PaymentTransaction; import org.qortal.transaction.RegisterNameTransaction; @@ -26,6 +26,11 @@ import org.qortal.transaction.Transaction; import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.utils.NTP; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; + public class MiscTests extends Common { @Before diff --git a/src/test/java/org/qortal/test/naming/UpdateTests.java b/src/test/java/org/qortal/test/naming/UpdateTests.java index 54227e94..8e54eb96 100644 --- a/src/test/java/org/qortal/test/naming/UpdateTests.java +++ b/src/test/java/org/qortal/test/naming/UpdateTests.java @@ -1,7 +1,5 @@ package org.qortal.test.naming; -import static org.junit.Assert.*; - import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; @@ -17,7 +15,8 @@ import org.qortal.test.common.Common; import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.transaction.TestTransaction; import org.qortal.transaction.RegisterNameTransaction; -import org.qortal.utils.NTP; + +import static org.junit.Assert.*; public class UpdateTests extends Common { diff --git a/src/test/java/org/qortal/test/network/OnlineAccountsTests.java b/src/test/java/org/qortal/test/network/OnlineAccountsTests.java index c8220d66..75625da8 100644 --- a/src/test/java/org/qortal/test/network/OnlineAccountsTests.java +++ b/src/test/java/org/qortal/test/network/OnlineAccountsTests.java @@ -12,26 +12,23 @@ import org.qortal.block.Block; import org.qortal.block.BlockChain; import org.qortal.controller.BlockMinter; import org.qortal.data.network.OnlineAccountData; -import org.qortal.network.message.*; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.settings.Settings; import org.qortal.test.common.AccountUtils; import org.qortal.test.common.Common; -import org.qortal.transform.Transformer; import org.qortal.utils.Base58; import org.qortal.utils.NTP; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.nio.ByteBuffer; import java.security.Security; import java.util.ArrayList; import java.util.List; import java.util.Random; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; public class OnlineAccountsTests extends Common { diff --git a/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java b/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java index 2c3c01ca..3483113d 100644 --- a/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java +++ b/src/test/java/org/qortal/test/network/OnlineAccountsV3Tests.java @@ -2,11 +2,12 @@ package org.qortal.test.network; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; -import org.junit.Ignore; import org.junit.Test; import org.qortal.controller.OnlineAccountsManager; import org.qortal.data.network.OnlineAccountData; -import org.qortal.network.message.*; +import org.qortal.network.message.GetOnlineAccountsV3Message; +import org.qortal.network.message.Message; +import org.qortal.network.message.MessageException; import org.qortal.transform.Transformer; import java.nio.ByteBuffer; diff --git a/src/test/java/org/qortal/test/serialization/SerializationTests.java b/src/test/java/org/qortal/test/serialization/SerializationTests.java index e9767909..e61ba053 100644 --- a/src/test/java/org/qortal/test/serialization/SerializationTests.java +++ b/src/test/java/org/qortal/test/serialization/SerializationTests.java @@ -1,6 +1,8 @@ package org.qortal.test.serialization; -import org.junit.Ignore; +import com.google.common.hash.HashCode; +import io.druid.extendedset.intset.ConciseSet; +import org.junit.Before; import org.junit.Test; import org.qortal.account.PrivateKeyAccount; import org.qortal.data.transaction.TransactionData; @@ -15,12 +17,6 @@ import org.qortal.transform.transaction.TransactionTransformer; import org.qortal.utils.Base58; import org.qortal.utils.Serialization; -import com.google.common.hash.HashCode; - -import io.druid.extendedset.intset.ConciseSet; - -import static org.junit.Assert.*; - import java.io.IOException; import java.math.BigDecimal; import java.nio.ByteBuffer; @@ -28,7 +24,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; -import org.junit.Before; +import static org.junit.Assert.assertEquals; public class SerializationTests extends Common { From d4ef175c4dccf92da927090379102e6a046e28f0 Mon Sep 17 00:00:00 2001 From: kennycud Date: Sat, 4 Nov 2023 14:49:15 -0700 Subject: [PATCH 67/74] Added Address info support for Litecoin --- .../api/model/crosschain/AddressRequest.java | 17 ++++ .../resource/CrossChainLitecoinResource.java | 40 ++++++++ .../org/qortal/crosschain/AddressInfo.java | 78 +++++++++++++++ .../java/org/qortal/crosschain/Bitcoiny.java | 94 +++++++++++++++++++ .../org/qortal/crosschain/PathComparator.java | 29 ++++++ .../qortal/test/crosschain/BitcoinyTests.java | 35 +++++++ .../test/crosschain/BitcoinyTestsUtils.java | 42 +++++++++ 7 files changed, 335 insertions(+) create mode 100644 src/main/java/org/qortal/api/model/crosschain/AddressRequest.java create mode 100644 src/main/java/org/qortal/crosschain/AddressInfo.java create mode 100644 src/main/java/org/qortal/crosschain/PathComparator.java create mode 100644 src/test/java/org/qortal/test/crosschain/BitcoinyTestsUtils.java diff --git a/src/main/java/org/qortal/api/model/crosschain/AddressRequest.java b/src/main/java/org/qortal/api/model/crosschain/AddressRequest.java new file mode 100644 index 00000000..91749863 --- /dev/null +++ b/src/main/java/org/qortal/api/model/crosschain/AddressRequest.java @@ -0,0 +1,17 @@ +package org.qortal.api.model.crosschain; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class AddressRequest { + + @Schema(description = "Litecoin BIP32 extended public key", example = "tpub___________________________________________________________________________________________________________") + public String xpub58; + + public AddressRequest() { + } + +} diff --git a/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java index 3e2ff799..439d19d5 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainLitecoinResource.java @@ -24,7 +24,9 @@ import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; +import org.qortal.api.model.crosschain.AddressRequest; import org.qortal.api.model.crosschain.LitecoinSendRequest; +import org.qortal.crosschain.AddressInfo; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Litecoin; import org.qortal.crosschain.SimpleTransaction; @@ -150,6 +152,44 @@ public class CrossChainLitecoinResource { } } + @POST + @Path("/addressinfos") + @Operation( + summary = "Returns information for each address for a hierarchical, deterministic BIP32 wallet", + description = "Supply BIP32 'm' private/public key in base58, starting with 'xprv'/'xpub' for mainnet, 'tprv'/'tpub' for testnet", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.APPLICATION_JSON, + schema = @Schema( + implementation = AddressRequest.class + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = AddressInfo.class ) ) ) + ) + } + + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public List getLitecoinAddressInfos(@HeaderParam(Security.API_KEY_HEADER) String apiKey, AddressRequest addressRequest) { + Security.checkApiCallAllowed(request); + + Litecoin litecoin = Litecoin.getInstance(); + + if (!litecoin.isValidDeterministicKey(addressRequest.xpub58)) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PRIVATE_KEY); + + try { + return litecoin.getWalletAddressInfos(addressRequest.xpub58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE); + } + } + @POST @Path("/unusedaddress") @Operation( diff --git a/src/main/java/org/qortal/crosschain/AddressInfo.java b/src/main/java/org/qortal/crosschain/AddressInfo.java new file mode 100644 index 00000000..d1226d5a --- /dev/null +++ b/src/main/java/org/qortal/crosschain/AddressInfo.java @@ -0,0 +1,78 @@ +package org.qortal.crosschain; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.util.List; +import java.util.Objects; + +/** + * Class AddressInfo + */ +@XmlAccessorType(XmlAccessType.FIELD) +public class AddressInfo { + + private String address; + + private List path; + + private long value; + + private String pathAsString; + + private int transactionCount; + + public AddressInfo() { + } + + public AddressInfo(String address, List path, long value, String pathAsString, int transactionCount) { + this.address = address; + this.path = path; + this.value = value; + this.pathAsString = pathAsString; + this.transactionCount = transactionCount; + } + + public String getAddress() { + return address; + } + + public List getPath() { + return path; + } + + public long getValue() { + return value; + } + + public String getPathAsString() { + return pathAsString; + } + + public int getTransactionCount() { + return transactionCount; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AddressInfo that = (AddressInfo) o; + return value == that.value && transactionCount == that.transactionCount && Objects.equals(address, that.address) && Objects.equals(path, that.path) && Objects.equals(pathAsString, that.pathAsString); + } + + @Override + public int hashCode() { + return Objects.hash(address, path, value, pathAsString, transactionCount); + } + + @Override + public String toString() { + return "AddressInfo{" + + "address='" + address + '\'' + + ", path=" + path + + ", value=" + value + + ", pathAsString='" + pathAsString + '\'' + + ", transactionCount=" + transactionCount + + '}'; + } +} diff --git a/src/main/java/org/qortal/crosschain/Bitcoiny.java b/src/main/java/org/qortal/crosschain/Bitcoiny.java index d1523b50..cf727953 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoiny.java +++ b/src/main/java/org/qortal/crosschain/Bitcoiny.java @@ -3,6 +3,7 @@ package org.qortal.crosschain; import java.util.*; import java.util.stream.Collectors; +import com.google.common.collect.ImmutableList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bitcoinj.core.Address; @@ -488,6 +489,37 @@ public abstract class Bitcoiny implements ForeignBlockchain { } } + public List getWalletAddressInfos(String key58) throws ForeignBlockchainException { + List infos = new ArrayList<>(); + + for(DeterministicKey key : getWalletKeys(key58)) { + infos.add(buildAddressInfo(key)); + } + + return infos.stream() + .sorted(new PathComparator(1)) + .collect(Collectors.toList()); + } + + public AddressInfo buildAddressInfo(DeterministicKey key) throws ForeignBlockchainException { + + Address address = Address.fromKey(this.params, key, ScriptType.P2PKH); + + int transactionCount = getAddressTransactions(ScriptBuilder.createOutputScript(address).getProgram(), true).size(); + + return new AddressInfo( + address.toString(), + toIntegerList( key.getPath()), + summingUnspentOutputs(address.toString()), + key.getPathAsString(), + transactionCount); + } + + private static List toIntegerList(ImmutableList path) { + + return path.stream().map(ChildNumber::num).collect(Collectors.toList()); + } + public Set getWalletAddresses(String key58) throws ForeignBlockchainException { synchronized (this) { Context.propagate(bitcoinjContext); @@ -546,6 +578,61 @@ public abstract class Bitcoiny implements ForeignBlockchain { } } + private List getWalletKeys(String key58) throws ForeignBlockchainException { + synchronized (this) { + Context.propagate(bitcoinjContext); + + Wallet wallet = walletFromDeterministicKey58(key58); + DeterministicKeyChain keyChain = wallet.getActiveKeyChain(); + + keyChain.setLookaheadSize(Bitcoiny.WALLET_KEY_LOOKAHEAD_INCREMENT); + keyChain.maybeLookAhead(); + + List keys = new ArrayList<>(keyChain.getLeafKeys()); + + int unusedCounter = 0; + int ki = 0; + do { + boolean areAllKeysUnused = true; + + for (; ki < keys.size(); ++ki) { + DeterministicKey dKey = keys.get(ki); + + // Check for transactions + Address address = Address.fromKey(this.params, dKey, ScriptType.P2PKH); + byte[] script = ScriptBuilder.createOutputScript(address).getProgram(); + + // Ask for transaction history - if it's empty then key has never been used + List historicTransactionHashes = this.getAddressTransactions(script, false); + + if (!historicTransactionHashes.isEmpty()) { + areAllKeysUnused = false; + } + } + + if (areAllKeysUnused) { + // No transactions + if (unusedCounter >= Settings.getInstance().getGapLimit()) { + // ... and we've hit our search limit + break; + } + // We haven't hit our search limit yet so increment the counter and keep looking + unusedCounter += WALLET_KEY_LOOKAHEAD_INCREMENT; + } else { + // Some keys in this batch were used, so reset the counter + unusedCounter = 0; + } + + // Generate some more keys + keys.addAll(generateMoreKeys(keyChain)); + + // Process new keys + } while (true); + + return keys; + } + } + protected SimpleTransaction convertToSimpleTransaction(BitcoinyTransaction t, Set keySet) { long amount = 0; long total = 0L; @@ -818,6 +905,13 @@ public abstract class Bitcoiny implements ForeignBlockchain { } } + private Long summingUnspentOutputs(String walletAddress) throws ForeignBlockchainException { + return this.getUnspentOutputs(walletAddress).stream() + .map(TransactionOutput::getValue) + .mapToLong(Coin::longValue) + .sum(); + } + // Utility methods for others public static List simplifyWalletTransactions(List transactions) { diff --git a/src/main/java/org/qortal/crosschain/PathComparator.java b/src/main/java/org/qortal/crosschain/PathComparator.java new file mode 100644 index 00000000..7226b09e --- /dev/null +++ b/src/main/java/org/qortal/crosschain/PathComparator.java @@ -0,0 +1,29 @@ +package org.qortal.crosschain; + +/** + * Class PathComparator + */ +public class PathComparator implements java.util.Comparator { + + private int max; + + public PathComparator(int max) { + this.max = max; + } + + @Override + public int compare(AddressInfo info1, AddressInfo info2) { + return compareAtLevel(info1, info2, 0); + } + + private int compareAtLevel(AddressInfo info1, AddressInfo info2, int level) { + + if( level < 0 ) return 0; + + int compareTo = info1.getPath().get(level).compareTo(info2.getPath().get(level)); + + if(compareTo != 0 || level == max) return compareTo; + + return compareAtLevel(info1, info2,level + 1); + } +} diff --git a/src/test/java/org/qortal/test/crosschain/BitcoinyTests.java b/src/test/java/org/qortal/test/crosschain/BitcoinyTests.java index b29fffd4..12e33767 100644 --- a/src/test/java/org/qortal/test/crosschain/BitcoinyTests.java +++ b/src/test/java/org/qortal/test/crosschain/BitcoinyTests.java @@ -4,6 +4,7 @@ import org.bitcoinj.core.Transaction; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.qortal.crosschain.AddressInfo; import org.qortal.crosschain.Bitcoiny; import org.qortal.crosschain.BitcoinyHTLC; import org.qortal.crosschain.ForeignBlockchainException; @@ -11,6 +12,8 @@ import org.qortal.repository.DataException; import org.qortal.test.common.Common; import java.util.Arrays; +import java.util.List; +import java.util.Set; import static org.junit.Assert.*; @@ -127,4 +130,36 @@ public abstract class BitcoinyTests extends Common { System.out.println(address); } + @Test + public void testGenerateRootKeyForTesting() { + + String rootKey = BitcoinyTestsUtils.generateBip32RootKey( this.bitcoiny.getNetworkParameters() ); + + System.out.println(String.format(getCoinName() + " generated BIP32 Root Key: " + rootKey)); + + } + + @Test + public void testGetWalletAddresses() throws ForeignBlockchainException { + + String xprv58 = getDeterministicKey58(); + + Set addresses = this.bitcoiny.getWalletAddresses(xprv58); + + System.out.println( "root key = " + xprv58 ); + System.out.println( "keys ..."); + addresses.stream().forEach(System.out::println); + } + + @Test + public void testWalletAddressInfos() throws ForeignBlockchainException { + + String xprv58 = getDeterministicKey58(); + + List addressInfos = this.bitcoiny.getWalletAddressInfos(xprv58); + + System.out.println("address count = " + addressInfos.size() ); + System.out.println( "address infos ..." ); + addressInfos.forEach( System.out::println ); + } } diff --git a/src/test/java/org/qortal/test/crosschain/BitcoinyTestsUtils.java b/src/test/java/org/qortal/test/crosschain/BitcoinyTestsUtils.java new file mode 100644 index 00000000..a11b5b2f --- /dev/null +++ b/src/test/java/org/qortal/test/crosschain/BitcoinyTestsUtils.java @@ -0,0 +1,42 @@ +package org.qortal.test.crosschain; + +import com.google.common.collect.ImmutableList; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.crypto.ChildNumber; +import org.bitcoinj.crypto.DeterministicKey; +import org.bitcoinj.script.Script; +import org.bitcoinj.wallet.DeterministicKeyChain; +import org.bitcoinj.wallet.DeterministicSeed; +import org.bitcoinj.wallet.Wallet; +import org.qortal.crosschain.ForeignBlockchainException; +import org.qortal.crosschain.Litecoin; +import org.qortal.repository.DataException; +import org.qortal.test.common.Common; + +public class BitcoinyTestsUtils { + + public static void main(String[] args) throws DataException, ForeignBlockchainException { + + Common.useDefaultSettings(); + + final String rootKey = generateBip32RootKey( Litecoin.LitecoinNet.TEST3.getParams()); + String address = Litecoin.getInstance().getUnusedReceiveAddress(rootKey); + + System.out.println("rootKey = " + rootKey); + System.out.println("address = " + address); + + System.exit(0); + } + + public static String generateBip32RootKey(NetworkParameters networkParameters) { + + final Wallet wallet = Wallet.createDeterministic(networkParameters, Script.ScriptType.P2PKH); + final DeterministicSeed seed = wallet.getKeyChainSeed(); + final DeterministicKeyChain keyChain = DeterministicKeyChain.builder().seed(seed).build(); + final ImmutableList path = keyChain.getAccountPath(); + final DeterministicKey parent = keyChain.getKeyByPath(path, true); + final String rootKey = parent.serializePrivB58(networkParameters); + + return rootKey; + } +} \ No newline at end of file From 0d64e809c78560760a88d9a0fff2e02f7db106ec Mon Sep 17 00:00:00 2001 From: kennycud Date: Sat, 4 Nov 2023 15:26:42 -0700 Subject: [PATCH 68/74] Ignoring test cases intended for Bitcoiny coins --- .../org/qortal/test/crosschain/PirateChainTests.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/org/qortal/test/crosschain/PirateChainTests.java b/src/test/java/org/qortal/test/crosschain/PirateChainTests.java index b212aea1..261b45b2 100644 --- a/src/test/java/org/qortal/test/crosschain/PirateChainTests.java +++ b/src/test/java/org/qortal/test/crosschain/PirateChainTests.java @@ -11,6 +11,7 @@ import org.qortal.crypto.Crypto; import org.qortal.transform.TransformationException; import java.util.List; +import java.util.Set; import static org.junit.Assert.*; import static org.qortal.crosschain.BitcoinyHTLC.Status.*; @@ -241,4 +242,12 @@ public class PirateChainTests extends BitcoinyTests { @Test @Ignore(value = "Needs adapting for Pirate Chain") public void testGetUnusedReceiveAddress() {} + + @Test + @Ignore(value = "Needs adapting for Pirate Chain") + public void testGetWalletAddresses() throws ForeignBlockchainException {} + + @Test + @Ignore(value = "Needs adapting for Pirate Chain") + public void testWalletAddressInfos() throws ForeignBlockchainException {} } \ No newline at end of file From 975b0a5f3deca8a2c0459f9b4ed016a44c1a1442 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 5 Nov 2023 19:15:16 +0100 Subject: [PATCH 69/74] Bump version 4.3.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0c1cad7c..f1973689 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.qortal qortal - 4.3.1 + 4.3.2 jar true From d915dc10f3a0d6634dbb245beba2d5be2e023ae9 Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Mon, 6 Nov 2023 13:03:21 -0500 Subject: [PATCH 70/74] Default minPeerVersion set to 4.3.2 --- src/main/java/org/qortal/settings/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index fc8ba4ce..d7b28fb5 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -221,7 +221,7 @@ public class Settings { public long recoveryModeTimeout = 9999999999999L; /** Minimum peer version number required in order to sync with them */ - private String minPeerVersion = "4.3.1"; + private String minPeerVersion = "4.3.2"; /** Whether to allow connections with peers below minPeerVersion * If true, we won't sync with them but they can still sync with us, and will show in the peers list * If false, sync will be blocked both ways, and they will not appear in the peers list */ From b05c0158b1d2c305768b4cd821d0b9e1c7f7fc4f Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Mon, 6 Nov 2023 14:23:49 -0500 Subject: [PATCH 71/74] Resolve temporary conflict --- .../java/org/qortal/crosschain/Bitcoiny.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/qortal/crosschain/Bitcoiny.java b/src/main/java/org/qortal/crosschain/Bitcoiny.java index db901395..96b25c21 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoiny.java +++ b/src/main/java/org/qortal/crosschain/Bitcoiny.java @@ -1,9 +1,25 @@ package org.qortal.crosschain; -import com.google.common.hash.HashCode; +import java.util.*; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bitcoinj.core.*; +import org.bitcoinj.core.Address; +import org.bitcoinj.core.AddressFormatException; +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.Context; +import org.bitcoinj.core.ECKey; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.LegacyAddress; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.Sha256Hash; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionOutput; +import org.bitcoinj.core.UTXO; +import org.bitcoinj.core.UTXOProvider; +import org.bitcoinj.core.UTXOProviderException; import org.bitcoinj.crypto.ChildNumber; import org.bitcoinj.crypto.DeterministicHierarchy; import org.bitcoinj.crypto.DeterministicKey; @@ -17,10 +33,9 @@ import org.qortal.crypto.Crypto; import org.qortal.settings.Settings; import org.qortal.utils.Amounts; import org.qortal.utils.BitTwiddling; -import org.qortal.utils.NTP; -import java.util.*; -import java.util.stream.Collectors; +import com.google.common.hash.HashCode; +import org.qortal.utils.NTP; /** Bitcoin-like (Bitcoin, Litecoin, etc.) support */ public abstract class Bitcoiny implements ForeignBlockchain { From 3a723ed1162db170d329927669695d3602d582d2 Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Mon, 6 Nov 2023 14:29:35 -0500 Subject: [PATCH 72/74] Revert temporary change --- .../java/org/qortal/crosschain/Bitcoiny.java | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/qortal/crosschain/Bitcoiny.java b/src/main/java/org/qortal/crosschain/Bitcoiny.java index cf727953..cac37d64 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoiny.java +++ b/src/main/java/org/qortal/crosschain/Bitcoiny.java @@ -1,25 +1,10 @@ package org.qortal.crosschain; -import java.util.*; -import java.util.stream.Collectors; - import com.google.common.collect.ImmutableList; +import com.google.common.hash.HashCode; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bitcoinj.core.Address; -import org.bitcoinj.core.AddressFormatException; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.Context; -import org.bitcoinj.core.ECKey; -import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.LegacyAddress; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Sha256Hash; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; -import org.bitcoinj.core.UTXO; -import org.bitcoinj.core.UTXOProvider; -import org.bitcoinj.core.UTXOProviderException; +import org.bitcoinj.core.*; import org.bitcoinj.crypto.ChildNumber; import org.bitcoinj.crypto.DeterministicHierarchy; import org.bitcoinj.crypto.DeterministicKey; @@ -33,10 +18,11 @@ import org.qortal.crypto.Crypto; import org.qortal.settings.Settings; import org.qortal.utils.Amounts; import org.qortal.utils.BitTwiddling; - -import com.google.common.hash.HashCode; import org.qortal.utils.NTP; +import java.util.*; +import java.util.stream.Collectors; + /** Bitcoin-like (Bitcoin, Litecoin, etc.) support */ public abstract class Bitcoiny implements ForeignBlockchain { From 183dac5ac48c06487c80d02187f377bee4feb221 Mon Sep 17 00:00:00 2001 From: QuickMythril Date: Mon, 6 Nov 2023 15:11:55 -0500 Subject: [PATCH 73/74] Add address infos for BTC, DOGE, DGB, RVN --- .../resource/CrossChainBitcoinResource.java | 40 +++++++++++++++++++ .../resource/CrossChainDigibyteResource.java | 40 +++++++++++++++++++ .../resource/CrossChainDogecoinResource.java | 40 +++++++++++++++++++ .../resource/CrossChainRavencoinResource.java | 40 +++++++++++++++++++ 4 files changed, 160 insertions(+) diff --git a/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java index efefd4c9..88cd622d 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainBitcoinResource.java @@ -13,7 +13,9 @@ import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; +import org.qortal.api.model.crosschain.AddressRequest; import org.qortal.api.model.crosschain.BitcoinSendRequest; +import org.qortal.crosschain.AddressInfo; import org.qortal.crosschain.Bitcoin; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.SimpleTransaction; @@ -148,6 +150,44 @@ public class CrossChainBitcoinResource { } } + @POST + @Path("/addressinfos") + @Operation( + summary = "Returns information for each address for a hierarchical, deterministic BIP32 wallet", + description = "Supply BIP32 'm' private/public key in base58, starting with 'xprv'/'xpub' for mainnet, 'tprv'/'tpub' for testnet", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.APPLICATION_JSON, + schema = @Schema( + implementation = AddressRequest.class + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = AddressInfo.class ) ) ) + ) + } + + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public List getBitcoinAddressInfos(@HeaderParam(Security.API_KEY_HEADER) String apiKey, AddressRequest addressRequest) { + Security.checkApiCallAllowed(request); + + Bitcoin bitcoin = Bitcoin.getInstance(); + + if (!bitcoin.isValidDeterministicKey(addressRequest.xpub58)) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PRIVATE_KEY); + + try { + return bitcoin.getWalletAddressInfos(addressRequest.xpub58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE); + } + } + @POST @Path("/unusedaddress") @Operation( diff --git a/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java b/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java index 60a4aa0d..3ab944ab 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainDigibyteResource.java @@ -13,7 +13,9 @@ import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; +import org.qortal.api.model.crosschain.AddressRequest; import org.qortal.api.model.crosschain.DigibyteSendRequest; +import org.qortal.crosschain.AddressInfo; import org.qortal.crosschain.Digibyte; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.SimpleTransaction; @@ -148,6 +150,44 @@ public class CrossChainDigibyteResource { } } + @POST + @Path("/addressinfos") + @Operation( + summary = "Returns information for each address for a hierarchical, deterministic BIP32 wallet", + description = "Supply BIP32 'm' private/public key in base58, starting with 'xprv'/'xpub' for mainnet, 'tprv'/'tpub' for testnet", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.APPLICATION_JSON, + schema = @Schema( + implementation = AddressRequest.class + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = AddressInfo.class ) ) ) + ) + } + + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public List getDigibyteAddressInfos(@HeaderParam(Security.API_KEY_HEADER) String apiKey, AddressRequest addressRequest) { + Security.checkApiCallAllowed(request); + + Digibyte digibyte = Digibyte.getInstance(); + + if (!digibyte.isValidDeterministicKey(addressRequest.xpub58)) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PRIVATE_KEY); + + try { + return digibyte.getWalletAddressInfos(addressRequest.xpub58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE); + } + } + @POST @Path("/unusedaddress") @Operation( diff --git a/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java index 3c04b0e8..b66b5716 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainDogecoinResource.java @@ -13,7 +13,9 @@ import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; +import org.qortal.api.model.crosschain.AddressRequest; import org.qortal.api.model.crosschain.DogecoinSendRequest; +import org.qortal.crosschain.AddressInfo; import org.qortal.crosschain.Dogecoin; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.SimpleTransaction; @@ -148,6 +150,44 @@ public class CrossChainDogecoinResource { } } + @POST + @Path("/addressinfos") + @Operation( + summary = "Returns information for each address for a hierarchical, deterministic BIP32 wallet", + description = "Supply BIP32 'm' private/public key in base58, starting with 'xprv'/'xpub' for mainnet, 'tprv'/'tpub' for testnet", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.APPLICATION_JSON, + schema = @Schema( + implementation = AddressRequest.class + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = AddressInfo.class ) ) ) + ) + } + + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public List getDogecoinAddressInfos(@HeaderParam(Security.API_KEY_HEADER) String apiKey, AddressRequest addressRequest) { + Security.checkApiCallAllowed(request); + + Dogecoin dogecoin = Dogecoin.getInstance(); + + if (!dogecoin.isValidDeterministicKey(addressRequest.xpub58)) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PRIVATE_KEY); + + try { + return dogecoin.getWalletAddressInfos(addressRequest.xpub58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE); + } + } + @POST @Path("/unusedaddress") @Operation( diff --git a/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java b/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java index fc66ba8c..4d3f204d 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainRavencoinResource.java @@ -13,7 +13,9 @@ import org.qortal.api.ApiError; import org.qortal.api.ApiErrors; import org.qortal.api.ApiExceptionFactory; import org.qortal.api.Security; +import org.qortal.api.model.crosschain.AddressRequest; import org.qortal.api.model.crosschain.RavencoinSendRequest; +import org.qortal.crosschain.AddressInfo; import org.qortal.crosschain.ForeignBlockchainException; import org.qortal.crosschain.Ravencoin; import org.qortal.crosschain.SimpleTransaction; @@ -148,6 +150,44 @@ public class CrossChainRavencoinResource { } } + @POST + @Path("/addressinfos") + @Operation( + summary = "Returns information for each address for a hierarchical, deterministic BIP32 wallet", + description = "Supply BIP32 'm' private/public key in base58, starting with 'xprv'/'xpub' for mainnet, 'tprv'/'tpub' for testnet", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.APPLICATION_JSON, + schema = @Schema( + implementation = AddressRequest.class + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = AddressInfo.class ) ) ) + ) + } + + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public List getRavencoinAddressInfos(@HeaderParam(Security.API_KEY_HEADER) String apiKey, AddressRequest addressRequest) { + Security.checkApiCallAllowed(request); + + Ravencoin ravencoin = Ravencoin.getInstance(); + + if (!ravencoin.isValidDeterministicKey(addressRequest.xpub58)) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PRIVATE_KEY); + + try { + return ravencoin.getWalletAddressInfos(addressRequest.xpub58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE); + } + } + @POST @Path("/unusedaddress") @Operation( From 6c4ed2496d73ab55140db455b3d88937a3397105 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:29:19 +0100 Subject: [PATCH 74/74] Added 2 PirateChain api endpoints --- pom.xml | 4 +- .../CrossChainPirateChainResource.java | 71 +++++++++++++++++++ .../org/qortal/crosschain/PirateChain.java | 24 +++++++ .../org/qortal/crosschain/PirateWallet.java | 19 +++++ 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f1973689..e0e3f90c 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 3.4.0 ${maven.build.timestamp} 1.4.1 - 3.10.0 + 3.8.0 1.11.0 2.11.0 1.24.0 @@ -43,7 +43,7 @@ 3.3.0 3.3.1 3.5.1 - 3.2.1 + 3.2.2 1.1.0 UTF-8 3.24.4 diff --git a/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java b/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java index 550b86b9..7f2e8402 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java @@ -222,6 +222,77 @@ public class CrossChainPirateChainResource { } } + @POST + @Path("/walletprivatekey") + @Operation( + summary = "Returns main wallet private key", + description = "Supply 32 bytes of entropy, Base58 encoded", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", description = "Private Key String")) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public String getPirateChainPrivateKey(@HeaderParam(Security.API_KEY_HEADER) String apiKey, String entropy58) { + Security.checkApiCallAllowed(request); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + return pirateChain.getPrivateKey(entropy58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } + + @POST + @Path("/walletseedphrase") + @Operation( + summary = "Returns main wallet seedphrase", + description = "Supply 32 bytes of entropy, Base58 encoded", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", description = "Wallet Seedphrase String")) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public String getPirateChainWalletSeed(@HeaderParam(Security.API_KEY_HEADER) String apiKey, String entropy58) { + Security.checkApiCallAllowed(request); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + return pirateChain.getWalletSeed(entropy58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } @POST @Path("/syncstatus") diff --git a/src/main/java/org/qortal/crosschain/PirateChain.java b/src/main/java/org/qortal/crosschain/PirateChain.java index 403d90e5..6587baca 100644 --- a/src/main/java/org/qortal/crosschain/PirateChain.java +++ b/src/main/java/org/qortal/crosschain/PirateChain.java @@ -356,6 +356,30 @@ public class PirateChain extends Bitcoiny { } } + public String getPrivateKey(String entropy58) throws ForeignBlockchainException { + synchronized (this) { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + walletController.ensureInitialized(); + walletController.ensureNotNullSeed(); + walletController.getCurrentWallet().unlock(); + + return walletController.getCurrentWallet().getPrivateKey(); + } + } + + public String getWalletSeed(String entropy58) throws ForeignBlockchainException { + synchronized (this) { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + walletController.ensureInitialized(); + walletController.ensureNotNullSeed(); + walletController.getCurrentWallet().unlock(); + + return walletController.getCurrentWallet().getWalletSeed(entropy58); + } + } + public String getUnusedReceiveAddress(String key58) throws ForeignBlockchainException { // For now, return the main wallet address // FUTURE: generate an unused one diff --git a/src/main/java/org/qortal/crosschain/PirateWallet.java b/src/main/java/org/qortal/crosschain/PirateWallet.java index 4b95d3cc..d8fdc351 100644 --- a/src/main/java/org/qortal/crosschain/PirateWallet.java +++ b/src/main/java/org/qortal/crosschain/PirateWallet.java @@ -398,6 +398,25 @@ public class PirateWallet { return null; } + public String getWalletSeed(String entropy58) { + // Decode entropy to bytes + byte[] myEntropyBytes = Base58.decode(entropy58); + + // Pirate library uses base64 encoding + String myEntropy64 = Base64.toBase64String(myEntropyBytes); + + // Derive seed phrase from entropy bytes + String mySeedResponse = LiteWalletJni.getseedphrasefromentropyb64(myEntropy64); + JSONObject mySeedJson = new JSONObject(mySeedResponse); + String mySeedPhrase = null; + if (mySeedJson.has("seedPhrase")) { + mySeedPhrase = mySeedJson.getString("seedPhrase"); + + return mySeedPhrase; + } + return null; + } + public PirateLightClient.Server getRandomServer() { PirateChain.PirateChainNet pirateChainNet = Settings.getInstance().getPirateChainNet(); Collection servers = pirateChainNet.getServers();