diff --git a/coordinator/app/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTrackerTest.kt b/coordinator/app/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTrackerTest.kt index ea0cbca3c..76e25d1d8 100644 --- a/coordinator/app/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTrackerTest.kt +++ b/coordinator/app/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ConsecutiveProvenBlobsProviderWithLastEndBlockNumberTrackerTest.kt @@ -1,9 +1,9 @@ package net.consensys.zkevm.ethereum.coordination.aggregation +import build.linea.domain.BlockIntervals import kotlinx.datetime.Instant import net.consensys.zkevm.domain.BlobAndBatchCounters import net.consensys.zkevm.domain.BlobCounters -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.persistence.AggregationsRepository import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test diff --git a/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ABProverClientRouter.kt b/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ABProverClientRouter.kt index ad5eefa0f..dc118f3f3 100644 --- a/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ABProverClientRouter.kt +++ b/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ABProverClientRouter.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.coordinator.clients.prover +import build.linea.domain.BlockInterval import net.consensys.zkevm.coordinator.clients.ProverClient -import net.consensys.zkevm.domain.BlockInterval import tech.pegasys.teku.infrastructure.async.SafeFuture class StartBlockNumberBasedSwitchPredicate( diff --git a/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClient.kt b/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClient.kt index dcc24fb2b..4b71a022c 100644 --- a/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClient.kt +++ b/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClient.kt @@ -1,11 +1,11 @@ package net.consensys.zkevm.coordinator.clients.prover +import build.linea.domain.BlockInterval import com.github.michaelbull.result.Err import com.github.michaelbull.result.getOrElse import com.github.michaelbull.result.map import io.vertx.core.Vertx import net.consensys.linea.errors.ErrorResponse -import net.consensys.zkevm.domain.BlockInterval import net.consensys.zkevm.domain.ProofIndex import net.consensys.zkevm.fileio.FileMonitor import net.consensys.zkevm.fileio.FileReader diff --git a/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactory.kt b/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactory.kt index 5802a45c0..ed09edbce 100644 --- a/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactory.kt +++ b/coordinator/clients/prover-client/file-based-client/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactory.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.coordinator.clients.prover +import build.linea.domain.BlockInterval import io.vertx.core.Vertx import net.consensys.linea.contract.Web3JL2MessageServiceLogsClient import net.consensys.linea.metrics.LineaMetricsCategory @@ -9,7 +10,6 @@ import net.consensys.zkevm.coordinator.clients.BlobCompressionProverClientV2 import net.consensys.zkevm.coordinator.clients.ExecutionProverClientV2 import net.consensys.zkevm.coordinator.clients.ProofAggregationProverClientV2 import net.consensys.zkevm.coordinator.clients.ProverClient -import net.consensys.zkevm.domain.BlockInterval import org.web3j.protocol.Web3j class ProverClientFactory( diff --git a/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClientTest.kt b/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClientTest.kt index d945b1b96..766ddc061 100644 --- a/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClientTest.kt +++ b/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/GenericFileBasedProverClientTest.kt @@ -1,9 +1,9 @@ package net.consensys.zkevm.coordinator.clients.prover +import build.linea.domain.BlockInterval import io.vertx.core.Vertx import io.vertx.junit5.VertxExtension import net.consensys.zkevm.coordinator.clients.prover.serialization.JsonSerialization -import net.consensys.zkevm.domain.BlockInterval import net.consensys.zkevm.domain.ProofIndex import net.consensys.zkevm.fileio.FileReader import net.consensys.zkevm.fileio.FileWriter diff --git a/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactoryTest.kt b/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactoryTest.kt index 11396479c..66b01a8ed 100644 --- a/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactoryTest.kt +++ b/coordinator/clients/prover-client/file-based-client/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/ProverClientFactoryTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.coordinator.clients.prover +import build.linea.domain.BlockIntervals import io.micrometer.core.instrument.MeterRegistry import io.micrometer.core.instrument.simple.SimpleMeterRegistry import io.vertx.core.Vertx @@ -8,7 +9,6 @@ import kotlinx.datetime.Clock import net.consensys.ByteArrayExt import net.consensys.linea.metrics.MetricsFacade import net.consensys.linea.metrics.micrometer.MicrometerMetricsFacade -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ProofIndex import net.consensys.zkevm.domain.ProofsToAggregate import org.assertj.core.api.Assertions.assertThat diff --git a/coordinator/clients/prover-client/serialization/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobJsonFileRequestResponse.kt b/coordinator/clients/prover-client/serialization/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobJsonFileRequestResponse.kt index d050c09cf..2ecfa52f1 100644 --- a/coordinator/clients/prover-client/serialization/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobJsonFileRequestResponse.kt +++ b/coordinator/clients/prover-client/serialization/src/main/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobJsonFileRequestResponse.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.coordinator.clients.prover.serialization +import build.linea.domain.BlockIntervals import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser @@ -13,7 +14,6 @@ import net.consensys.decodeHex import net.consensys.encodeHex import net.consensys.zkevm.coordinator.clients.BlobCompressionProof import net.consensys.zkevm.coordinator.clients.BlobCompressionProofRequest -import net.consensys.zkevm.domain.BlockIntervals internal class ByteArrayDeserializer : JsonDeserializer() { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): ByteArray { diff --git a/coordinator/clients/prover-client/serialization/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobCompressionProofJsonResponseTest.kt b/coordinator/clients/prover-client/serialization/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobCompressionProofJsonResponseTest.kt index 5d0a01be9..334d01a52 100644 --- a/coordinator/clients/prover-client/serialization/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobCompressionProofJsonResponseTest.kt +++ b/coordinator/clients/prover-client/serialization/src/test/kotlin/net/consensys/zkevm/coordinator/clients/prover/serialization/BlobCompressionProofJsonResponseTest.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.coordinator.clients.prover.serialization +import build.linea.domain.BlockIntervals import net.consensys.zkevm.coordinator.clients.prover.serialization.JsonSerialization.proofResponseMapperV1 -import net.consensys.zkevm.domain.BlockIntervals import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BatchExecutionProverRequestResponse.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BatchExecutionProverRequestResponse.kt index 900827efd..97ecfc618 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BatchExecutionProverRequestResponse.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BatchExecutionProverRequestResponse.kt @@ -1,6 +1,6 @@ package net.consensys.zkevm.coordinator.clients -import net.consensys.zkevm.domain.BlockInterval +import build.linea.domain.BlockInterval import net.consensys.zkevm.toULong import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1 diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BlobCompressionProverRequestResponse.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BlobCompressionProverRequestResponse.kt index a2dc06ca6..2bf32a247 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BlobCompressionProverRequestResponse.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/coordinator/clients/BlobCompressionProverRequestResponse.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.coordinator.clients -import net.consensys.zkevm.domain.BlockInterval -import net.consensys.zkevm.domain.BlockIntervals +import build.linea.domain.BlockInterval +import build.linea.domain.BlockIntervals import net.consensys.zkevm.domain.ConflationCalculationResult import net.consensys.zkevm.ethereum.coordination.blob.ShnarfResult diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Aggregation.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Aggregation.kt index 90f765de5..417ff331a 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Aggregation.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Aggregation.kt @@ -1,8 +1,10 @@ package net.consensys.zkevm.domain +import build.linea.domain.BlockInterval +import build.linea.domain.BlockIntervals import kotlinx.datetime.Instant -typealias BlobsToAggregate = BlockIntervalData +typealias BlobsToAggregate = BlockInterval /** * Represents an Aggregation request to the Prover diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Blob.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Blob.kt index aee335bf6..7bd83f835 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Blob.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Blob.kt @@ -1,5 +1,7 @@ package net.consensys.zkevm.domain +import build.linea.domain.BlockInterval +import build.linea.domain.BlockIntervals import kotlinx.datetime.Instant import net.consensys.linea.CommonDomainFunctions import net.consensys.zkevm.coordinator.clients.BlobCompressionProof diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Conflation.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Conflation.kt index 70bf2dd47..2a3f6fd51 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Conflation.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/Conflation.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.domain +import build.linea.domain.BlockInterval import kotlinx.datetime.Instant import net.consensys.isSortedBy import net.consensys.linea.CommonDomainFunctions @@ -7,50 +8,6 @@ import net.consensys.linea.traces.TracesCounters import net.consensys.zkevm.toULong import tech.pegasys.teku.ethereum.executionclient.schema.ExecutionPayloadV1 -/** - * Represents a block interval, with inclusive start and end block numbers - * @property startBlockNumber start block number, inclusive - * @property endBlockNumber end block number, inclusive - */ -interface BlockInterval { - val startBlockNumber: ULong - val endBlockNumber: ULong - val blocksRange: ULongRange - get() = startBlockNumber..endBlockNumber - fun intervalString(): String = CommonDomainFunctions.blockIntervalString(startBlockNumber, endBlockNumber) - - companion object { - fun between( - startBlockNumber: ULong, - endBlockNumber: ULong - ): BlockInterval { - return BlockIntervalData(startBlockNumber, endBlockNumber) - } - } -} - -fun List.toBlockIntervalsString(): String { - return this.joinToString( - separator = ", ", - prefix = "[", - postfix = "]$size", - transform = BlockInterval::intervalString - ) -} - -fun List.filterOutWithEndBlockNumberBefore( - endBlockNumberInclusive: ULong -): List { - return this.filter { int -> int.endBlockNumber > endBlockNumberInclusive } -} - -fun assertConsecutiveIntervals(intervals: List) { - require(intervals.isSortedBy { it.startBlockNumber }) { "Intervals must be sorted by startBlockNumber" } - require(intervals.zipWithNext().all { (a, b) -> a.endBlockNumber + 1u == b.startBlockNumber }) { - "Intervals must be consecutive: intervals=${intervals.toBlockIntervalsString()}" - } -} - data class BlocksConflation( val blocks: List, val conflationResult: ConflationCalculationResult @@ -148,52 +105,3 @@ data class BlockCounters( "blockRLPEncoded=${blockRLPEncoded.size}bytes)" } } - -/** - * Represents a block interval - * @property startBlockNumber starting block number inclusive - * @property endBlockNumber ending block number inclusive - */ -data class BlockIntervalData( - override val startBlockNumber: ULong, - override val endBlockNumber: ULong -) : BlockInterval - -/** - * Data class that represents sequential blocks intervals for either Conflations, Blobs or Aggregations. - * Example: - * conflations: [100..110], [111..120], [121..130] --> BlockIntervals(100, [110, 120, 130]) - * Blobs with - * Blob1 2 conflations above: [100..110], [111..120] - * Blob2 1 conflations: [121..130] - * --> BlockIntervals(100, [120, 130]) - */ -data class BlockIntervals( - val startingBlockNumber: ULong, - val upperBoundaries: List -) { - // This default constructor is to avoid the parse error when deserializing - constructor() : this(0UL, listOf()) - - fun toIntervalList(): List { - var previousBlockNumber = startingBlockNumber - val intervals = mutableListOf() - upperBoundaries.forEach { - intervals.add(BlockIntervalData(previousBlockNumber, it)) - previousBlockNumber = it + 1u - } - return intervals - } - - fun toBlockInterval(): BlockInterval { - return BlockIntervalData(startingBlockNumber, upperBoundaries.last()) - } -} - -fun List.toBlockIntervals(): BlockIntervals { - require(isNotEmpty()) { "BlockIntervals list must not be empty" } - return BlockIntervals( - startingBlockNumber = first().startBlockNumber, - upperBoundaries = map { it.endBlockNumber } - ) -} diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/ProofIndex.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/ProofIndex.kt index e6130f88c..bdd1b408b 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/ProofIndex.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/domain/ProofIndex.kt @@ -1,5 +1,7 @@ package net.consensys.zkevm.domain +import build.linea.domain.BlockInterval + data class ProofIndex( override val startBlockNumber: ULong, override val endBlockNumber: ULong, diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/AggregationTriggerCalculatorByTargetBlockNumbers.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/AggregationTriggerCalculatorByTargetBlockNumbers.kt index 0c711fde6..865f60b62 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/AggregationTriggerCalculatorByTargetBlockNumbers.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/AggregationTriggerCalculatorByTargetBlockNumbers.kt @@ -1,8 +1,8 @@ package net.consensys.zkevm.ethereum.coordination.aggregation +import build.linea.domain.BlockInterval import net.consensys.zkevm.domain.BlobCounters import net.consensys.zkevm.domain.BlobsToAggregate -import net.consensys.zkevm.domain.BlockInterval import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorService.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorService.kt index f093b6b37..f12a90350 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorService.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorService.kt @@ -1,5 +1,7 @@ package net.consensys.zkevm.ethereum.coordination.aggregation +import build.linea.domain.BlockIntervals +import build.linea.domain.toBlockIntervalsString import io.vertx.core.Vertx import kotlinx.datetime.Clock import net.consensys.linea.metrics.MetricsFacade @@ -10,10 +12,8 @@ import net.consensys.zkevm.coordinator.clients.ProofAggregationProverClientV2 import net.consensys.zkevm.domain.Aggregation import net.consensys.zkevm.domain.BlobAndBatchCounters import net.consensys.zkevm.domain.BlobsToAggregate -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ProofIndex import net.consensys.zkevm.domain.ProofsToAggregate -import net.consensys.zkevm.domain.toBlockIntervalsString import net.consensys.zkevm.ethereum.coordination.blockcreation.SafeBlockProvider import net.consensys.zkevm.persistence.AggregationsRepository import org.apache.logging.log4j.LogManager diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinator.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinator.kt index bda75ba7a..ae05a29cb 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinator.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinator.kt @@ -1,5 +1,8 @@ package net.consensys.zkevm.ethereum.coordination.blob +import build.linea.domain.BlockInterval +import build.linea.domain.BlockIntervals +import build.linea.domain.toBlockIntervalsString import io.vertx.core.Handler import io.vertx.core.Vertx import kotlinx.datetime.Instant @@ -11,10 +14,7 @@ import net.consensys.zkevm.coordinator.clients.BlobCompressionProverClientV2 import net.consensys.zkevm.domain.Blob import net.consensys.zkevm.domain.BlobRecord import net.consensys.zkevm.domain.BlobStatus -import net.consensys.zkevm.domain.BlockInterval -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ConflationCalculationResult -import net.consensys.zkevm.domain.toBlockIntervalsString import net.consensys.zkevm.ethereum.coordination.conflation.BlobCreationHandler import net.consensys.zkevm.persistence.BlobsRepository import org.apache.logging.log4j.LogManager diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofHandler.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofHandler.kt index 62c7426e2..9b95f5de9 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofHandler.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofHandler.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.ethereum.coordination.blob +import build.linea.domain.BlockInterval import net.consensys.zkevm.coordinator.clients.BlobCompressionProof -import net.consensys.zkevm.domain.BlockInterval import tech.pegasys.teku.infrastructure.async.SafeFuture data class BlobCompressionProofUpdate( diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobShnarfCalulator.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobShnarfCalulator.kt index 27344a3eb..9350bea78 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobShnarfCalulator.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobShnarfCalulator.kt @@ -1,11 +1,11 @@ package net.consensys.zkevm.ethereum.coordination.blob +import build.linea.domain.BlockIntervals import net.consensys.decodeHex import net.consensys.encodeHex import net.consensys.linea.blob.GoNativeBlobShnarfCalculator import net.consensys.linea.blob.GoNativeShnarfCalculatorFactory import net.consensys.linea.blob.ShnarfCalculatorVersion -import net.consensys.zkevm.domain.BlockIntervals import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger import java.util.Base64 diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculator.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculator.kt index 62d44bd55..954743e0f 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculator.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculator.kt @@ -1,5 +1,7 @@ package net.consensys.zkevm.ethereum.coordination.blob +import build.linea.domain.BlockInterval +import build.linea.domain.BlockIntervals import com.github.michaelbull.result.getOrThrow import com.github.michaelbull.result.map import com.github.michaelbull.result.onSuccess @@ -7,8 +9,6 @@ import com.github.michaelbull.result.recover import com.github.michaelbull.result.runCatching import net.consensys.encodeHex import net.consensys.zkevm.domain.BlobRecord -import net.consensys.zkevm.domain.BlockInterval -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.persistence.BlobsRepository import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger diff --git a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/GlobalBlobAwareConflationCalculator.kt b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/GlobalBlobAwareConflationCalculator.kt index faf5f3318..912ee571d 100644 --- a/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/GlobalBlobAwareConflationCalculator.kt +++ b/coordinator/core/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/GlobalBlobAwareConflationCalculator.kt @@ -1,11 +1,11 @@ package net.consensys.zkevm.ethereum.coordination.conflation +import build.linea.domain.toBlockIntervalsString import net.consensys.linea.CommonDomainFunctions.blockIntervalString import net.consensys.zkevm.domain.Blob import net.consensys.zkevm.domain.BlockCounters import net.consensys.zkevm.domain.ConflationCalculationResult import net.consensys.zkevm.domain.ConflationTrigger -import net.consensys.zkevm.domain.toBlockIntervalsString import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger import tech.pegasys.teku.infrastructure.async.SafeFuture diff --git a/coordinator/core/src/test/kotlin/net/consensys/zkevm/coordination/blob/GoBackedCalculateShnarfCalculatorTest.kt b/coordinator/core/src/test/kotlin/net/consensys/zkevm/coordination/blob/GoBackedCalculateShnarfCalculatorTest.kt index b7eb3890e..b1db17fc0 100644 --- a/coordinator/core/src/test/kotlin/net/consensys/zkevm/coordination/blob/GoBackedCalculateShnarfCalculatorTest.kt +++ b/coordinator/core/src/test/kotlin/net/consensys/zkevm/coordination/blob/GoBackedCalculateShnarfCalculatorTest.kt @@ -1,10 +1,10 @@ package net.consensys.zkevm.coordination.blob +import build.linea.domain.BlockIntervals import net.consensys.decodeHex import net.consensys.encodeHex import net.consensys.linea.blob.CalculateShnarfResult import net.consensys.linea.blob.GoNativeBlobShnarfCalculator -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.ethereum.coordination.blob.GoBackedBlobShnarfCalculator import net.consensys.zkevm.ethereum.coordination.blob.ShnarfResult import org.apache.tuweni.bytes.Bytes32 diff --git a/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorServiceTest.kt b/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorServiceTest.kt index 7782b7ba7..4698897bd 100644 --- a/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorServiceTest.kt +++ b/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/aggregation/ProofAggregationCoordinatorServiceTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.ethereum.coordination.aggregation +import build.linea.domain.BlockIntervals import io.vertx.core.Vertx import kotlinx.datetime.Clock import kotlinx.datetime.Instant @@ -9,7 +10,6 @@ import net.consensys.zkevm.domain.Aggregation import net.consensys.zkevm.domain.BlobAndBatchCounters import net.consensys.zkevm.domain.BlobCounters import net.consensys.zkevm.domain.BlobsToAggregate -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ProofIndex import net.consensys.zkevm.domain.ProofToFinalize import net.consensys.zkevm.domain.ProofsToAggregate diff --git a/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculatorTest.kt b/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculatorTest.kt index 29db3eed4..cb7faf0a0 100644 --- a/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculatorTest.kt +++ b/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/blob/RollingBlobShnarfCalculatorTest.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.ethereum.coordination.blob +import build.linea.domain.BlockIntervals import net.consensys.zkevm.domain.BlobRecord -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.persistence.BlobsRepository import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach diff --git a/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/BlockToBatchSubmissionCoordinatorTest.kt b/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/BlockToBatchSubmissionCoordinatorTest.kt index 2ebc290df..17451a100 100644 --- a/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/BlockToBatchSubmissionCoordinatorTest.kt +++ b/coordinator/core/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/conflation/BlockToBatchSubmissionCoordinatorTest.kt @@ -24,7 +24,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import tech.pegasys.teku.ethereum.executionclient.schema.randomExecutionPayload import tech.pegasys.teku.infrastructure.async.SafeFuture -import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds import kotlin.time.toJavaDuration @ExtendWith(VertxExtension::class) @@ -79,7 +79,7 @@ class BlockToBatchSubmissionCoordinatorTest { val captor = argumentCaptor() Assertions.assertThat(blockToBatchSubmissionCoordinator.acceptBlock(baseBlock)).isCompleted - Awaitility.await().atMost(200.milliseconds.toJavaDuration()) + Awaitility.await().atMost(1.seconds.toJavaDuration()) .untilAsserted { verify(testLogger, times(1)).error( eq("Failed to conflate block={} errorMessage={}"), diff --git a/coordinator/core/src/testFixtures/kotlin/net/consensys/zkevm/domain/BlobRecord.kt b/coordinator/core/src/testFixtures/kotlin/net/consensys/zkevm/domain/BlobRecord.kt index 97c7c4b8d..226309458 100644 --- a/coordinator/core/src/testFixtures/kotlin/net/consensys/zkevm/domain/BlobRecord.kt +++ b/coordinator/core/src/testFixtures/kotlin/net/consensys/zkevm/domain/BlobRecord.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.domain +import build.linea.domain.BlockIntervals import kotlinx.datetime.Clock import kotlinx.datetime.Instant import net.consensys.linea.blob.ShnarfCalculatorVersion diff --git a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinator.kt b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinator.kt index 8ea0e8c3b..29d63f93d 100644 --- a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinator.kt +++ b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinator.kt @@ -1,5 +1,8 @@ package net.consensys.zkevm.ethereum.submission +import build.linea.domain.filterOutWithEndBlockNumberBefore +import build.linea.domain.toBlockIntervals +import build.linea.domain.toBlockIntervalsString import io.vertx.core.Vertx import kotlinx.datetime.Clock import net.consensys.linea.async.AsyncFilter @@ -9,9 +12,6 @@ import net.consensys.zkevm.coordinator.clients.smartcontract.LineaRollupSmartCon import net.consensys.zkevm.domain.Aggregation import net.consensys.zkevm.domain.BlobRecord import net.consensys.zkevm.domain.ProofToFinalize -import net.consensys.zkevm.domain.filterOutWithEndBlockNumberBefore -import net.consensys.zkevm.domain.toBlockIntervals -import net.consensys.zkevm.domain.toBlockIntervalsString import net.consensys.zkevm.ethereum.gaspricing.GasPriceCapProvider import net.consensys.zkevm.persistence.AggregationsRepository import net.consensys.zkevm.persistence.BlobsRepository diff --git a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelper.kt b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelper.kt index a3b42c042..792fea54e 100644 --- a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelper.kt +++ b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelper.kt @@ -1,9 +1,9 @@ package net.consensys.zkevm.ethereum.submission -import net.consensys.zkevm.domain.BlockInterval -import net.consensys.zkevm.domain.BlockIntervals -import net.consensys.zkevm.domain.assertConsecutiveIntervals -import net.consensys.zkevm.domain.toBlockIntervalsString +import build.linea.domain.BlockInterval +import build.linea.domain.BlockIntervals +import build.linea.domain.assertConsecutiveIntervals +import build.linea.domain.toBlockIntervalsString import org.apache.logging.log4j.Logger import kotlin.math.min diff --git a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmitterAsEIP4844MultipleBlobsPerTx.kt b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmitterAsEIP4844MultipleBlobsPerTx.kt index bc46ae570..2c8a920bf 100644 --- a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmitterAsEIP4844MultipleBlobsPerTx.kt +++ b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmitterAsEIP4844MultipleBlobsPerTx.kt @@ -1,8 +1,8 @@ package net.consensys.zkevm.ethereum.submission +import build.linea.domain.toBlockIntervalsString import net.consensys.zkevm.coordinator.clients.smartcontract.LineaRollupSmartContractClient import net.consensys.zkevm.domain.BlobRecord -import net.consensys.zkevm.domain.toBlockIntervalsString import net.consensys.zkevm.ethereum.gaspricing.GasPriceCapProvider import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger diff --git a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobsGrouperForSubmission.kt b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobsGrouperForSubmission.kt index 59132767c..1fe37f605 100644 --- a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobsGrouperForSubmission.kt +++ b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/BlobsGrouperForSubmission.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.ethereum.submission +import build.linea.domain.BlockIntervals import net.consensys.zkevm.domain.BlobRecord -import net.consensys.zkevm.domain.BlockIntervals fun interface BlobsGrouperForSubmission { fun chunkBlobs( diff --git a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/ContractUpgradeSubmissionLatchFilter.kt b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/ContractUpgradeSubmissionLatchFilter.kt index 61fb6ba26..a3710ea08 100644 --- a/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/ContractUpgradeSubmissionLatchFilter.kt +++ b/coordinator/ethereum/blob-submitter/src/main/kotlin/net/consensys/zkevm/ethereum/submission/ContractUpgradeSubmissionLatchFilter.kt @@ -1,9 +1,9 @@ package net.consensys.zkevm.ethereum.submission +import build.linea.domain.BlockInterval import net.consensys.linea.async.AsyncFilter import net.consensys.zkevm.coordinator.clients.smartcontract.ContractVersionProvider import net.consensys.zkevm.coordinator.clients.smartcontract.LineaContractVersion -import net.consensys.zkevm.domain.BlockInterval import org.apache.logging.log4j.LogManager import tech.pegasys.teku.infrastructure.async.SafeFuture import java.util.concurrent.atomic.AtomicBoolean diff --git a/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinatorTest.kt b/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinatorTest.kt index ae36c1c0a..bdb155097 100644 --- a/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinatorTest.kt +++ b/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionCoordinatorTest.kt @@ -1,15 +1,15 @@ package net.consensys.zkevm.ethereum.submission +import build.linea.domain.BlockIntervals +import build.linea.domain.toBlockIntervals import io.vertx.core.Vertx import net.consensys.FakeFixedClock import net.consensys.linea.async.AsyncFilter import net.consensys.zkevm.coordinator.clients.smartcontract.BlockAndNonce import net.consensys.zkevm.coordinator.clients.smartcontract.LineaRollupSmartContractClient import net.consensys.zkevm.domain.BlobRecord -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.createAggregation import net.consensys.zkevm.domain.createBlobRecords -import net.consensys.zkevm.domain.toBlockIntervals import net.consensys.zkevm.persistence.AggregationsRepository import net.consensys.zkevm.persistence.BlobsRepository import org.apache.logging.log4j.LogManager diff --git a/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelperKtTest.kt b/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelperKtTest.kt index 055c543b8..6b9b5d602 100644 --- a/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelperKtTest.kt +++ b/coordinator/ethereum/blob-submitter/src/test/kotlin/net/consensys/zkevm/ethereum/submission/BlobSubmissionHelperKtTest.kt @@ -1,7 +1,7 @@ package net.consensys.zkevm.ethereum.submission -import net.consensys.zkevm.domain.BlockIntervalData -import net.consensys.zkevm.domain.BlockIntervals +import build.linea.domain.BlockIntervalData +import build.linea.domain.BlockIntervals import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows diff --git a/coordinator/persistence/aggregation/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/aggregation/AggregationsPostgresDaoTest.kt b/coordinator/persistence/aggregation/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/aggregation/AggregationsPostgresDaoTest.kt index e0e439292..4fe0878e6 100644 --- a/coordinator/persistence/aggregation/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/aggregation/AggregationsPostgresDaoTest.kt +++ b/coordinator/persistence/aggregation/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/aggregation/AggregationsPostgresDaoTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.persistence.dao.aggregation +import build.linea.domain.BlockIntervals import io.vertx.junit5.VertxExtension import io.vertx.sqlclient.Row import io.vertx.sqlclient.RowSet @@ -15,7 +16,6 @@ import net.consensys.zkevm.domain.BlobAndBatchCounters import net.consensys.zkevm.domain.BlobCounters import net.consensys.zkevm.domain.BlobRecord import net.consensys.zkevm.domain.BlobStatus -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ProofToFinalize import net.consensys.zkevm.domain.createAggregation import net.consensys.zkevm.domain.createBatch diff --git a/coordinator/persistence/aggregation/src/main/kotlin/net/consensys/zkevm/persistence/dao/aggregation/PostgresAggregationsDao.kt b/coordinator/persistence/aggregation/src/main/kotlin/net/consensys/zkevm/persistence/dao/aggregation/PostgresAggregationsDao.kt index c900f2753..6b5ccba9a 100644 --- a/coordinator/persistence/aggregation/src/main/kotlin/net/consensys/zkevm/persistence/dao/aggregation/PostgresAggregationsDao.kt +++ b/coordinator/persistence/aggregation/src/main/kotlin/net/consensys/zkevm/persistence/dao/aggregation/PostgresAggregationsDao.kt @@ -1,5 +1,7 @@ package net.consensys.zkevm.persistence.dao.aggregation +import build.linea.domain.BlockIntervals +import build.linea.domain.toBlockIntervalsString import io.vertx.core.Future import io.vertx.pgclient.PgException import io.vertx.sqlclient.Row @@ -13,9 +15,7 @@ import net.consensys.zkevm.coordinator.clients.prover.serialization.ProofToFinal import net.consensys.zkevm.domain.Aggregation import net.consensys.zkevm.domain.BlobAndBatchCounters import net.consensys.zkevm.domain.BlobCounters -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ProofToFinalize -import net.consensys.zkevm.domain.toBlockIntervalsString import net.consensys.zkevm.persistence.db.DuplicatedRecordException import net.consensys.zkevm.persistence.db.SQLQueryLogger import org.apache.logging.log4j.Level diff --git a/coordinator/persistence/aggregation/src/test/kotlin/net/consensys/zkevm/persistence/dao/aggregation/RetryingPostgresAggregationsDaoTest.kt b/coordinator/persistence/aggregation/src/test/kotlin/net/consensys/zkevm/persistence/dao/aggregation/RetryingPostgresAggregationsDaoTest.kt index 3a706901e..7fc455d11 100644 --- a/coordinator/persistence/aggregation/src/test/kotlin/net/consensys/zkevm/persistence/dao/aggregation/RetryingPostgresAggregationsDaoTest.kt +++ b/coordinator/persistence/aggregation/src/test/kotlin/net/consensys/zkevm/persistence/dao/aggregation/RetryingPostgresAggregationsDaoTest.kt @@ -1,12 +1,12 @@ package net.consensys.zkevm.persistence.dao.aggregation +import build.linea.domain.BlockIntervals import io.vertx.core.Vertx import io.vertx.junit5.VertxExtension import kotlinx.datetime.Instant import net.consensys.FakeFixedClock import net.consensys.zkevm.domain.Aggregation import net.consensys.zkevm.domain.BlobAndBatchCounters -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.blobCounters import net.consensys.zkevm.domain.createAggregation import net.consensys.zkevm.domain.createProofToFinalize diff --git a/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinatorIntTest.kt b/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinatorIntTest.kt index 390c04d10..a38cc1fb1 100644 --- a/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinatorIntTest.kt +++ b/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/coordination/blob/BlobCompressionProofCoordinatorIntTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.ethereum.coordination.blob +import build.linea.domain.BlockIntervals import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.github.michaelbull.result.Ok @@ -15,7 +16,6 @@ import net.consensys.zkevm.coordinator.clients.BlobCompressionProverClientV2 import net.consensys.zkevm.coordinator.clients.GetZkEVMStateMerkleProofResponse import net.consensys.zkevm.coordinator.clients.Type2StateManagerClient import net.consensys.zkevm.domain.Blob -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ConflationCalculationResult import net.consensys.zkevm.domain.ConflationTrigger import net.consensys.zkevm.domain.createBlobRecord diff --git a/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/blob/BlobsPostgresDaoTest.kt b/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/blob/BlobsPostgresDaoTest.kt index b65fe6966..c5e20c028 100644 --- a/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/blob/BlobsPostgresDaoTest.kt +++ b/coordinator/persistence/blob/src/integrationTest/kotlin/net/consensys/zkevm/persistence/dao/blob/BlobsPostgresDaoTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.persistence.dao.blob +import build.linea.domain.BlockIntervals import io.vertx.junit5.VertxExtension import io.vertx.sqlclient.PreparedQuery import io.vertx.sqlclient.Row @@ -14,7 +15,6 @@ import net.consensys.trimToSecondPrecision import net.consensys.zkevm.coordinator.clients.BlobCompressionProof import net.consensys.zkevm.domain.BlobRecord import net.consensys.zkevm.domain.BlobStatus -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.createBlobRecord import net.consensys.zkevm.persistence.db.DbHelper import net.consensys.zkevm.persistence.db.DuplicatedRecordException diff --git a/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/ethereum/coordinator/blob/BlobCompressionProofCoordinatorTest.kt b/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/ethereum/coordinator/blob/BlobCompressionProofCoordinatorTest.kt index cdcd2e0ac..416356d30 100644 --- a/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/ethereum/coordinator/blob/BlobCompressionProofCoordinatorTest.kt +++ b/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/ethereum/coordinator/blob/BlobCompressionProofCoordinatorTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.ethereum.coordinator.blob +import build.linea.domain.BlockIntervals import io.vertx.core.Vertx import io.vertx.junit5.VertxExtension import net.consensys.FakeFixedClock @@ -8,7 +9,6 @@ import net.consensys.zkevm.coordinator.clients.BlobCompressionProof import net.consensys.zkevm.coordinator.clients.BlobCompressionProofRequest import net.consensys.zkevm.coordinator.clients.BlobCompressionProverClientV2 import net.consensys.zkevm.domain.Blob -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.ConflationCalculationResult import net.consensys.zkevm.domain.ConflationTrigger import net.consensys.zkevm.ethereum.coordination.blob.BlobCompressionProofCoordinator diff --git a/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/persistence/dao/blob/RetryingBlobsPostgresDaoTest.kt b/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/persistence/dao/blob/RetryingBlobsPostgresDaoTest.kt index 2e663249d..1339ff8ad 100644 --- a/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/persistence/dao/blob/RetryingBlobsPostgresDaoTest.kt +++ b/coordinator/persistence/blob/src/test/kotlin/net/consensys/zkevm/persistence/dao/blob/RetryingBlobsPostgresDaoTest.kt @@ -1,5 +1,6 @@ package net.consensys.zkevm.persistence.dao.blob +import build.linea.domain.BlockIntervals import io.vertx.core.Vertx import io.vertx.junit5.VertxExtension import net.consensys.FakeFixedClock @@ -7,7 +8,6 @@ import net.consensys.setFirstByteToZero import net.consensys.trimToSecondPrecision import net.consensys.zkevm.coordinator.clients.BlobCompressionProof import net.consensys.zkevm.domain.BlobStatus -import net.consensys.zkevm.domain.BlockIntervals import net.consensys.zkevm.domain.createBlobRecord import net.consensys.zkevm.persistence.db.PersistenceRetryer import org.junit.jupiter.api.BeforeEach diff --git a/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/URIExtensions.kt b/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/URIExtensions.kt new file mode 100644 index 000000000..a4453ea7b --- /dev/null +++ b/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/URIExtensions.kt @@ -0,0 +1,16 @@ +package build.linea + +import java.net.URI + +fun URI.getPortWithSchemeDefaults(): Int { + return if (port != -1) { + port + } else { + when (scheme.lowercase()) { + "http" -> 80 + "https" -> 443 + // Focous on HTTP as it is what we need for now + else -> throw IllegalArgumentException("Unsupported scheme: $scheme") + } + } +} diff --git a/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/UrlExtensions.kt b/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/UrlExtensions.kt new file mode 100644 index 000000000..30a5e0f8e --- /dev/null +++ b/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/UrlExtensions.kt @@ -0,0 +1,16 @@ +package build.linea + +import java.net.URI + +fun URI.getPortWithSchemaDefaults(): Int { + return if (port != -1) { + port + } else { + when (scheme.lowercase()) { + "http" -> 80 + "https" -> 443 + // Focous on HTTP as it what we need for now + else -> throw IllegalArgumentException("Unsupported scheme: $scheme") + } + } +} diff --git a/jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/jvm/ResourcesUtil.kt b/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/jvm/ResourcesUtil.kt similarity index 95% rename from jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/jvm/ResourcesUtil.kt rename to jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/jvm/ResourcesUtil.kt index 232c8d5c2..6d7a2f461 100644 --- a/jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/jvm/ResourcesUtil.kt +++ b/jvm-libs/generic/extensions/kotlin/src/main/kotlin/build/linea/jvm/ResourcesUtil.kt @@ -1,4 +1,4 @@ -package net.consensys.jvm +package build.linea.jvm import java.io.File import java.nio.file.Files diff --git a/jvm-libs/generic/extensions/kotlin/src/test/kotlin/build/linea/URIExtensionsTest.kt b/jvm-libs/generic/extensions/kotlin/src/test/kotlin/build/linea/URIExtensionsTest.kt new file mode 100644 index 000000000..18701f6e2 --- /dev/null +++ b/jvm-libs/generic/extensions/kotlin/src/test/kotlin/build/linea/URIExtensionsTest.kt @@ -0,0 +1,20 @@ +package build.linea + +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import java.net.URI + +class URIExtensionsTest { + @Test + fun `getPortWithSchemaDefaults`() { + assertThat(URI.create("http://example.com").getPortWithSchemeDefaults()).isEqualTo(80) + assertThat(URI.create("https://example.com").getPortWithSchemeDefaults()).isEqualTo(443) + assertThat(URI.create("http://example.com:8080").getPortWithSchemeDefaults()).isEqualTo(8080) + assertThat(URI.create("https://example.com:8080").getPortWithSchemeDefaults()).isEqualTo(8080) + assertThat(URI.create("myschema://example.com:8080").getPortWithSchemeDefaults()).isEqualTo(8080) + assertThatThrownBy { (URI.create("mySchema://example.com").getPortWithSchemeDefaults()) } + .isInstanceOf(IllegalArgumentException::class.java) + .hasMessage("Unsupported scheme: mySchema") + } +} diff --git a/jvm-libs/linea/blob-compressor/src/test/kotlin/net/consensys/jvm/ResourcesUtilTest.kt b/jvm-libs/generic/extensions/kotlin/src/test/kotlin/build/linea/jvm/ResourcesUtilTest.kt similarity index 92% rename from jvm-libs/linea/blob-compressor/src/test/kotlin/net/consensys/jvm/ResourcesUtilTest.kt rename to jvm-libs/generic/extensions/kotlin/src/test/kotlin/build/linea/jvm/ResourcesUtilTest.kt index 8f732e861..a2afd0cc9 100644 --- a/jvm-libs/linea/blob-compressor/src/test/kotlin/net/consensys/jvm/ResourcesUtilTest.kt +++ b/jvm-libs/generic/extensions/kotlin/src/test/kotlin/build/linea/jvm/ResourcesUtilTest.kt @@ -1,6 +1,6 @@ -package net.consensys.jvm +package build.linea.jvm -import net.consensys.jvm.ResourcesUtil.copyResourceToTmpDir +import build.linea.jvm.ResourcesUtil.copyResourceToTmpDir import org.assertj.core.api.AssertionsForClassTypes.assertThat import org.junit.jupiter.api.Test import java.nio.file.Files diff --git a/jvm-libs/linea/blob-compressor/src/test/resources/root-resource.txt b/jvm-libs/generic/extensions/kotlin/src/test/resources/root-resource.txt similarity index 100% rename from jvm-libs/linea/blob-compressor/src/test/resources/root-resource.txt rename to jvm-libs/generic/extensions/kotlin/src/test/resources/root-resource.txt diff --git a/jvm-libs/linea/blob-compressor/src/test/resources/test/folder/nested-resource.txt b/jvm-libs/generic/extensions/kotlin/src/test/resources/test/folder/nested-resource.txt similarity index 100% rename from jvm-libs/linea/blob-compressor/src/test/resources/test/folder/nested-resource.txt rename to jvm-libs/generic/extensions/kotlin/src/test/resources/test/folder/nested-resource.txt diff --git a/jvm-libs/linea/blob-compressor/src/test/resources/test/folder2/nested-resource.txt b/jvm-libs/generic/extensions/kotlin/src/test/resources/test/folder2/nested-resource.txt similarity index 100% rename from jvm-libs/linea/blob-compressor/src/test/resources/test/folder2/nested-resource.txt rename to jvm-libs/generic/extensions/kotlin/src/test/resources/test/folder2/nested-resource.txt diff --git a/jvm-libs/generic/extensions/tuweni/build.gradle b/jvm-libs/generic/extensions/tuweni/build.gradle new file mode 100644 index 000000000..abbc14918 --- /dev/null +++ b/jvm-libs/generic/extensions/tuweni/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'net.consensys.zkevm.kotlin-library-conventions' +} + +dependencies { + api "io.tmio:tuweni-bytes:${libs.versions.tuweni.get()}" + implementation(project(':jvm-libs:generic:extensions:kotlin')) + testImplementation "io.tmio:tuweni-units:${libs.versions.tuweni.get()}" +} diff --git a/jvm-libs/generic/extensions/tuweni/src/main/kotlin/build/linea/tuweni/Bytes32.kt b/jvm-libs/generic/extensions/tuweni/src/main/kotlin/build/linea/tuweni/Bytes32.kt new file mode 100644 index 000000000..2c9336aa3 --- /dev/null +++ b/jvm-libs/generic/extensions/tuweni/src/main/kotlin/build/linea/tuweni/Bytes32.kt @@ -0,0 +1,9 @@ +package build.linea.tuweni + +import net.consensys.toULong +import org.apache.tuweni.bytes.Bytes32 +import java.math.BigInteger + +fun ByteArray.toBytes32(): Bytes32 = Bytes32.wrap(this) +fun ByteArray.sliceAsBytes32(sliceIndex: Int): Bytes32 = Bytes32.wrap(this, /*offset*/sliceIndex * 32) +fun Bytes32.toULong(): ULong = BigInteger(this.toArray()).toULong() diff --git a/jvm-libs/generic/extensions/tuweni/src/test/kotlin/build/linea/tuweni/Bytes32Test.kt b/jvm-libs/generic/extensions/tuweni/src/test/kotlin/build/linea/tuweni/Bytes32Test.kt new file mode 100644 index 000000000..87d176137 --- /dev/null +++ b/jvm-libs/generic/extensions/tuweni/src/test/kotlin/build/linea/tuweni/Bytes32Test.kt @@ -0,0 +1,40 @@ +package build.linea.tuweni + +import net.consensys.toBigInteger +import org.apache.tuweni.bytes.Bytes32 +import org.apache.tuweni.units.bigints.UInt256 +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import kotlin.random.Random + +class Bytes32Test { + @BeforeEach + fun setUp() { + // workaround: need this to load the functions otherwise JUNit gets stuck ¯\_(ツ)_/¯ + Random.Default.nextBytes(32).sliceAsBytes32(0) + UInt256.ZERO.toBytes().toULong() + } + + @Test + fun testSliceAsBytes32() { + val bytes = Random.Default.nextBytes(3 * 32 - 1) + assertThat(bytes.sliceAsBytes32(0)).isEqualTo(Bytes32.wrap(bytes, 0)) + assertThat(bytes.sliceAsBytes32(1)).isEqualTo(Bytes32.wrap(bytes, 32)) + assertThatThrownBy { bytes.sliceAsBytes32(2) } + .isInstanceOf(IllegalArgumentException::class.java) + } + + @Test + fun testToULong() { + UInt256.ZERO.toBytes() + .also { bytes -> assertThat(bytes.toULong()).isEqualTo(0uL) } + UInt256.valueOf(Long.MAX_VALUE) + .also { bytes -> assertThat(bytes.toULong()).isEqualTo(Long.MAX_VALUE.toULong()) } + UInt256.valueOf(Long.MAX_VALUE).add(UInt256.ONE) + .also { bytes -> assertThat(bytes.toULong()).isEqualTo(Long.MAX_VALUE.toULong() + 1UL) } + UInt256.valueOf(ULong.MAX_VALUE.toBigInteger()) + .also { bytes -> assertThat(bytes.toULong()).isEqualTo(ULong.MAX_VALUE) } + } +} diff --git a/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClientFactory.kt b/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClientFactory.kt index 21687a62d..01b2dfd5d 100644 --- a/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClientFactory.kt +++ b/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClientFactory.kt @@ -150,7 +150,6 @@ class VertxHttpJsonRpcClientFactory( } fun createV2( - vertx: Vertx, endpoints: Set, maxInflightRequestsPerClient: UInt? = null, retryConfig: RequestRetryConfig, diff --git a/jvm-libs/generic/json-rpc/src/test/kotlin/net/consensys/linea/jsonrpc/client/JsonRpcV2ClientImplTest.kt b/jvm-libs/generic/json-rpc/src/test/kotlin/net/consensys/linea/jsonrpc/client/JsonRpcV2ClientImplTest.kt index c6a008993..df85c7e52 100644 --- a/jvm-libs/generic/json-rpc/src/test/kotlin/net/consensys/linea/jsonrpc/client/JsonRpcV2ClientImplTest.kt +++ b/jvm-libs/generic/json-rpc/src/test/kotlin/net/consensys/linea/jsonrpc/client/JsonRpcV2ClientImplTest.kt @@ -78,7 +78,6 @@ class JsonRpcV2ClientImplTest { ) private fun createClientAndSetupWireMockServer( - vertx: Vertx, responseObjectMapper: ObjectMapper = defaultObjectMapper, requestObjectMapper: ObjectMapper = defaultObjectMapper, retryConfig: RequestRetryConfig = defaultRetryConfig, @@ -89,7 +88,6 @@ class JsonRpcV2ClientImplTest { endpoint = URI(wiremock.baseUrl() + path).toURL() return factory.createV2( - vertx = vertx, endpoints = setOf(endpoint), retryConfig = retryConfig, requestObjectMapper = requestObjectMapper, @@ -103,7 +101,7 @@ class JsonRpcV2ClientImplTest { this.vertx = vertx this.meterRegistry = SimpleMeterRegistry() this.factory = VertxHttpJsonRpcClientFactory(vertx, meterRegistry) - this.client = createClientAndSetupWireMockServer(vertx) + this.client = createClientAndSetupWireMockServer() } @AfterEach @@ -192,7 +190,7 @@ class JsonRpcV2ClientImplTest { fun `request params shall use defined objectMapper and not affect json-rpc envelope`() { val obj = User(name = "John", email = "email@example.com", address = "0x01ffbb".decodeHex(), value = 987UL) - createClientAndSetupWireMockServer(vertx, requestObjectMapper = defaultObjectMapper).also { client -> + createClientAndSetupWireMockServer(requestObjectMapper = defaultObjectMapper).also { client -> replyRequestWith(200, jsonRpcResultOk) client.makeRequest( method = "someMethod", @@ -223,7 +221,7 @@ class JsonRpcV2ClientImplTest { } ) - createClientAndSetupWireMockServer(vertx, requestObjectMapper = objMapperWithNumbersAsHex).also { client -> + createClientAndSetupWireMockServer(requestObjectMapper = objMapperWithNumbersAsHex).also { client -> replyRequestWith(200, jsonRpcResultOk) client.makeRequest( method = "someMethod", @@ -456,7 +454,6 @@ class JsonRpcV2ClientImplTest { @Test fun `when it gets an error propagates to shallRetryRequestPredicate and retries while is true`() { createClientAndSetupWireMockServer( - vertx, retryConfig = retryConfig(maxRetries = 10u) ).also { client -> val responses = listOf( @@ -507,7 +504,6 @@ class JsonRpcV2ClientImplTest { @Test fun `when it has connection error propagates to shallRetryRequestPredicate and retries while is true`() { createClientAndSetupWireMockServer( - vertx, retryConfig = retryConfig(maxRetries = 10u) ).also { client -> // stop the server to simulate connection error @@ -543,7 +539,6 @@ class JsonRpcV2ClientImplTest { @Test fun `when it has connection error propagates to shallRetryRequestPredicate and retries until retry config elapses`() { createClientAndSetupWireMockServer( - vertx, retryConfig = retryConfig(maxRetries = 2u, timeout = 8.seconds, backoffDelay = 5.milliseconds) ).also { client -> // stop the server to simulate connection error @@ -580,7 +575,6 @@ class JsonRpcV2ClientImplTest { (it.value as String).startsWith("retry_a") } createClientAndSetupWireMockServer( - vertx, retryConfig = RequestRetryConfig( maxRetries = 10u, timeout = 5.minutes, diff --git a/jvm-libs/generic/vertx-helper/build.gradle b/jvm-libs/generic/vertx-helper/build.gradle index d2cf40bb7..7e77bfca7 100644 --- a/jvm-libs/generic/vertx-helper/build.gradle +++ b/jvm-libs/generic/vertx-helper/build.gradle @@ -3,6 +3,7 @@ plugins { } dependencies { + implementation project(':jvm-libs:generic:extensions:kotlin') implementation project(':jvm-libs:generic:extensions:futures') implementation "io.vertx:vertx-core" implementation "io.vertx:vertx-web" diff --git a/jvm-libs/generic/vertx-helper/src/main/kotlin/net/consensys/linea/vertx/ClientOptions.kt b/jvm-libs/generic/vertx-helper/src/main/kotlin/net/consensys/linea/vertx/ClientOptions.kt new file mode 100644 index 000000000..3f46023c9 --- /dev/null +++ b/jvm-libs/generic/vertx-helper/src/main/kotlin/net/consensys/linea/vertx/ClientOptions.kt @@ -0,0 +1,13 @@ +package net.consensys.linea.vertx + +import build.linea.getPortWithSchemeDefaults +import io.vertx.core.http.HttpClientOptions +import java.net.URI + +fun T.setDefaultsFrom(uri: URI): T { + isSsl = uri.scheme.lowercase() == "https" + defaultHost = uri.host + defaultPort = uri.getPortWithSchemeDefaults() + + return this +} diff --git a/jvm-libs/linea/blob-compressor/build.gradle b/jvm-libs/linea/blob-compressor/build.gradle index c2281e817..0c9cb129f 100644 --- a/jvm-libs/linea/blob-compressor/build.gradle +++ b/jvm-libs/linea/blob-compressor/build.gradle @@ -10,7 +10,7 @@ apply from: rootProject.file("gradle/publishing.gradle") dependencies { implementation "net.java.dev.jna:jna:${libs.versions.jna.get()}" - testImplementation project(":jvm-libs:generic:extensions:kotlin") + implementation project(":jvm-libs:generic:extensions:kotlin") testImplementation project(":jvm-libs:linea:blob-shnarf-calculator") } diff --git a/jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobCompressor.kt b/jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobCompressor.kt index bb21ba126..99a37939a 100644 --- a/jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobCompressor.kt +++ b/jvm-libs/linea/blob-compressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobCompressor.kt @@ -1,8 +1,8 @@ package net.consensys.linea.blob +import build.linea.jvm.ResourcesUtil.copyResourceToTmpDir import com.sun.jna.Library import com.sun.jna.Native -import net.consensys.jvm.ResourcesUtil.copyResourceToTmpDir interface GoNativeBlobCompressor { diff --git a/jvm-libs/linea/blob-compressor/src/test/resources/net/consensys/linea/nativecompressor/rlp_blocks.bin b/jvm-libs/linea/blob-compressor/src/test/resources/net/consensys/linea/nativecompressor/rlp_blocks.bin deleted file mode 100644 index 82c04c3ff..000000000 Binary files a/jvm-libs/linea/blob-compressor/src/test/resources/net/consensys/linea/nativecompressor/rlp_blocks.bin and /dev/null differ diff --git a/jvm-libs/linea/blob-decompressor/build.gradle b/jvm-libs/linea/blob-decompressor/build.gradle new file mode 100644 index 000000000..2a085ddb9 --- /dev/null +++ b/jvm-libs/linea/blob-decompressor/build.gradle @@ -0,0 +1,58 @@ +plugins { + id 'net.consensys.zkevm.kotlin-library-conventions' + id 'net.consensys.zkevm.linea-native-libs-helper' + alias(libs.plugins.jreleaser) + id 'java-test-fixtures' +} + +description = 'Java JNA wrapper for Linea Blob Decompressor Library implemented in GO Lang' +apply from: rootProject.file("gradle/publishing.gradle") + +dependencies { + implementation "net.java.dev.jna:jna:${libs.versions.jna.get()}" + implementation project(":jvm-libs:generic:extensions:kotlin") + + testImplementation project(":jvm-libs:linea:blob-compressor") + testImplementation(testFixtures(project(":jvm-libs:linea:blob-compressor"))) + testImplementation(project(":jvm-libs:linea:testing:file-system")) + testImplementation("io.tmio:tuweni-bytes:${libs.versions.tuweni.get()}") + testImplementation("org.hyperledger.besu:besu-datatypes:${libs.versions.besu.get()}") + testImplementation "org.hyperledger.besu:evm:${libs.versions.besu.get()}" + testImplementation("org.hyperledger.besu.internal:core:${libs.versions.besu.get()}") + testImplementation("org.hyperledger.besu:plugin-api:${libs.versions.besu.get()}") + testImplementation("org.hyperledger.besu.internal:rlp:${libs.versions.besu.get()}") +} + +jar { + dependsOn configurations.runtimeClasspath +} + +test { + // we cannot have more 1 compressor per JVM, hence we disable parallel execution + // because multiple threads would cause issues with the native library + systemProperties["junit.jupiter.execution.parallel.enabled"] = false + maxParallelForks = 1 +} + +def libsZipDownloadOutputDir = project.parent.layout.buildDirectory.asFile.get().absolutePath + +task downloadNativeLibs { + doLast { + fetchLibFromZip("https://github.com/Consensys/linea-monorepo/releases/download/blob-libs-v1.1.0-test8/linea-blob-libs-v1.1.0-test8.zip", "blob_decompressor", libsZipDownloadOutputDir) + } +} + +compileKotlin { + dependsOn tasks.downloadNativeLibs +} + +task cleanResources(type: Delete) { + fileTree(project.layout.projectDirectory.dir('src/main/resources')) + .filter { + it.name.endsWith(".so") || it.name.endsWith(".dll") || it.name.endsWith(".dylib") + }.each { + delete it + } +} + +clean.dependsOn cleanResources diff --git a/jvm-libs/linea/blob-decompressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobDecompressor.kt b/jvm-libs/linea/blob-decompressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobDecompressor.kt new file mode 100644 index 000000000..fa78dca2c --- /dev/null +++ b/jvm-libs/linea/blob-decompressor/src/main/kotlin/net/consensys/linea/blob/GoNativeBlobDecompressor.kt @@ -0,0 +1,105 @@ +package net.consensys.linea.blob + +import build.linea.jvm.ResourcesUtil.copyResourceToTmpDir +import com.sun.jna.Library +import com.sun.jna.Native +import java.nio.file.Path + +class DecompressionException(message: String) : RuntimeException(message) + +interface BlobDecompressor { + fun decompress(blob: ByteArray): ByteArray +} + +internal class Adapter( + private val delegate: GoNativeBlobDecompressorJnaBinding, + private val maxExpectedCompressionRatio: Int = 10, + dictionaries: List +) : BlobDecompressor { + init { + delegate.Init() + + val paths = dictionaries.joinToString(separator = ":") { path -> path.toString() } + + if (delegate.LoadDictionaries(paths) != dictionaries.size) { + throw DecompressionException("Failed to load dictionaries '$paths', error='${delegate.Error()}'") + } + } + + override fun decompress(blob: ByteArray): ByteArray { + val decompressionBuffer = ByteArray(blob.size * maxExpectedCompressionRatio) + val decompressedSize = delegate.Decompress(blob, blob.size, decompressionBuffer, decompressionBuffer.size) + if (decompressedSize < 0) { + throw DecompressionException("Decompression failed, error='${delegate.Error()}'") + } + return decompressionBuffer.copyOf(decompressedSize) + } +} + +internal interface GoNativeBlobDecompressorJnaBinding { + + /** + * Init initializes the Decompressor. Must be run before anything else. + */ + fun Init() + + /** + * LoadDictionaries attempts to cache dictionaries from given paths, separated by colons, + * e.g. "../compressor_dict.bin:./other_dict" + * Returns the number of dictionaries successfully loaded, and -1 in case of failure, in which case Error() will + * return a description of the error. + * + * @param dictPaths a colon-separated list of paths to dictionaries, to be loaded into the decompressor + * @return the number of dictionaries loaded if successful, -1 if not. + */ + fun LoadDictionaries(dictPaths: String): Int + + /** + + * Decompress processes a Linea blob and outputs an RLP encoded list of blocks. + * Due to information loss during pre-compression encoding, two pieces of information are represented "hackily": + * The block hash is in the ParentHash field. + * The transaction from address is in the signature.R field. + * + * Returns the number of bytes in out, or -1 in case of failure + * If -1 is returned, the Error() method will return a string describing the error. + * + * @param blob to be decompressed + * @param blob_len length of the blob + * @param out buffer to write the decompressed data + * @param out_max_len maximum length of the out buffer + * @return number of bytes in out, or -1 in case of failure + */ + fun Decompress(blob: ByteArray, blob_len: Int, out: ByteArray, out_max_len: Int): Int + + /** + * Error returns the last error message. Should be checked if Write returns false. + */ + fun Error(): String? +} + +internal interface GoNativeBlobDecompressorJnaLib : GoNativeBlobDecompressorJnaBinding, Library + +enum class BlobDecompressorVersion(val version: String) { + V1_1_0("v1.1.0") +} + +class GoNativeBlobDecompressorFactory { + companion object { + private const val DICTIONARY_NAME = "compressor_dict.bin" + private val dictionaryPath = copyResourceToTmpDir(DICTIONARY_NAME) + + private fun getLibFileName(version: String) = "blob_decompressor_jna_$version" + + fun getInstance( + version: BlobDecompressorVersion + ): BlobDecompressor { + return Native.load( + Native.extractFromResourcePath(getLibFileName(version.version)).toString(), + GoNativeBlobDecompressorJnaLib::class.java + ).let { + Adapter(delegate = it, dictionaries = listOf(dictionaryPath)) + } + } + } +} diff --git a/jvm-libs/linea/blob-decompressor/src/main/resources/.gitignore b/jvm-libs/linea/blob-decompressor/src/main/resources/.gitignore new file mode 100644 index 000000000..272f436b7 --- /dev/null +++ b/jvm-libs/linea/blob-decompressor/src/main/resources/.gitignore @@ -0,0 +1,4 @@ +linux-aarch64/* +linux-x86-64/* +darwin-aarch64/* +darwin-x86-64/* diff --git a/jvm-libs/linea/blob-decompressor/src/main/resources/compressor_dict.bin b/jvm-libs/linea/blob-decompressor/src/main/resources/compressor_dict.bin new file mode 100644 index 000000000..62296498c Binary files /dev/null and b/jvm-libs/linea/blob-decompressor/src/main/resources/compressor_dict.bin differ diff --git a/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/BlobDecompressorDataDecodingTest.kt b/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/BlobDecompressorDataDecodingTest.kt new file mode 100644 index 000000000..38c514ca9 --- /dev/null +++ b/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/BlobDecompressorDataDecodingTest.kt @@ -0,0 +1,50 @@ +package net.consensys.linea.blob + +import net.consensys.linea.testing.filesystem.findPathTo +import org.apache.tuweni.bytes.Bytes +import org.assertj.core.api.Assertions.assertThat +import org.hyperledger.besu.ethereum.core.Block +import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions +import org.hyperledger.besu.ethereum.rlp.RLP +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import kotlin.io.path.readBytes + +class BlobDecompressorDataDecodingTest { + private lateinit var decompressor: BlobDecompressor + + @BeforeEach + fun beforeEach() { + decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_1_0) + } + + @Test + fun `can deserialize native lib testdata blobs`() { + val blob = findPathTo("prover")!! + .resolve("lib/compressor/blob/testdata/v0/sample-blob-0151eda71505187b5.bin") + .readBytes() + val decompressedBlob = decompressor.decompress(blob) + val blocksRlpEncoded = rlpDecodeAsListOfBytes(decompressedBlob) + assertThat(blocksRlpEncoded).hasSize(254) + // TODO: enable after Besu supports deserializing transactions without signatures validation + // + // blocksRlpEncoded.forEachIndexed { index, blockRlp -> + // val rlpInput = RLP.input(Bytes.wrap(blockRlp)) + // val decodedBlock = Block.readFrom(rlpInput, MainnetBlockHeaderFunctions()) + // println("$index: $decodedBlock") + // } + } + + @Disabled("for local dev validation") + fun `can decode RLP`() { + val blockBytes = Bytes.wrap( + // INSERT HERE THE RLP ENCODED BLOCK + // 0x01ff.decodeHex() + ) + RLP.validate(blockBytes) + val rlpInput = RLP.input(blockBytes) + val decodedBlock = Block.readFrom(rlpInput, MainnetBlockHeaderFunctions()) + println(decodedBlock) + } +} diff --git a/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/GoNativeBlobDecompressorTest.kt b/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/GoNativeBlobDecompressorTest.kt new file mode 100644 index 000000000..0d1454d8e --- /dev/null +++ b/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/GoNativeBlobDecompressorTest.kt @@ -0,0 +1,42 @@ +package net.consensys.linea.blob + +import net.consensys.linea.nativecompressor.CompressorTestData +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class GoNativeBlobDecompressorTest { + private val blobCompressedLimit = 10 * 1024 + private lateinit var compressor: GoNativeBlobCompressor + private lateinit var decompressor: BlobDecompressor + + @BeforeEach + fun beforeEach() { + compressor = GoNativeBlobCompressorFactory + .getInstance(BlobCompressorVersion.V1_0_1) + .apply { + Init( + dataLimit = blobCompressedLimit, + dictPath = GoNativeBlobCompressorFactory.dictionaryPath.toAbsolutePath().toString() + ) + Reset() + } + decompressor = GoNativeBlobDecompressorFactory.getInstance(BlobDecompressorVersion.V1_1_0) + } + + @Test + fun `when blocks are compressed with compressor shall decompress them back`() { + val blocks = CompressorTestData.blocksRlpEncoded + assertTrue(compressor.Write(blocks[0], blocks[0].size)) + assertTrue(compressor.Write(blocks[1], blocks[1].size)) + + val compressedData = ByteArray(compressor.Len()) + compressor.Bytes(compressedData) + + val decompressedBlob = decompressor.decompress(compressedData) + assertThat(decompressedBlob.size).isGreaterThan(compressedData.size) + val decompressedBlocks: List = rlpDecodeAsListOfBytes(decompressedBlob) + assertThat(decompressedBlocks).hasSize(2) + } +} diff --git a/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/RLPHelper.kt b/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/RLPHelper.kt new file mode 100644 index 000000000..ba8554bf5 --- /dev/null +++ b/jvm-libs/linea/blob-decompressor/src/test/kotlin/net/consensys/linea/blob/RLPHelper.kt @@ -0,0 +1,26 @@ +package net.consensys.linea.blob + +import org.apache.tuweni.bytes.Bytes +import org.hyperledger.besu.ethereum.rlp.RLP + +internal fun rlpEncode(list: List): ByteArray { + return RLP.encode { rlpWriter -> + rlpWriter.startList() + list.forEach { bytes -> + rlpWriter.writeBytes(Bytes.wrap(bytes)) + } + rlpWriter.endList() + }.toArray() +} + +internal fun rlpDecodeAsListOfBytes(rlpEncoded: ByteArray): List { + val decodedBytes = mutableListOf() + RLP.input(Bytes.wrap(rlpEncoded), true).also { rlpInput -> + rlpInput.enterList() + while (!rlpInput.isEndOfCurrentList) { + decodedBytes.add(rlpInput.readBytes().toArray()) + } + rlpInput.leaveList() + } + return decodedBytes +} diff --git a/jvm-libs/linea/clients/linea-state-manager/build.gradle b/jvm-libs/linea/clients/linea-state-manager/build.gradle new file mode 100644 index 000000000..55a647453 --- /dev/null +++ b/jvm-libs/linea/clients/linea-state-manager/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'net.consensys.zkevm.kotlin-library-conventions' +} + +dependencies { + api project(':jvm-libs:linea:core:domain-models') + api project(':jvm-libs:linea:core:metrics') + api project(':jvm-libs:linea:core:client-interface') + api project(':jvm-libs:generic:json-rpc') + api project(':jvm-libs:generic:errors') + api project(':jvm-libs:generic:extensions:futures') + api project(':jvm-libs:generic:extensions:kotlin') + api "io.tmio:tuweni-bytes:${libs.versions.tuweni.get()}" + + implementation "com.fasterxml.jackson.core:jackson-annotations:${libs.versions.jackson.get()}" + implementation "com.fasterxml.jackson.core:jackson-databind:${libs.versions.jackson.get()}" + implementation "com.fasterxml.jackson.module:jackson-module-kotlin:${libs.versions.jackson.get()}" + + testImplementation(project(":jvm-libs:linea:testing:file-system")) + testImplementation "io.vertx:vertx-junit5" + testImplementation "com.github.tomakehurst:wiremock-jre8:${libs.versions.wiremock.get()}" +} diff --git a/jvm-libs/linea/clients/linea-state-manager/src/main/kotlin/build/linea/clients/StateManagerClientV1.kt b/jvm-libs/linea/clients/linea-state-manager/src/main/kotlin/build/linea/clients/StateManagerClientV1.kt new file mode 100644 index 000000000..475bdb02d --- /dev/null +++ b/jvm-libs/linea/clients/linea-state-manager/src/main/kotlin/build/linea/clients/StateManagerClientV1.kt @@ -0,0 +1,87 @@ +package build.linea.clients + +import build.linea.domain.BlockInterval +import com.fasterxml.jackson.databind.node.ArrayNode +import com.github.michaelbull.result.Result +import net.consensys.encodeHex +import net.consensys.linea.errors.ErrorResponse +import tech.pegasys.teku.infrastructure.async.SafeFuture + +enum class StateManagerErrorType : ClientError { + UNKNOWN, + UNSUPPORTED_VERSION, + BLOCK_MISSING_IN_CHAIN +} + +sealed interface StateManagerRequest +sealed class GetChainHeadRequest() : StateManagerRequest +data class GetStateMerkleProofRequest( + val blockInterval: BlockInterval +) : StateManagerRequest, BlockInterval by blockInterval + +sealed interface StateManagerResponse + +data class GetZkEVMStateMerkleProofResponse( + val zkStateMerkleProof: ArrayNode, + val zkParentStateRootHash: ByteArray, + val zkEndStateRootHash: ByteArray, + val zkStateManagerVersion: String +) : StateManagerResponse { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as GetZkEVMStateMerkleProofResponse + + if (zkStateMerkleProof != other.zkStateMerkleProof) return false + if (!zkParentStateRootHash.contentEquals(other.zkParentStateRootHash)) return false + if (!zkEndStateRootHash.contentEquals(other.zkEndStateRootHash)) return false + if (zkStateManagerVersion != other.zkStateManagerVersion) return false + + return true + } + + override fun hashCode(): Int { + var result = zkStateMerkleProof.hashCode() + result = 31 * result + zkParentStateRootHash.contentHashCode() + result = 31 * result + zkEndStateRootHash.contentHashCode() + result = 31 * result + zkStateManagerVersion.hashCode() + return result + } + + override fun toString(): String { + return "GetZkEVMStateMerkleProofResponse(" + + "zkStateMerkleProof=$zkStateMerkleProof, zkParentStateRootHash=${zkParentStateRootHash.encodeHex()}, " + + "zkEndStateRootHash=${zkEndStateRootHash.encodeHex()}, " + + "zkStateManagerVersion='$zkStateManagerVersion')" + } +} + +// Type alias dedicated for each method +typealias StateManagerClientToGetStateMerkleProofV0 = + AsyncClient + +typealias StateManagerClientToGetChainHeadV1 = + AsyncClient + +interface StateManagerClientV1 { + /** + * Get the head block number of the chain. + * @return GetZkEVMStateMerkleProofResponse + * @throws ClientException with errorType StateManagerErrorType when know error occurs + */ + fun rollupGetStateMerkleProof( + blockInterval: BlockInterval + ): SafeFuture = rollupGetStateMerkleProofWithTypedError(blockInterval) + .unwrapResultMonad() + + /** + * This is for backward compatibility with the old version in the coordinator side. + * This error typing is not really usefull anymore + */ + fun rollupGetStateMerkleProofWithTypedError( + blockInterval: BlockInterval + ): SafeFuture>> + + fun rollupGetHeadBlockNumber(): SafeFuture +} diff --git a/jvm-libs/linea/clients/linea-state-manager/src/main/kotlin/build/linea/clients/StateManagerV1JsonRpcClient.kt b/jvm-libs/linea/clients/linea-state-manager/src/main/kotlin/build/linea/clients/StateManagerV1JsonRpcClient.kt new file mode 100644 index 000000000..dadb3f9b6 --- /dev/null +++ b/jvm-libs/linea/clients/linea-state-manager/src/main/kotlin/build/linea/clients/StateManagerV1JsonRpcClient.kt @@ -0,0 +1,109 @@ +package build.linea.clients + +import build.linea.domain.BlockInterval +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ArrayNode +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok +import com.github.michaelbull.result.Result +import io.vertx.core.json.JsonObject +import net.consensys.decodeHex +import net.consensys.fromHexString +import net.consensys.linea.errors.ErrorResponse +import net.consensys.linea.jsonrpc.JsonRpcErrorResponseException +import net.consensys.linea.jsonrpc.client.JsonRpcV2Client +import org.apache.logging.log4j.LogManager +import org.apache.logging.log4j.Logger +import tech.pegasys.teku.infrastructure.async.SafeFuture + +class StateManagerV1JsonRpcClient( + private val rpcClient: JsonRpcV2Client, + private val zkStateManagerVersion: String +) : StateManagerClientV1 { + private val log: Logger = LogManager.getLogger(this::class.java) + + override fun rollupGetHeadBlockNumber(): SafeFuture { + return rpcClient + .makeRequest( + method = "rollup_getZkEVMBlockNumber", + params = emptyList(), + shallRetryRequestPredicate = { it is Err }, + resultMapper = { ULong.fromHexString(it as String) } + ) + } + + override fun rollupGetStateMerkleProof(blockInterval: BlockInterval): SafeFuture { + val params = listOf( + JsonObject.of( + "startBlockNumber", + blockInterval.startBlockNumber.toLong(), + "endBlockNumber", + blockInterval.endBlockNumber.toLong(), + "zkStateManagerVersion", + zkStateManagerVersion + ) + ) + + return rpcClient + .makeRequest( + method = "rollup_getZkEVMStateMerkleProofV0", + params = params, + shallRetryRequestPredicate = { it is Err }, + resultMapper = { it as JsonNode; parseZkEVMStateMerkleProofResponse(it) } + ) + } + + override fun rollupGetStateMerkleProofWithTypedError( + blockInterval: BlockInterval + ): SafeFuture>> { + return rollupGetStateMerkleProof(blockInterval) + .handleComposed { result, th -> + if (th != null) { + if (th is JsonRpcErrorResponseException) { + SafeFuture.completedFuture(Err(mapErrorResponse(th))) + } else { + SafeFuture.failedFuture(th) + } + } else { + SafeFuture.completedFuture(Ok(result)) + } + } + } + + private fun mapErrorResponse( + jsonRpcErrorResponse: JsonRpcErrorResponseException + ): ErrorResponse { + val errorType = + try { + StateManagerErrorType.valueOf( + jsonRpcErrorResponse.rpcErrorMessage.substringBefore('-').trim() + ) + } catch (_: Exception) { + log.error( + "State manager found unrecognised JSON-RPC response error: {}", + jsonRpcErrorResponse.rpcErrorMessage + ) + StateManagerErrorType.UNKNOWN + } + + return ErrorResponse( + errorType, + listOfNotNull( + jsonRpcErrorResponse.rpcErrorMessage, + jsonRpcErrorResponse.rpcErrorData?.toString() + ) + .joinToString(": ") + ) + } + + private fun parseZkEVMStateMerkleProofResponse( + result: JsonNode + ): GetZkEVMStateMerkleProofResponse { + return GetZkEVMStateMerkleProofResponse( + zkStateManagerVersion = result.get("zkStateManagerVersion").asText(), + zkStateMerkleProof = result.get("zkStateMerkleProof") as ArrayNode, + zkParentStateRootHash = result.get("zkParentStateRootHash").asText().decodeHex(), + zkEndStateRootHash = result.get("zkEndStateRootHash").asText().decodeHex() + ) + } +} diff --git a/jvm-libs/linea/clients/linea-state-manager/src/test/kotlin/build/linea/clients/StateManagerV1JsonRpcClientTest.kt b/jvm-libs/linea/clients/linea-state-manager/src/test/kotlin/build/linea/clients/StateManagerV1JsonRpcClientTest.kt new file mode 100644 index 000000000..4e618e210 --- /dev/null +++ b/jvm-libs/linea/clients/linea-state-manager/src/test/kotlin/build/linea/clients/StateManagerV1JsonRpcClientTest.kt @@ -0,0 +1,215 @@ +package build.linea.clients + +import build.linea.domain.BlockInterval +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.WireMock.containing +import com.github.tomakehurst.wiremock.client.WireMock.ok +import com.github.tomakehurst.wiremock.client.WireMock.post +import com.github.tomakehurst.wiremock.core.WireMockConfiguration.options +import io.micrometer.core.instrument.simple.SimpleMeterRegistry +import io.vertx.core.Vertx +import io.vertx.junit5.VertxExtension +import net.consensys.decodeHex +import net.consensys.fromHexString +import net.consensys.linea.async.get +import net.consensys.linea.errors.ErrorResponse +import net.consensys.linea.jsonrpc.client.RequestRetryConfig +import net.consensys.linea.jsonrpc.client.VertxHttpJsonRpcClientFactory +import net.consensys.linea.testing.filesystem.findPathTo +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.net.URI +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds +import kotlin.time.toJavaDuration + +@ExtendWith(VertxExtension::class) +class StateManagerV1JsonRpcClientTest { + private lateinit var wiremock: WireMockServer + private lateinit var stateManagerClient: StateManagerV1JsonRpcClient + private lateinit var meterRegistry: SimpleMeterRegistry + + private fun wiremockStubForPost(response: String) { + wiremock.stubFor( + post("/") + .withHeader("Content-Type", containing("application/json")) + .willReturn( + ok() + .withHeader("Content-type", "application/json") + .withBody(response.toByteArray()) + ) + ) + } + + @BeforeEach + fun setup(vertx: Vertx) { + wiremock = WireMockServer(options().dynamicPort()) + wiremock.start() + meterRegistry = SimpleMeterRegistry() + val rpcClientFactory = VertxHttpJsonRpcClientFactory(vertx, meterRegistry) + val vertxHttpJsonRpcClient = rpcClientFactory.createV2( + endpoints = setOf(URI("http://127.0.0.1:" + wiremock.port()).toURL()), + retryConfig = RequestRetryConfig( + maxRetries = 2u, + timeout = 2.seconds, + 10.milliseconds, + 1u + ) + ) + + stateManagerClient = + StateManagerV1JsonRpcClient( + rpcClient = vertxHttpJsonRpcClient, + zkStateManagerVersion = "0.1.2" + ) + } + + @AfterEach + fun tearDown(vertx: Vertx) { + val vertxStopFuture = vertx.close() + wiremock.stop() + vertxStopFuture.get() + } + + @Test + fun getZkEVMStateMerkleProof_success() { + val testFilePath = findPathTo("testdata")!!.resolve("type2state-manager/state-proof.json") + val json = jacksonObjectMapper().readTree(testFilePath.toFile()) + val zkStateManagerVersion = json.get("zkStateManagerVersion").asText() + val zkStateMerkleProof = json.get("zkStateMerkleProof") as ArrayNode + val zkParentStateRootHash = json.get("zkParentStateRootHash").asText() + val zkEndStateRootHash = json.get("zkEndStateRootHash").asText() + + wiremockStubForPost( + """ + { + "jsonrpc":"2.0", + "id":"1", + "result": { + "zkParentStateRootHash": "$zkParentStateRootHash", + "zkEndStateRootHash": "$zkEndStateRootHash", + "zkStateMerkleProof": $zkStateMerkleProof, + "zkStateManagerVersion": "$zkStateManagerVersion" + } + } + """ + ) + + assertThat(stateManagerClient.rollupGetStateMerkleProofWithTypedError(BlockInterval(50UL, 100UL))) + .succeedsWithin(5.seconds.toJavaDuration()) + .isEqualTo( + Ok( + GetZkEVMStateMerkleProofResponse( + zkStateManagerVersion = zkStateManagerVersion, + zkStateMerkleProof = zkStateMerkleProof, + zkParentStateRootHash = zkParentStateRootHash.decodeHex(), + zkEndStateRootHash = zkEndStateRootHash.decodeHex() + ) + ) + ) + } + + @Test + fun getZkEVMStateMerkleProof_error_block_missing() { + wiremockStubForPost( + """ + { + "jsonrpc":"2.0", + "id":"1", + "error":{ + "code":"-32600", + "message":"BLOCK_MISSING_IN_CHAIN - block 1 is missing" + } + }""" + ) + + assertThat(stateManagerClient.rollupGetStateMerkleProofWithTypedError(BlockInterval(50UL, 100UL))) + .succeedsWithin(5.seconds.toJavaDuration()) + .isEqualTo( + Err( + ErrorResponse( + StateManagerErrorType.BLOCK_MISSING_IN_CHAIN, + "BLOCK_MISSING_IN_CHAIN - block 1 is missing" + ) + ) + ) + } + + @Test + fun getZkEVMStateMerkleProof_error_unsupported_version() { + val response = """ + { + "jsonrpc":"2.0", + "id":"1", + "error":{ + "code":"-32602", + "message":"UNSUPPORTED_VERSION", + "data": { + "requestedVersion": "0.1.2", + "supportedVersion": "0.0.1-dev-3e607237" + } + } + }""" + + wiremockStubForPost(response) + + assertThat(stateManagerClient.rollupGetStateMerkleProofWithTypedError(BlockInterval(50UL, 100UL))) + .succeedsWithin(5.seconds.toJavaDuration()) + .isEqualTo( + Err( + ErrorResponse( + StateManagerErrorType.UNSUPPORTED_VERSION, + "UNSUPPORTED_VERSION: {requestedVersion=0.1.2, supportedVersion=0.0.1-dev-3e607237}" + ) + ) + ) + } + + @Test + fun getZkEVMStateMerkleProof_error_unknown() { + wiremockStubForPost( + """ + { + "jsonrpc":"2.0", + "id":"1", + "error":{ + "code":-999, + "message":"BRA_BRA_BRA_SOME_UNKNOWN_ERROR", + "data": {"xyz": "1234", "abc": 100} + } + }""" + ) + + assertThat(stateManagerClient.rollupGetStateMerkleProofWithTypedError(BlockInterval(50L, 100L))) + .succeedsWithin(5.seconds.toJavaDuration()) + .isEqualTo( + Err(ErrorResponse(StateManagerErrorType.UNKNOWN, """BRA_BRA_BRA_SOME_UNKNOWN_ERROR: {xyz=1234, abc=100}""")) + ) + } + + @Test + fun rollupGetHeadBlockNumber_success_response() { + wiremockStubForPost("""{"jsonrpc":"2.0","id":1,"result":"0xf1"}""") + + assertThat(stateManagerClient.rollupGetHeadBlockNumber().get()) + .isEqualTo(ULong.fromHexString("0xf1")) + } + + @Test + fun rollupGetHeadBlockNumber_error_response() { + val response = """{"jsonrpc":"2.0","id":1,"error":{"code": -32603, "message": "Internal error"}}""" + + wiremockStubForPost(response) + + assertThatThrownBy { stateManagerClient.rollupGetHeadBlockNumber().get() } + .hasMessageContaining("Internal error") + } +} diff --git a/jvm-libs/linea/core/client-interface/build.gradle b/jvm-libs/linea/core/client-interface/build.gradle new file mode 100644 index 000000000..1b9412c59 --- /dev/null +++ b/jvm-libs/linea/core/client-interface/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'net.consensys.zkevm.kotlin-library-conventions' +} + +dependencies { + implementation(project(':jvm-libs:generic:extensions:kotlin')) + implementation(project(':jvm-libs:linea:core:domain-models')) + implementation(project(':jvm-libs:generic:errors')) +} diff --git a/jvm-libs/linea/core/client-interface/src/main/kotlin/build/linea/clients/Client.kt b/jvm-libs/linea/core/client-interface/src/main/kotlin/build/linea/clients/Client.kt new file mode 100644 index 000000000..dc0688ee5 --- /dev/null +++ b/jvm-libs/linea/core/client-interface/src/main/kotlin/build/linea/clients/Client.kt @@ -0,0 +1,36 @@ +package build.linea.clients + +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok +import com.github.michaelbull.result.Result +import net.consensys.linea.errors.ErrorResponse +import tech.pegasys.teku.infrastructure.async.SafeFuture + +/** + * Marker interface for error types. + * Allow concrete clients to extend this interface to define their own error types. + */ +interface ClientError + +class ClientException( + override val message: String, + val errorType: ClientError? +) : + RuntimeException(errorType?.let { "errorType=$it $message" } ?: message) + +interface Client { + fun makeRequest(request: Request): Response +} + +interface AsyncClient { + fun makeRequest(request: Request): SafeFuture +} + +fun SafeFuture>>.unwrapResultMonad(): SafeFuture { + return this.thenCompose { + when (it) { + is Ok -> SafeFuture.completedFuture(it.value) + is Err -> SafeFuture.failedFuture(ClientException(it.error.message, it.error.type)) + } + } +} diff --git a/jvm-libs/linea/core/domain-models/src/main/kotlin/build/linea/domain/BlockInterval.kt b/jvm-libs/linea/core/domain-models/src/main/kotlin/build/linea/domain/BlockInterval.kt new file mode 100644 index 000000000..62a06ebc8 --- /dev/null +++ b/jvm-libs/linea/core/domain-models/src/main/kotlin/build/linea/domain/BlockInterval.kt @@ -0,0 +1,126 @@ +package build.linea.domain + +import net.consensys.isSortedBy +import net.consensys.linea.CommonDomainFunctions + +/** + * Represents a block interval, with inclusive start and end block numbers + * @property startBlockNumber start block number, inclusive + * @property endBlockNumber end block number, inclusive + */ +interface BlockInterval { + val startBlockNumber: ULong + val endBlockNumber: ULong + val blocksRange: ULongRange + get() = startBlockNumber..endBlockNumber + + fun intervalString(): String = CommonDomainFunctions.blockIntervalString(startBlockNumber, endBlockNumber) + + companion object { + operator fun invoke( + startBlockNumber: ULong, + endBlockNumber: ULong + ): BlockInterval { + return BlockIntervalData(startBlockNumber, endBlockNumber) + } + + operator fun invoke( + startBlockNumber: Number, + endBlockNumber: Number + ): BlockInterval { + assert(startBlockNumber.toLong() >= 0 && endBlockNumber.toLong() >= 0) { + "startBlockNumber=${startBlockNumber.toLong()} and " + + "endBlockNumber=${endBlockNumber.toLong()} must be non-negative!" + } + return BlockIntervalData(startBlockNumber.toLong().toULong(), endBlockNumber.toLong().toULong()) + } + + // Todo: remove later + /** + * Please use BlockInterval(startBlockNumber, endBlockNumber) instead + */ + fun between( + startBlockNumber: ULong, + endBlockNumber: ULong + ): BlockInterval { + return BlockIntervalData(startBlockNumber, endBlockNumber) + } + } +} + +/** + * Represents a block interval + * @property startBlockNumber starting block number inclusive + * @property endBlockNumber ending block number inclusive + */ +data class BlockIntervalData( + override val startBlockNumber: ULong, + override val endBlockNumber: ULong +) : BlockInterval { + init { + require(startBlockNumber <= endBlockNumber) { + "startBlockNumber=$startBlockNumber must be less than or equal to endBlockNumber$endBlockNumber" + } + } +} + +fun List.toBlockIntervalsString(): String { + return this.joinToString( + separator = ", ", + prefix = "[", + postfix = "]$size", + transform = BlockInterval::intervalString + ) +} + +fun List.filterOutWithEndBlockNumberBefore( + endBlockNumberInclusive: ULong +): List { + return this.filter { int -> int.endBlockNumber > endBlockNumberInclusive } +} + +fun assertConsecutiveIntervals(intervals: List) { + require(intervals.isSortedBy { it.startBlockNumber }) { "Intervals must be sorted by startBlockNumber" } + require(intervals.zipWithNext().all { (a, b) -> a.endBlockNumber + 1u == b.startBlockNumber }) { + "Intervals must be consecutive: intervals=${intervals.toBlockIntervalsString()}" + } +} + +/** + * Data class that represents sequential blocks intervals for either Conflations, Blobs or Aggregations. + * Example: + * conflations: [100..110], [111..120], [121..130] --> BlockIntervals(100, [110, 120, 130]) + * Blobs with + * Blob1 2 conflations above: [100..110], [111..120] + * Blob2 1 conflations: [121..130] + * --> BlockIntervals(100, [120, 130]) + */ +data class BlockIntervals( + val startingBlockNumber: ULong, + val upperBoundaries: List +) { + // This default constructor is to avoid the parse error when deserializing + constructor() : this(0UL, listOf()) + + fun toIntervalList(): List { + var previousBlockNumber = startingBlockNumber + val intervals = mutableListOf() + upperBoundaries.forEach { + intervals.add(BlockIntervalData(previousBlockNumber, it)) + previousBlockNumber = it + 1u + } + return intervals + } + + fun toBlockInterval(): BlockInterval { + return BlockIntervalData(startingBlockNumber, upperBoundaries.last()) + } +} + +fun List.toBlockIntervals(): BlockIntervals { + require(isNotEmpty()) { "BlockIntervals list must not be empty" } + return BlockIntervals( + startingBlockNumber = first().startBlockNumber, + upperBoundaries = map { it.endBlockNumber } + ) +} diff --git a/coordinator/core/src/test/kotlin/net/consensys/zkevm/domain/BlockIntervalsTest.kt b/jvm-libs/linea/core/domain-models/src/test/kotlin/build/linea/domain/BlockIntervalsTest.kt similarity index 98% rename from coordinator/core/src/test/kotlin/net/consensys/zkevm/domain/BlockIntervalsTest.kt rename to jvm-libs/linea/core/domain-models/src/test/kotlin/build/linea/domain/BlockIntervalsTest.kt index 4fd73b46d..f76d706e0 100644 --- a/coordinator/core/src/test/kotlin/net/consensys/zkevm/domain/BlockIntervalsTest.kt +++ b/jvm-libs/linea/core/domain-models/src/test/kotlin/build/linea/domain/BlockIntervalsTest.kt @@ -1,4 +1,4 @@ -package net.consensys.zkevm.domain +package build.linea.domain import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test diff --git a/settings.gradle b/settings.gradle index bacee4331..cc82fd277 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,27 +3,31 @@ rootProject.name = 'linea' include 'jvm-libs:generic:serialization:jackson' include 'jvm-libs:generic:json-rpc' include 'jvm-libs:generic:http-rest' +include 'jvm-libs:generic:extensions:futures' include 'jvm-libs:generic:extensions:kotlin' +include 'jvm-libs:generic:extensions:tuweni' include 'jvm-libs:generic:logging' include 'jvm-libs:generic:vertx-helper' -include 'jvm-libs:generic:extensions:futures' include 'jvm-libs:generic:errors' include 'jvm-libs:generic:persistence:db' +include 'jvm-libs:linea:clients:linea-state-manager' +include 'jvm-libs:linea:core:client-interface' include 'jvm-libs:linea:core:domain-models' +include 'jvm-libs:linea:core:long-running-service' include 'jvm-libs:linea:core:metrics' include 'jvm-libs:linea:core:traces' -include 'jvm-libs:linea:web3j-extensions' include 'jvm-libs:linea:blob-compressor' +include 'jvm-libs:linea:blob-decompressor' include 'jvm-libs:linea:blob-shnarf-calculator' -include 'jvm-libs:linea:core:long-running-service' include 'jvm-libs:linea:linea-contracts:l1-rollup' include 'jvm-libs:linea:linea-contracts:l2-message-service' include 'jvm-libs:linea:metrics:micrometer' include 'jvm-libs:linea:teku-execution-client' +include 'jvm-libs:linea:testing:file-system' include 'jvm-libs:linea:testing:l1-blob-and-proof-submission' include 'jvm-libs:linea:testing:teku-helper' -include 'jvm-libs:linea:testing:file-system' +include 'jvm-libs:linea:web3j-extensions' include 'coordinator:app' include 'coordinator:core'