From e4238a62c92594c42a6ef113d5df98a52aaacdcc Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 13 Feb 2022 19:21:16 +0000 Subject: [PATCH] Exclude metadata-only transactions in the data management page (but added an API parameter to allow them to optionally be included). This ensures that the list will only show resources where there is at least 1 chunk. --- .../api/resource/ArbitraryResource.java | 10 +++++---- .../arbitrary/ArbitraryDataManager.java | 2 +- .../ArbitraryDataStorageManager.java | 22 ++++++++++++++++--- 3 files changed, 26 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 172f21f0..d6dae046 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -430,12 +430,13 @@ public class ArbitraryResource { @ApiErrors({ApiError.REPOSITORY_ISSUE}) public List getHostedTransactions(@HeaderParam(Security.API_KEY_HEADER) String apiKey, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, - @Parameter(ref = "offset") @QueryParam("offset") Integer offset) { + @Parameter(ref = "offset") @QueryParam("offset") Integer offset, + @QueryParam("includemetadata") Boolean includeMetadata) { Security.checkApiCallAllowed(request); try (final Repository repository = RepositoryManager.getRepository()) { - List hostedTransactions = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, limit, offset); + List hostedTransactions = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, limit, offset, includeMetadata); return hostedTransactions; @@ -459,14 +460,15 @@ public class ArbitraryResource { @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) { + @Parameter(ref = "offset") @QueryParam("offset") Integer offset, + @QueryParam("includemetadata") Boolean includeMetadata) { Security.checkApiCallAllowed(request); List resources = new ArrayList<>(); try (final Repository repository = RepositoryManager.getRepository()) { - List transactionDataList = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, limit, offset); + List transactionDataList = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, limit, offset, includeMetadata); for (ArbitraryTransactionData transactionData : transactionDataList) { ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo(); arbitraryResourceInfo.name = transactionData.getName(); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java index f2ceb95a..ee67e435 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java @@ -370,7 +370,7 @@ public class ArbitraryDataManager extends Thread { public void broadcastHostedSignatureList() { try (final Repository repository = RepositoryManager.getRepository()) { - List hostedTransactions = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, null, null); + List hostedTransactions = ArbitraryDataStorageManager.getInstance().listAllHostedTransactions(repository, null, null, false); List hostedSignatures = hostedTransactions.stream().map(ArbitraryTransactionData::getSignature).collect(Collectors.toList()); if (!hostedSignatures.isEmpty()) { // Broadcast the list, using null to represent our peer address diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataStorageManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataStorageManager.java index 16aac458..76290dc0 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataStorageManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataStorageManager.java @@ -259,7 +259,7 @@ public class ArbitraryDataStorageManager extends Thread { // Hosted data - public List listAllHostedTransactions(Repository repository, Integer limit, Integer offset) { + public List listAllHostedTransactions(Repository repository, Integer limit, Integer offset, boolean includeMetadataOnly) { // Load from cache if we can, to avoid disk reads if (this.hostedTransactions != null) { return ArbitraryTransactionUtils.limitOffsetTransactions(this.hostedTransactions, limit, offset); @@ -285,7 +285,23 @@ public class ArbitraryDataStorageManager extends Thread { if (transactionData == null || transactionData.getType() != Transaction.TransactionType.ARBITRARY) { continue; } - arbitraryTransactionDataList.add((ArbitraryTransactionData) transactionData); + ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) transactionData; + + // Make sure to exclude metadata-only resources if requested + if (!includeMetadataOnly) { + if (arbitraryTransactionData.getMetadataHash() != null) { + if (contents.length == 1) { + String metadataHash58 = Base58.encode(arbitraryTransactionData.getMetadataHash()); + if (Objects.equals(metadataHash58, contents[0])) { + // We only have the metadata file for this resource, not the actual data, so exclude it + continue; + } + } + } + } + + // Found some data matching a transaction, so add it to the list + arbitraryTransactionDataList.add(arbitraryTransactionData); } catch (DataException e) { continue; @@ -451,7 +467,7 @@ public class ArbitraryDataStorageManager extends Thread { long maxStoragePerName = this.storageCapacityPerName(threshold); // Fetch all hosted transactions - List hostedTransactions = this.listAllHostedTransactions(repository, null, null); + List hostedTransactions = this.listAllHostedTransactions(repository, null, null, true); for (ArbitraryTransactionData transactionData : hostedTransactions) { String transactionName = transactionData.getName(); if (!Objects.equals(name, transactionName)) {