diff --git a/server/src/main/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSession.java b/server/src/main/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSession.java index 0f3adecbc..f276ecd2d 100644 --- a/server/src/main/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSession.java +++ b/server/src/main/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSession.java @@ -121,11 +121,9 @@ protected void processBlockItems(List blockItems) throws Pars */ protected void finalizeVerification(BlockProof blockProof) { Bytes blockHash = CommonUtils.computeFinalBlockHash(blockProof, inputTreeHasher, outputTreeHasher); - + VerificationResult result; boolean verified = signatureVerifier.verifySignature(blockHash, blockProof.blockSignature()); if (verified) { - verificationResultFuture.complete( - new VerificationResult(blockNumber, blockHash, BlockVerificationStatus.VERIFIED)); long verificationLatency = System.nanoTime() - blockWorkStartTime; metricsService .get(BlockNodeMetricTypes.Counter.VerificationBlockTime) @@ -133,16 +131,18 @@ protected void finalizeVerification(BlockProof blockProof) { metricsService .get(BlockNodeMetricTypes.Counter.VerificationBlocksVerified) .increment(); + + result = new VerificationResult(blockNumber, blockHash, BlockVerificationStatus.VERIFIED); } else { LOGGER.log(INFO, "Block verification failed for block number: {0}", blockNumber); metricsService .get(BlockNodeMetricTypes.Counter.VerificationBlocksFailed) .increment(); - verificationResultFuture.complete( - new VerificationResult(blockNumber, blockHash, BlockVerificationStatus.SIGNATURE_INVALID)); - } + result = new VerificationResult(blockNumber, blockHash, BlockVerificationStatus.SIGNATURE_INVALID); + } shutdownSession(); + verificationResultFuture.complete(result); } /** diff --git a/server/src/main/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactory.java b/server/src/main/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactory.java index e30299c18..3b23339fd 100644 --- a/server/src/main/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactory.java +++ b/server/src/main/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactory.java @@ -54,7 +54,6 @@ public BlockVerificationSession createSession(@NonNull final BlockHeader blockHe case ASYNC -> new BlockVerificationSessionAsync( blockHeader, metricsService, signatureVerifier, executorService, hashCombineBatchSize); case SYNC -> new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); - default -> throw new IllegalArgumentException("Unsupported session type: " + type); }; } } diff --git a/server/src/test/java/com/hedera/block/server/verification/hasher/ConcurrentStreamingTreeHasherTest.java b/server/src/test/java/com/hedera/block/server/verification/hasher/ConcurrentStreamingTreeHasherTest.java index 3e5628b2a..c7715b086 100644 --- a/server/src/test/java/com/hedera/block/server/verification/hasher/ConcurrentStreamingTreeHasherTest.java +++ b/server/src/test/java/com/hedera/block/server/verification/hasher/ConcurrentStreamingTreeHasherTest.java @@ -27,9 +27,12 @@ import java.util.SplittableRandom; import java.util.concurrent.ForkJoinPool; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.junit.jupiter.MockitoExtension; +@ExtendWith(MockitoExtension.class) class ConcurrentStreamingTreeHasherTest { private static final SplittableRandom RANDOM = new SplittableRandom(); diff --git a/server/src/test/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSessionTest.java b/server/src/test/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSessionTest.java new file mode 100644 index 000000000..94d6ac685 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/verification/session/AbstractBlockVerificationSessionTest.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.verification.session; + +import static com.hedera.block.common.utils.FileUtilities.readGzipFileUnsafe; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlockTime; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlocksError; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlocksFailed; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlocksVerified; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import com.hedera.block.server.metrics.MetricsService; +import com.hedera.block.server.verification.BlockVerificationStatus; +import com.hedera.block.server.verification.VerificationResult; +import com.hedera.block.server.verification.signature.SignatureVerifier; +import com.hedera.hapi.block.BlockItemUnparsed; +import com.hedera.hapi.block.BlockUnparsed; +import com.hedera.hapi.block.stream.output.BlockHeader; +import com.hedera.pbj.runtime.ParseException; +import com.hedera.pbj.runtime.io.buffer.Bytes; +import com.swirlds.metrics.api.Counter; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public abstract class AbstractBlockVerificationSessionTest { + + @Mock + protected MetricsService metricsService; + + @Mock + protected SignatureVerifier signatureVerifier; + + @Mock + protected Counter verificationBlocksVerified; + + @Mock + protected Counter verificationBlocksFailed; + + @Mock + protected Counter verificationBlockTime; + + @Mock + protected Counter verificationBlocksError; + + protected final Bytes hashing01BlockHash = Bytes.fromHex( + "006ae77f87ff57df598f4d6536dcb5c0a5c1f840c2fef817b2faebd554d32cfc9a4eaee1d873ed88de668b53b7839117"); + + @BeforeEach + void setUpBase() { + MockitoAnnotations.openMocks(this); + when(metricsService.get(VerificationBlocksVerified)).thenReturn(verificationBlocksVerified); + when(metricsService.get(VerificationBlocksFailed)).thenReturn(verificationBlocksFailed); + when(metricsService.get(VerificationBlockTime)).thenReturn(verificationBlockTime); + when(metricsService.get(VerificationBlocksError)).thenReturn(verificationBlocksError); + } + + protected abstract BlockVerificationSession createSession(BlockHeader blockHeader); + + protected List getTestBlock1Items() throws IOException, ParseException, URISyntaxException { + Path block01Path = + Path.of(getClass().getResource("/test-blocks/hashing-01.blk.gz").toURI()); + Bytes block01Bytes = Bytes.wrap(readGzipFileUnsafe(block01Path)); + BlockUnparsed blockUnparsed = BlockUnparsed.PROTOBUF.parse(block01Bytes); + return blockUnparsed.blockItems(); + } + + @Test + void testSuccessfulVerification() throws Exception { + // Given + List blockItems = getTestBlock1Items(); + BlockHeader blockHeader = + BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); + BlockVerificationSession session = createSession(blockHeader); + + when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) + .thenReturn(true); + + // When + session.appendBlockItems(blockItems); + CompletableFuture future = session.getVerificationResult(); + VerificationResult result = future.get(); + + // Then + assertEquals(BlockVerificationStatus.VERIFIED, result.status()); + assertEquals(1L, result.blockNumber()); + assertEquals(hashing01BlockHash, result.blockHash()); + assertFalse(session.isRunning()); + verify(verificationBlocksVerified, times(1)).increment(); + verify(verificationBlockTime, times(1)).add(any(Long.class)); + verifyNoMoreInteractions(verificationBlocksFailed); + } + + @Test + void testSuccessfulVerification_multipleAppends() throws Exception { + // Given + List blockItems = getTestBlock1Items(); + // Slice list into 2 parts of different sizes + List blockItems1 = blockItems.subList(0, 3); + List blockItems2 = blockItems.subList(3, blockItems.size()); + BlockHeader blockHeader = + BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); + BlockVerificationSession session = createSession(blockHeader); + when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) + .thenReturn(true); + + // When + session.appendBlockItems(blockItems1); + session.appendBlockItems(blockItems2); + CompletableFuture future = session.getVerificationResult(); + VerificationResult result = future.get(); + + // Then + assertEquals(BlockVerificationStatus.VERIFIED, result.status()); + assertEquals(1L, result.blockNumber()); + assertEquals(hashing01BlockHash, result.blockHash()); + assertFalse(session.isRunning()); + verify(verificationBlocksVerified, times(1)).increment(); + verify(verificationBlockTime, times(1)).add(any(Long.class)); + verifyNoMoreInteractions(verificationBlocksFailed); + } + + @Test + void testVerificationFailure() throws Exception { + // Given + List blockItems = getTestBlock1Items(); + final Bytes hashing01BlockHash = Bytes.fromHex( + "006ae77f87ff57df598f4d6536dcb5c0a5c1f840c2fef817b2faebd554d32cfc9a4eaee1d873ed88de668b53b7839117"); + BlockHeader blockHeader = + BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); + BlockVerificationSession session = createSession(blockHeader); + when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) + .thenReturn(false); + + // When + session.appendBlockItems(blockItems); + CompletableFuture future = session.getVerificationResult(); + VerificationResult result = future.get(); + + // Then + assertEquals(BlockVerificationStatus.SIGNATURE_INVALID, result.status()); + assertEquals(1L, result.blockNumber()); + assertEquals(hashing01BlockHash, result.blockHash()); + assertFalse(session.isRunning()); + verifyNoMoreInteractions(verificationBlocksVerified); + verify(verificationBlocksFailed, times(1)).increment(); + } + + @Test + void testAppendBlockItemsNotRunning() throws Exception { + // Given + List blockItems = getTestBlock1Items(); + BlockHeader blockHeader = + BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); + BlockVerificationSession session = createSession(blockHeader); + when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) + .thenReturn(true); + // send a whole block and wait for the result, the session should be completed. + session.appendBlockItems(blockItems); + CompletableFuture future = session.getVerificationResult(); + VerificationResult result = future.get(); + + // metrics should be 1 + verify(verificationBlocksVerified, times(1)).increment(); + verify(verificationBlockTime, times(1)).add(any(Long.class)); + + // When + // Try to append more items after the session has completed + session.appendBlockItems(blockItems); + + // Then + // counters should still be 1 + verify(verificationBlocksVerified, times(1)).increment(); + verify(verificationBlockTime, times(1)).add(any(Long.class)); + } + + @Test + void testParseException() + throws IOException, ParseException, URISyntaxException, ExecutionException, InterruptedException { + // Given + List blockItems = getTestBlock1Items(); + BlockHeader blockHeader = + BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); + blockItems.set( + blockItems.size() - 1, + BlockItemUnparsed.newBuilder().blockProof(Bytes.wrap("invalid")).build()); + BlockVerificationSession session = createSession(blockHeader); + + // When + session.appendBlockItems(blockItems); + CompletableFuture future = session.getVerificationResult(); + assertThrows(ExecutionException.class, future::get); + + // Then + assertTrue(future.isCompletedExceptionally()); + verify(verificationBlocksError, times(1)).increment(); + } +} diff --git a/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionAsyncTest.java b/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionAsyncTest.java new file mode 100644 index 000000000..9d3717e39 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionAsyncTest.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.verification.session; + +import com.hedera.hapi.block.stream.output.BlockHeader; +import java.util.concurrent.Executors; + +class BlockVerificationSessionAsyncTest extends AbstractBlockVerificationSessionTest { + + @Override + protected BlockVerificationSession createSession(BlockHeader blockHeader) { + return new BlockVerificationSessionAsync( + blockHeader, metricsService, signatureVerifier, Executors.newSingleThreadExecutor(), 32); + } +} diff --git a/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactoryTest.java b/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactoryTest.java new file mode 100644 index 000000000..298c646a1 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionFactoryTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.verification.session; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import com.hedera.block.server.metrics.MetricsService; +import com.hedera.block.server.verification.VerificationConfig; +import com.hedera.block.server.verification.signature.SignatureVerifier; +import com.hedera.hapi.block.stream.output.BlockHeader; +import java.util.concurrent.ExecutorService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +class BlockVerificationSessionFactoryTest { + + @Mock + private MetricsService mockMetricsService; + + @Mock + private SignatureVerifier mockSignatureVerifier; + + @Mock + private ExecutorService mockExecutorService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + // Default configuration stubs + + } + + @Test + void createSession_whenSessionTypeIsAsync_returnsBlockVerificationSessionAsync() { + // Given + VerificationConfig config = new VerificationConfig(true, BlockVerificationSessionType.ASYNC, 32); + BlockHeader blockHeader = BlockHeader.newBuilder().number(1L).build(); + + BlockVerificationSessionFactory sessionFactory = new BlockVerificationSessionFactory( + config, mockMetricsService, mockSignatureVerifier, mockExecutorService); + + // When + var session = sessionFactory.createSession(blockHeader); + + // Then + assertNotNull(session, "Session should not be null"); + assertInstanceOf( + BlockVerificationSessionAsync.class, + session, + "Session should be an instance of BlockVerificationSessionAsync"); + } + + @Test + void createSession_whenSessionTypeIsSync_returnsBlockVerificationSessionSync() { + // Given + VerificationConfig config = new VerificationConfig(true, BlockVerificationSessionType.SYNC, 32); + BlockHeader blockHeader = BlockHeader.newBuilder().number(1L).build(); + + BlockVerificationSessionFactory sessionFactory = new BlockVerificationSessionFactory( + config, mockMetricsService, mockSignatureVerifier, mockExecutorService); + + // When + var session = sessionFactory.createSession(blockHeader); + + // Then + assertNotNull(session, "Session should not be null"); + assertInstanceOf( + BlockVerificationSessionSync.class, + session, + "Session should be an instance of BlockVerificationSessionSync"); + } +} diff --git a/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionSyncTest.java b/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionSyncTest.java index 5cace8af6..352a05a39 100644 --- a/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionSyncTest.java +++ b/server/src/test/java/com/hedera/block/server/verification/session/BlockVerificationSessionSyncTest.java @@ -16,212 +16,12 @@ package com.hedera.block.server.verification.session; -import static com.hedera.block.common.utils.FileUtilities.readGzipFileUnsafe; -import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlockTime; -import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlocksError; -import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlocksFailed; -import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.VerificationBlocksVerified; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.hedera.block.server.metrics.MetricsService; -import com.hedera.block.server.verification.BlockVerificationStatus; -import com.hedera.block.server.verification.VerificationResult; -import com.hedera.block.server.verification.signature.SignatureVerifier; -import com.hedera.hapi.block.BlockItemUnparsed; -import com.hedera.hapi.block.BlockUnparsed; import com.hedera.hapi.block.stream.output.BlockHeader; -import com.hedera.pbj.runtime.ParseException; -import com.hedera.pbj.runtime.io.buffer.Bytes; -import com.swirlds.metrics.api.Counter; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -class BlockVerificationSessionSyncTest { - - @Mock - private MetricsService metricsService; - - @Mock - private SignatureVerifier signatureVerifier; - - @Mock - private Counter verificationBlocksVerified; - - @Mock - private Counter verificationBlocksFailed; - - @Mock - private Counter verificationBlockTime; - - @Mock - Counter verificationBlocksError; - - final Bytes hashing01BlockHash = Bytes.fromHex( - "006ae77f87ff57df598f4d6536dcb5c0a5c1f840c2fef817b2faebd554d32cfc9a4eaee1d873ed88de668b53b7839117"); - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - // set metrics - when(metricsService.get(VerificationBlocksVerified)).thenReturn(verificationBlocksVerified); - when(metricsService.get(VerificationBlocksFailed)).thenReturn(verificationBlocksFailed); - when(metricsService.get(VerificationBlockTime)).thenReturn(verificationBlockTime); - when(metricsService.get(VerificationBlocksError)).thenReturn(verificationBlocksError); - } - - private List getTestBlock1Items() throws IOException, ParseException, URISyntaxException { - Path block01Path = - Path.of(getClass().getResource("/test-blocks/hashing-01.blk.gz").toURI()); - Bytes block01Bytes = Bytes.wrap(readGzipFileUnsafe(block01Path)); - BlockUnparsed blockUnparsed = BlockUnparsed.PROTOBUF.parse(block01Bytes); - - return blockUnparsed.blockItems(); - } - - @Test - void testSuccessfulVerification() throws Exception { - // Given - List blockItems = getTestBlock1Items(); - BlockHeader blockHeader = - BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); - BlockVerificationSessionSync session = - new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); - when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) - .thenReturn(true); - - // When - session.appendBlockItems(blockItems); - CompletableFuture future = session.getVerificationResult(); - VerificationResult result = future.get(); - - // Then - assertEquals(BlockVerificationStatus.VERIFIED, result.status()); - assertEquals(1L, result.blockNumber()); - assertEquals(hashing01BlockHash, result.blockHash()); - assertFalse(session.isRunning()); - verify(verificationBlocksVerified, times(1)).increment(); - verify(verificationBlockTime, times(1)).add(any(Long.class)); - verifyNoMoreInteractions(verificationBlocksFailed); - } - - @Test - void testSuccessfulVerification_multipleAppends() throws Exception { - // Given - List blockItems = getTestBlock1Items(); - // Slice list into 2 parts of different sizes - List blockItems1 = blockItems.subList(0, 3); - List blockItems2 = blockItems.subList(3, blockItems.size()); - BlockHeader blockHeader = - BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); - BlockVerificationSessionSync session = - new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); - when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) - .thenReturn(true); - - // When - session.appendBlockItems(blockItems1); - session.appendBlockItems(blockItems2); - CompletableFuture future = session.getVerificationResult(); - VerificationResult result = future.get(); - - // Then - assertEquals(BlockVerificationStatus.VERIFIED, result.status()); - assertEquals(1L, result.blockNumber()); - assertEquals(hashing01BlockHash, result.blockHash()); - assertFalse(session.isRunning()); - verify(verificationBlocksVerified, times(1)).increment(); - verify(verificationBlockTime, times(1)).add(any(Long.class)); - verifyNoMoreInteractions(verificationBlocksFailed); - } - - @Test - void testVerificationFailure() throws Exception { - // Given - List blockItems = getTestBlock1Items(); - final Bytes hashing01BlockHash = Bytes.fromHex( - "006ae77f87ff57df598f4d6536dcb5c0a5c1f840c2fef817b2faebd554d32cfc9a4eaee1d873ed88de668b53b7839117"); - BlockHeader blockHeader = - BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); - BlockVerificationSessionSync session = - new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); - when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) - .thenReturn(false); - - // When - session.appendBlockItems(blockItems); - CompletableFuture future = session.getVerificationResult(); - VerificationResult result = future.get(); - - // Then - assertEquals(BlockVerificationStatus.SIGNATURE_INVALID, result.status()); - assertEquals(1L, result.blockNumber()); - assertEquals(hashing01BlockHash, result.blockHash()); - assertFalse(session.isRunning()); - verifyNoMoreInteractions(verificationBlocksVerified); - verify(verificationBlocksFailed, times(1)).increment(); - } - - @Test - void testAppendBlockItemsNotRunning() throws Exception { - // Given - List blockItems = getTestBlock1Items(); - BlockHeader blockHeader = - BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); - BlockVerificationSessionSync session = - new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); - when(signatureVerifier.verifySignature(any(Bytes.class), any(Bytes.class))) - .thenReturn(true); - // send a whole block and wait for the result, the session should be completed. - session.appendBlockItems(blockItems); - CompletableFuture future = session.getVerificationResult(); - VerificationResult result = future.get(); - - // metrics should be 1 - verify(verificationBlocksVerified, times(1)).increment(); - verify(verificationBlockTime, times(1)).add(any(Long.class)); - - // When - // Try to append more items after the session has completed - session.appendBlockItems(blockItems); - - // Then - // counters should still be 1 - verify(verificationBlocksVerified, times(1)).increment(); - verify(verificationBlockTime, times(1)).add(any(Long.class)); - } - - @Test - void testParseException() - throws IOException, ParseException, URISyntaxException, ExecutionException, InterruptedException { - // Given - List blockItems = getTestBlock1Items(); - BlockHeader blockHeader = - BlockHeader.PROTOBUF.parse(blockItems.getFirst().blockHeader()); - blockItems.set( - blockItems.size() - 1, - BlockItemUnparsed.newBuilder().blockProof(Bytes.wrap("invalid")).build()); - BlockVerificationSessionSync session = - new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); - // When - session.appendBlockItems(blockItems); - CompletableFuture future = session.getVerificationResult(); +class BlockVerificationSessionSyncTest extends AbstractBlockVerificationSessionTest { - // Then - assertTrue(future.isCompletedExceptionally()); - verify(verificationBlocksError, times(1)).increment(); + @Override + protected BlockVerificationSession createSession(BlockHeader blockHeader) { + return new BlockVerificationSessionSync(blockHeader, metricsService, signatureVerifier); } }