From 878394535e96d50f5bd67f03420f1f28f22c7d0b Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 26 Feb 2022 16:10:26 +0000 Subject: [PATCH] Improvements relating to fetching metadata - Rate limiter is disabled when using the API - fetchArbitraryMetadata() returns the actual metadata content rather than a boolean - Exceptions are thrown on certain errors, rather than returning null --- .../api/resource/ArbitraryResource.java | 12 ++++--- .../arbitrary/ArbitraryMetadataManager.java | 31 +++++++++++++------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 7d331074..8fc45c99 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -688,12 +688,16 @@ public class ArbitraryResource { ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - byte[] metadata = ArbitraryMetadataManager.getInstance().fetchMetadata(resource); - if (metadata != null) { - return new String(metadata, StandardCharsets.UTF_8); + try { + byte[] metadata = ArbitraryMetadataManager.getInstance().fetchMetadata(resource, false); + if (metadata != null) { + return new String(metadata, StandardCharsets.UTF_8); + } + } catch (IllegalArgumentException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, e.getMessage()); } - return null; + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA); } diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java index 2cad0cc2..b2b36355 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryMetadataManager.java @@ -75,7 +75,7 @@ public class ArbitraryMetadataManager { } - public byte[] fetchMetadata(ArbitraryDataResource arbitraryDataResource) { + public byte[] fetchMetadata(ArbitraryDataResource arbitraryDataResource, boolean useRateLimiter) { try (final Repository repository = RepositoryManager.getRepository()) { // Find latest transaction ArbitraryTransactionData latestTransaction = repository.getArbitraryRepository() @@ -87,7 +87,7 @@ public class ArbitraryMetadataManager { byte[] metadataHash = latestTransaction.getMetadataHash(); if (metadataHash == null) { // This resource doesn't have metadata - return null; + throw new IllegalArgumentException("This resource doesn't have metadata"); } ArbitraryDataFile metadataFile = ArbitraryDataFile.fromHash(metadataHash, signature); @@ -97,7 +97,7 @@ public class ArbitraryMetadataManager { } else { // Request from network - this.fetchArbitraryMetadata(latestTransaction); + return this.fetchArbitraryMetadata(latestTransaction, useRateLimiter); } } @@ -111,20 +111,25 @@ public class ArbitraryMetadataManager { // Request metadata from network - public boolean fetchArbitraryMetadata(ArbitraryTransactionData arbitraryTransactionData) { + public byte[] fetchArbitraryMetadata(ArbitraryTransactionData arbitraryTransactionData, boolean useRateLimiter) { + byte[] metadataHash = arbitraryTransactionData.getMetadataHash(); + if (metadataHash == null) { + return null; + } + byte[] signature = arbitraryTransactionData.getSignature(); String signature58 = Base58.encode(signature); // Require an NTP sync Long now = NTP.getTime(); if (now == null) { - return false; + return null; } // If we've already tried too many times in a short space of time, make sure to give up - if (!this.shouldMakeMetadataRequestForSignature(signature58)) { + if (useRateLimiter && !this.shouldMakeMetadataRequestForSignature(signature58)) { LOGGER.trace("Skipping metadata request for signature {} due to rate limit", signature58); - return false; + return null; } this.addToSignatureRequests(signature58, true, false); @@ -162,14 +167,22 @@ public class ArbitraryMetadataManager { requestEntry = arbitraryMetadataRequests.get(id); if (requestEntry == null) - return false; + return null; if (requestEntry.getA() == null) break; totalWait += singleWait; } - return true; + + try { + ArbitraryDataFile metadataFile = ArbitraryDataFile.fromHash(metadataHash, signature); + return metadataFile.getBytes(); + } catch (DataException e) { + // Do nothing + } + + return null; }