diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/AutoTransactionLogBloomCachingService.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/AutoTransactionLogBloomCachingService.java index ed7b84fc655..a500720a32d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/AutoTransactionLogBloomCachingService.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/AutoTransactionLogBloomCachingService.java @@ -20,6 +20,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.Duration; +import java.util.Optional; import java.util.OptionalLong; import org.apache.logging.log4j.LogManager; @@ -51,13 +52,15 @@ public void start() { (event, __) -> { if (event.isNewCanonicalHead()) { transactionLogBloomCacher.cacheLogsBloomForBlockHeader( - event.getBlock().getHeader()); + event.getBlock().getHeader(), Optional.empty(), true); } })); chainReorgSubscriptionId = OptionalLong.of( blockchain.observeChainReorg( - (header, __) -> transactionLogBloomCacher.cacheLogsBloomForBlockHeader(header))); + (header, __) -> + transactionLogBloomCacher.cacheLogsBloomForBlockHeader( + header, Optional.empty(), true))); transactionLogBloomCacher .getScheduler() diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/TransactionLogBloomCacher.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/TransactionLogBloomCacher.java index e72d274fca8..4148ea61331 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/TransactionLogBloomCacher.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/TransactionLogBloomCacher.java @@ -30,7 +30,6 @@ import java.io.RandomAccessFile; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.time.Duration; import java.util.Map; import java.util.Optional; @@ -49,7 +48,6 @@ public class TransactionLogBloomCacher { public static final int BLOCKS_PER_BLOOM_CACHE = 100_000; private static final int BLOOM_BITS_LENGTH = 256; - public static final String PENDING = "pending"; private final Map cachedSegments; private final Lock submissionLock = new ReentrantLock(); @@ -95,22 +93,16 @@ public CachingStatus generateLogBloomCache(final long start, final long stop) { LOG.error("Cache directory '{}' does not exist and could not be made.", cacheDir); return cachingStatus; } - - final File pendingFile = calculateCacheFileName(PENDING, cacheDir); for (long blockNum = start; blockNum < stop; blockNum += BLOCKS_PER_BLOOM_CACHE) { LOG.info("Caching segment at {}", blockNum); - try (final FileOutputStream fos = new FileOutputStream(pendingFile)) { - final long blockCount = fillCacheFile(blockNum, blockNum + BLOCKS_PER_BLOOM_CACHE, fos); - if (blockCount == BLOCKS_PER_BLOOM_CACHE) { - Files.move( - pendingFile.toPath(), - calculateCacheFileName(blockNum, cacheDir).toPath(), - StandardCopyOption.REPLACE_EXISTING, - StandardCopyOption.ATOMIC_MOVE); - } else { - LOG.info("Partial segment at {}, only {} blocks cached", blockNum, blockCount); - break; - } + final File cacheFile = calculateCacheFileName(blockNum, cacheDir); + blockchain + .getBlockHeader(blockNum) + .ifPresent( + blockHeader -> + cacheLogsBloomForBlockHeader(blockHeader, Optional.of(cacheFile), false)); + try (final FileOutputStream fos = new FileOutputStream(cacheFile)) { + fillCacheFile(blockNum, blockNum + BLOCKS_PER_BLOOM_CACHE, fos); } } } catch (final Exception e) { @@ -122,7 +114,7 @@ public CachingStatus generateLogBloomCache(final long start, final long stop) { return cachingStatus; } - private long fillCacheFile( + private void fillCacheFile( final long startBlock, final long stopBlock, final FileOutputStream fos) throws IOException { long blockNum = startBlock; while (blockNum < stopBlock) { @@ -134,15 +126,19 @@ private long fillCacheFile( cachingStatus.currentBlock = blockNum; blockNum++; } - return blockNum - startBlock; } - public void cacheLogsBloomForBlockHeader(final BlockHeader blockHeader) { + public void cacheLogsBloomForBlockHeader( + final BlockHeader blockHeader, + final Optional reusedCacheFile, + final boolean ensureChecks) { try { final long blockNumber = blockHeader.getNumber(); LOG.debug("Caching logs bloom for block {}.", "0x" + Long.toHexString(blockNumber)); - ensurePreviousSegmentsArePresent(blockNumber); - final File cacheFile = calculateCacheFileName(blockNumber, cacheDir); + if (ensureChecks) { + ensurePreviousSegmentsArePresent(blockNumber); + } + final File cacheFile = reusedCacheFile.orElse(calculateCacheFileName(blockNumber, cacheDir)); if (!cacheFile.exists()) { Files.createFile(cacheFile.toPath()); }